2009-05-29 14 views
43

Tengo una sucursal local para el trabajo diario de desarrollo en git. Mi flujo de trabajo es:Cómo hacer copias de seguridad de sucursales privadas en git

  1. hacer cosas en local_branch, cometen
  2. Fetch origin/master
  3. local_branch Rebase para ponerse al día con el nuevo material de origen/maestra

Todo funciona bien, sin embargo la mayoría de las recomendaciones que encontré dicen que uno no debe "presionar" las ramas privadas, en las cuales se realiza regularmente la rebase.

El problema aquí es que en este caso la rama local no está respaldado en un servidor y la única manera de salvar la obra es fusionarla de nuevo a la rama "que se puede empujar" (es decir, origin/master)

Lo serían sus recomendaciones sobre el flujo de trabajo en este caso?

Gracias!

ACTUALIZACIÓN: Me di cuenta de que uno de los requisitos originales que tenía (evitando el uso de utilidades externas) es una limitación innecesaria.

Mi solución actual es almacenar todos mis repositorios en una carpeta sincronizada en la nube, de esta manera obtengo una copia de seguridad de forma gratuita.

Respuesta

48

uso la opción --mirror y empuje a una copia de seguridad repositorio personal:

añadirlo como un mando a distancia:

git remote add bak server:/path/to/backup/repo 

hacer la copia de seguridad:

git push --mirror bak 

Esto automáticamente haga que su repositorio de respaldo se vea como uno activo - las sucursales se crearán, eliminarán y actualizarán (incluso forzadas/no rápidas) según sea necesario. Se puede crear un alias para esto también:

git config alias.bak "push --mirror bak" 

Entonces, es sólo una cuestión de funcionamiento "git bak" cuando se quiere hacer una copia de seguridad. También podrías incluir esto en un trabajo de cron.

+0

Gracias por --mirror y config alias, lo investigaremos – Art

+0

Solo un aviso, esto * no * reflejará sus archivos de configuración desde su directorio '.git' (' config', 'hooks/*', etc.) . Solo un aviso. Aún así, creo que es una buena solución. –

1

¿Puede configurar otro repositorio remoto al que empuje todas sus ramas? La otra cosa a tener en cuenta es simplemente realizar una copia de seguridad de todo (importante) en su máquina local, incluido el repositorio git.

+1

En caso de configurar un repositorio por separado, seguiré teniendo problemas para cambiar el historial, es decir, no podré presionar directamente después de rebase – Art

2

No hay nada de malo en empujar hacia la misma rama desde la que realiza el rebasado. Estos diagramas deben ilustrar por qué esto funciona bien:

Digamos que esto es lo que parece el gráfico de compromiso después de que haya ramificado local_branch y haya hecho un par de confirmaciones (C y D). Otra persona ha hecho un commit (E) para origin/master ya que bifurcó local_branch:

 
A -- B -- E [origin/master] 
     \ 
     \  
     \-- C -- D [local_branch] 

A continuación, después de ejecutar "git rebase origin/master", el gráfico de comprometerse se parecerá al siguiente diagrama. "Origin/master" sigue siendo el mismo, pero "local_branch" ha sido sincronizado:

 
A -- B -- E [origin/master] 
      \ 
      \ 
      \-- C -- D [local_branch] 

En esta etapa, si lo hace "git push origin local_branch: maestro", entonces el resultado será un simple EXPRES- adelante. "Origin/master" y "local_branch" será idéntico:

 
A -- B -- E -- C -- D [origin/master],[local_branch] 

Ahora que son libres de hacer más trabajo en "local_branch". Eventualmente, puede obtener algo como esto:

 
A -- B -- E -- C -- D -- G -- I [origin/master] 
        \ 
         \ 
         \-- F -- H [local_branch] 

Observe que se parece mucho al gráfico de inicio. Puedes seguir repitiendo este proceso una y otra vez.

Debería evitar presionar a alguna otra rama , una que no está modificando. Ahí es donde se encontrará con problemas (para la otra rama, parecerá que la historia de su "bifurcación local" ha sido reescrita de repente, después de que haya cambiado su ubicación desde "origen/maestro").

+1

