2010-09-19 4 views
11

Creé una nueva rama antes de iniciar el desarrollo de algo experimental. Normalmente me olvido de eso (que no es un problema), pero ahora lo hice de antemano.
Desde entonces he actualizado 3 archivos.GIT: confirmar los cambios en la rama anterior/segura mientras estaba en la rama nueva/sucia/dev sin verificar o perder datos sin grabar

  • En 2 solo hay cambios experimentales que NO QUIERO comprometer con la rama segura.
  • En 1 solo hay cambios seguros (menores) que definitivamente DESEO comprometer con la sucursal segura. Estoy de acuerdo con estos últimos cambios para estar comprometido con la nueva rama también (pero no así).

¿Es posible - Estoy seguro de que es - a (rápidamente) comprometerse unos cambios no confirmados, unstaged de mi (sucia) que trabajan dir a una rama de edad, salvo?

Lo único que se me ocurre es cambiar ramas (sin pago), confirmar los cambios en 1 archivo y volver, pero no sé qué pasará con los cambios cuando vuelva a la rama sucia (¿todavía están allí o desaparecieron debido a la confirmación?) ...

Estoy seguro de que GIT tiene algo hermoso para esto, pero GIT tiene mucho, no puedo encontrar exactamente lo mismo.
(he estado usando this 'manual' for help pero no estoy seguro de que exista exactamente lo mismo. Si lo está (y está dispuesto a escanear la información), hágamelo saber, por lo que sé que la próxima vez lo veré más difícil.)

Gracias! Por ahora solo tendré un papel a mano con los cambios 'para comprometerme a una rama segura más tarde'.

Respuesta

6

Por lo que su situación es

x--x--x (safe) 
     \ 
     <a,b,c> (3 private evolutions in exp branch) 

y que desea ir a

x--x--x--a (a committed only in safe banch) 
     \ 
     b,c (b and c commited in exp branch) 

Usted podría:

git add a 
git commit -m  # in exp branch, gasp! 
git stash save  # save the rest of the exp work in progress 
git checkout master 
git merge exp  # fast-forward merge 

x--x--x--a (safe,exp) 
      \ 
      [b,c] (stashed) 

git branch -f exp HEAD~1 # reset branch exp to before 'a' 
git checkout exp 
git stash pop 
git add -A 
git commit -m "..." 

x--x--x--a (a committed only in safe banch) 
     \ 
     b,c (b and c commited in exp branch) 
+2

Dado que el proceso de pago no toca los archivos modificados, ¿no estaría bien si simplemente 'checkout maestro; Agrega un; cometer; checkout exp' y continuar? Suponiendo que los cambios no están escalonados. – rlduffy

+0

@rlduffy: debería funcionar. Siempre trato de ser un poco más cuidadoso con esos interruptores de rama. – VonC

+0

Si 'exp' se compromete más allá de 'seguro' (no pude decidirlo por la descripción del OP), entonces no querrás 'git checkout safe && git merge exp' ya que podría obtener esas otras confirmaciones. Si de todos modos vas a cortar 'a' de 'exp' de todos modos, me limitaré a seleccionarlo 'seguro' en lugar de fusionarlo. –

0

Dado que las operaciones de ramificación de GIT es tan barato, lo haría solo utilice el siguiente flujo de trabajo:

  • Crear una nueva rama de la sucursal "experimental"
  • cometen aquellos ficheros necesarios unstaged
  • volver a dominar
  • cherrypick lo compromete desde su & la nueva rama "experimental" acaba de crear en el paso 1.
  • volver a la rama "experimental"
7

no hay manera de añadir una confirmación a una rama alternan con git commit. Hay formas de utilizar los comandos de "plomería" de bajo nivel para hacer exactamente lo que describió, pero la interfaz formada por esos comandos no está diseñada para uso interactivo . Ciertamente hay maneras de hacer lo que quieres; Dependiendo de los detalles de sus cambios y el contenido de las ramas involucradas, puede ser bastante simple.

El caso fácil: Sólo usa git checkout

Al cambiar ramas, git checkout preservará modificaciones sin confirmar o rechazar a cambiar (a menos que utilice --force, --merge o --conflict). Entonces, mientras sus cambios no comprometidos solo toquen los archivos que son iguales en HEAD (la rama actual) y su sucursal de destino, git checkout dejarán esos cambios en el índice y/o en el árbol de trabajo al cambiar de rama. Si los cambios no satisfacen esta condición, entonces usted puede hacer esto:

git checkout safe-branch 
git add -- files-with-safe-changes 
git commit 
git checkout - 

También puede utilizar git add --patch para organizar y comprometer sólo algunos de los cambios en los archivos.

Después de esto, sus "cambios seguros" formarán parte de 'safe-branch'; volver a la rama original "los dejará atrás" (recuerde, git checkout solo conserva cambios no confirmados al cambiar de rama).

