2010-10-30 13 views
12

estoy totalmente de amor git add -p y git stash pero a veces tengo el siguiente problema, que se reproduce mediante la siguiente secuencia de comandos:alijo Git y editado trozos

  • git add -p my_file: entonces editar un trozo manualmente (usando e) debido a la división que sugiere git no me conviene
  • git stash --keep-index: entonces hacer algunas pruebas, y si las pruebas pasan no cometo
  • git stash pop: ahora el problema se produce: el archivo my_filese considera ahora como en conflicto, y Git tiene completamente metido con mi trozo editado, así que tengo que editar el archivo, quitar las marcas de combinación inútiles, y ejecutar git add my_file seguido por git reset HEAD

Estoy desconcertado porque esto ocurre solo cuando se edita un trozo de forma manual. No veo cómo esto debería hacer ninguna diferencia en absoluto.


para reproducir el problema:

  • touch newfile
  • git add newfile
  • git commit -m 'newfile'
  • añadir dos líneas en el archivo
  • git add -p newfile
  • edición del h unk (e), eliminar uno de la línea en el trozo, a continuación, salga git add (q)
  • git stash --keep-index
  • git stash pop

Ahora el archivo newfile encuentra en estado sin combinar. Tenga en cuenta, una vez más, que el problema solo se produce con trozos editados manualmente. No hay problema alguno con los comandos anteriores si uno no edita ningún trozo manualmente.

Dicho sea de paso, el estado anterior del archivo se encuentra en la tercera etapa (git show :3:newfile), y la versión anterior está en la segunda etapa (git show :2:newfile). Así que pude, gracias a la magia negra de Git, lograr poner la segunda etapa en este índice, y la tercera etapa en el informe de trabajo ... pero no sé cómo hacerlo, así que lo hago a mano. :-(

+0

Lo intenté varias veces, pero no puedo reproducir su problema con la versión de Git 1.7.2.3. Qué versión estás usando? –

+0

Estoy usando la versión 1.7.3.1 en Mac OS X. –

+1

Intenté de nuevo con diferentes ediciones al azar en 'git add -p', y siempre funciona bien para mí. Estoy en Linux por cierto. Suena como un error, recomendaría preguntar en la lista de correo git, son bastante receptivos. –

Respuesta

4

Hice la pregunta en la lista de correo git Lo que describo es el comportamiento esperado. No es un error.:-(

Aquí está la respuesta que obtuve:

Si no modificó el trozo manualmente, cada trozo será o bien en CABEZA estado o en el estado A, y aplicando el diff entre la cabeza y un a tal archivo será o un no-op (trozo ya aplicado), o una aplicación exitosa .

para mí esto es una limitación severa de git add --patch, y yo no entienden de qué manera esta el comportamiento puede ser útil para cualquier persona, pero aprenderé a vive con ello.

+1

Parece que el problema es que cuando se hace "git stash --keep-index" oculta los cambios por etapas y los cambios por etapas, con la única diferencia de que conserva los cambios por etapas en la copia de trabajo. Y cuando intentas aplicar el alijo, los cambios por etapas se encuentran tanto en la copia de trabajo como en el alijo que causa un conflicto. En el caso de trozos no editados mientras responden, recuerdan qué trozos están presentes en la copia de trabajo y cuáles no son y no se aplican, una vez presentes, evitando los conflictos de fusión. Para un trozo editado, solo se aplica una parte; no se puede hacer el truco. – axk

2

git stash --keep-index conserva su índice, pero todavía añade el contenido del índice como parte del alijo

Trate git stash save -p -. Un poco más tedioso para salvar al escondite, pero probablemente va a hacer lo que quiere.

+0

¿Cómo explica eso que git considere que hay un conflicto ** solo ** cuando tengo un fragmento editado manualmente? –

+0

porque sus índices no coinciden cuando se convierte pop stash. – Scott

+0

@Scott: lo siento, no entiendo su respuesta ...: -/¿por qué hay un conflicto solo cuando había un fragmento editado manualmente? –

7

Para crear y probar un índice que contiene parte de los cambios en el árbol de trabajo, incluso trozos editado manualmente, hacer:

git add --patch <files> 

git stash --keep-index 

<test the indexed changes> 

git reset --hard 

git stash pop --index 

En este punto no hay conflictos, y el repositorio, el índice y directorio de trabajo son en el estado inmediatamente anterior al git stash. Ahora puede git commit los cambios indexados.

Por supuesto, esto es bastante raro y no muy intuitivo, y realmente me gustaría saber si hay una manera más fácil de hacerlo.

+0

+1, esto funciona. He llegado a la misma solución pero me perdí el interruptor --index. Esta es una forma lógica de hacer las cosas, ya que oculta tanto el índice como los cambios no planificados para evitar el conflicto de fusión entre los cambios por etapas en la copia de trabajo y en los escondidos, primero hay que eliminarlos de la copia de trabajo (es decir, un restablecimiento completo). – axk

+0

¡Gracias! Ahora para engancharlo a un mago ... – seanmcl

Cuestiones relacionadas