Esto no es exactamente lo que quiero. Supongamos que el trabajo está en progreso y no quiero fusionarlo en maestro y solo quiero hacer una copia de seguridad. – Art

+0

Oh, he entendido mal tu pregunta. Lo siento por eso. Me parece que una solución razonable sería clonar el repositorio local en una ubicación que * está * respaldada. Solo vuelva a clonar periódicamente para mantener su copia de seguridad actualizada. Pero no necesariamente necesita hacer ningún trabajo en el clon (puede simplemente eliminarlo antes de volver a clonarlo para hacer una nueva copia de seguridad). –

+0

@Dan, ¿es este el flujo de trabajo que obtendría al hacer "git pull - rebase"? – cmcginty

1

Here's what I do. Pero - esto no es privado. Hago esto para poder colaborar conmigo mismo (por así decirlo). Me permite trabajar en la misma rama en dos o más cajas. si otras personas tuvieran acceso al repositorio compartido, podrían ver el trabajo que estoy haciendo en la sucursal. Por supuesto, en mis repositorios domésticos, nadie más tiene acceso, por lo que sigue siendo privado. En github, todo el mundo podría ver mis cosas. Como si realmente les importara ;)

+0

Parece que no estás haciendo ningún rebases, que es el verdadero problema que tengo. – Art

+0

¿No sería útil "extraer" su copia local y luego volver a establecerla localmente? Entonces su sucursal local tendría todos los cambios del maestro fusionados, y el siguiente empuje empujaría a la sucursal remota. Tendría que intentar esto para saberlo con certeza, pero parece que eso funcionaría. –

+0

Don, la próxima extracción después de rebase en una rama no privada provoca un conflicto. – Art

4

Otra opción sería la de empujar "local_branch" al repositorio "origen", sino a su propia sucursal en ese repo (no "maestro"), es decir:

git push origin local_branch:local_backup

Luego, cuando está listo para hacer otra copia de seguridad (y después de haber estado trabajando y rebase) simplemente elimine la rama de respaldo del repositorio de origen antes de volver a sacarla:

git push origin :local_backup < === elimina la sucursal del origen

git push origin local_branch:local_backup

De esta manera no tendrá problemas empujando "local_branch" después de que haya sido sincronizado de "origin/master".

Y si eliminar las ramas de respaldo te pone nervioso (hasta que finalmente hayas comprometido tu trabajo a "masterizar"), siempre puedes seguir presionando a una nueva rama con un nuevo nombre (por ejemplo, "local_backup1", "local_backup2" ", etc.)

+0

¿la eliminación sería un paso innecesario si se usa push --force? – Art

+0

Sí, --force es una buena alternativa a la eliminación. Reemplazará la cabeza de la sucursal remota con la nueva de su sucursal local. –

+0

De forma predeterminada, los repositorios remotos rechazarán los reenvíos no rápidos, por lo que --force puede no ser suficiente. http://stackoverflow.com/questions/253055/how-do-i-push-amended-commit-to-the-remote-git-repo/255080#255080 –

3

No hay nada de malo en presionar las ramas personales. En general, se desaconseja porque las personas pueden comenzar a trabajar en función de su sucursal, y cuando se rebase, sus cambios se dejan flotando.

Lo que hago es usar un prefijo para indicar "esto es mi sucursal, lo utilizan en su propio riesgo", como: fc general-limpieza.

+0

Pero luego de la rebase recibes una advertencia de ramas divergentes, ¿no? Ver http://superuser.com/q/667146/57249. ¿Es posible que la solución sea hacer un 'git push --force' para la rama privada? – Dror

+0

Por supuesto que recibes una advertencia sobre divergencia, eso es lo que hace una rebase, y sí, necesitas hacer 'git push --force'. – FelipeC

0

En lugar de confiar en Dropbox para sincronizar todos los archivos de un repositorio git, preferiría usar git bundle, que sólo produce uno archivo (incluyendo todas sus ramas privadas), y sincronizar el archivo con DropBox .
Ver "Git with Dropbox"

En "Backup a Local Git Repository", Yars mencionado que tiene errores de sincronización con Dropbox.

Cuestiones relacionadas