Si sus otros cambios dependen de los "cambios seguros" puede necesitar fusionar 'safe-branch' en su rama de trabajo (o, dependiendo de su flujo de trabajo, rebase su rama de trabajo en la nueva punta de 'safe-branch '). Para hacer esto, tendrá que esconder sus cambios no confirmados (ya que ambos fusionarán y rebase se negarán a funcionar si hay cambios no confirmados).

git stash save 
git merge safe-branch 
git stash pop --index 

Si sus otros cambios no dependen de los cambios “seguros”, entonces debería probablemente no molestarse con una fusión o rebase. Eventualmente combinará estas ramas (por ejemplo, fusionándolas en una rama 'qa' para las pruebas previas a la publicación), pero no hay razón para fusionarlas prematuramente.

siendo fácil, pero un poco arriesgado: git checkout -m

Si el primer git checkout se queja “Usted tiene cambios locales en some‑file; no cambiar de ramas. ", significa que ha modificado los cambios a some-file y que el archivo es diferente en las sugerencias de 'safe-branch' y su rama actual; necesitarás un enfoque diferente.

Si se tiene la certeza de que los cambios se aplicarían limpiamente a la versión de some‑file que está en 'seguro-rama', entonces usted puede utilizar la opción -m/--merge para contar git checkout para tratar de adaptarse a los cambios de modo que se aplican a los archivos en 'safe-branch'. Si la fusión no se puede hacer limpiamente, terminará con un conflicto de fusión y puede ser difícil recuperar los cambios originales (por eso lo llamo "riesgoso").

seguro: git stash + git checkout -m

Desde que realmente sólo quiere mover un subconjunto de los cambios de nuevo a ‘seguro-rama’, puede ser mejor centrarse en sólo esos cambios. Un método es usar git stash para guardar temporalmente sus cambios actuales para que no tenga que arrastrarlos todos a la 'rama segura' (y más tarde arrastre algunos/la mayoría de ellos de vuelta a su rama de trabajo).

git stash save 
git checkout stash -- files-with-save-changes 
git checkout -m safe-branch 
git commit 
git checkout - 
git stash pop --index 

Otras variaciones son posibles. Puede usar git checkout -p stash -- files para seleccionar solo algunos de los cambios en esos archivos. Si no hay cambios por etapas en el índice, entonces primero podría organizar los "cambios seguros", git add -- files (nuevamente, opcionalmente con -p), use git stash save --keep-index, cambie de ramas (con fusión), y luego confirme (es decir, reemplace el git checkout stash -- files con pre "cambios seguros" en la plataforma y git stash --keep-index).

En esta situación considero git checkout -m ser seguro porque utilizamos git alijo para conservar una copia de los cambios actuales; Si el intento de fusión tripartita resulta en un lío irremediable, entonces puede abandonar fácilmente la idea de poner los "cambios seguros" en la 'rama segura' y volver al trabajo: vuelva a su rama original y saque el alijo (git checkout -f - && git stash pop).

Nuevamente, si sus otros cambios dependen de los "cambios seguros", deberá fusionar o volver a establecer la base. También podría hacer esto antes de mostrar el alijo (ya que necesita un índice limpio y un árbol de trabajo para hacer la combinación/rebase).

Si no va a combinar su rama de trabajo con (o volver a establecer la base en) la "rama de seguridad" de inmediato, entonces es probable que desee deshacer los "cambios seguros" después de abrir el alijo (el " cambios seguros "se guardaron en el alijo original y es probable que no desee terminar con confirmaciones que realizan los mismos cambios desde cero en dos ramas diferentes). Una vez que haya reventado el alijo, use git checkout -- files-with-safe-changes para revertir esos archivos a versiones en la punta de la rama de trabajo.


La interfaz “fontanería” está diseñada para su uso en scripts. Sería engorroso usarlos directamente en la línea de comando. Las primeras versiones de git commit (y la mayoría de los demás comandos de Git) eran scripts de shell basados ​​en esta interfaz. Todavía podrían escribirse como scripts de shell hoy, pero las versiones C son generalmente mucho más rápidas. Los pasos necesarios para comprometerse con una sucursal alternativa son:
configurar un índice alternativo basado en el árbol en la punta de la "rama segura",
actualizar el índice con los cambios "seguros" (¿qué pasa si los cambios no pueden? se aplica limpiamente? es bueno tener un árbol de trabajo para que el usuario resuelva los conflictos),
escribe el índice como un objeto de árbol,
crea un nuevo objeto de confirmación que apunta al nuevo árbol y tiene el consejo actual de "rama segura" como su elemento primario,
actualice la referencia "rama segura" para que apunte a la nueva confirmación.

No hay nada malo con técnicamente confirmar los cambios “seguros” en dos ramas, pero por lo general es una buena idea para asegurarse de que cada cambio tiene su origen en un solo lugar.

+0

Me gusta la fontanería y los detalles. +1 – VonC

Cuestiones relacionadas