git merge: eliminando files que quiero conservar

¿Cómo se pueden fusionar dos twigs en git, reteniendo los files necesarios de una twig?

Al fusionar dos twigs, si se eliminó un file en una twig y no en otra, el file finalmente se elimina.

Por ejemplo:

  • Existe un file en el maestro cuando se crea una nueva twig
  • usted elimina el file del maestro ya que no lo necesitamos (aún)
  • realiza cambios en la twig para agregar una característica, que se basa en el file existente
  • haces correcciones de errores en el maestro (no se puede descartar)
  • te fusionas algún día y el file ya no está!

Cómo reproducir:

  1. Crea un repository git con un file.

    git init echo "test" > test.txt git add . git commit -m "initial commit" 
  2. Crear una twig

     git branch branchA 
  3. Eliminar el file en el maestro

     git rm test.txt git commit -m "removed file from master" 
  4. Realice CUALQUIER cambio en branchA que no toque el file eliminado (no debe modificarse para evitar Conflict)

     git checkout branchA touch something.txt git add . git commit -m "some branch changes" 

Desde aquí, de cualquier manera que he encontrado para fusionar estas dos twigs, se elimina el file test.txt. Suponiendo que confiamos en el file para branchA , este es un gran problema.


Ejemplos fallidos:

Fusionar 1

 git checkout branchA git merge master ls test.txt 

Merge 2

 git checkout master git merge branchA ls test.txt 

Rebase 1

 git checkout branchA git rebase master ls test.txt 

Este es un tema interesante. Debido a que eliminó el file después de que se creó BranchA , y luego está fusionando master en BranchA , no estoy seguro de cómo Git podría darse count de que hay un conflicto.

Después de la fusión incorrecta, puede deshacer, y luego volver a fusionar, pero volver a agregar el file:

 git checkout HEAD@{1} . git merge --no-commit master git checkout master test.txt git add test.txt git commit 

Para una solución rápida en este caso, "git revert" la confirmación que eliminó el file.

Cuando surja esta situación en el futuro, la mejor manera de manejarla es asegurar que la creación del nuevo file ocurra en la sucursal. Luego se agrega en el maestro cuando se fusiona, pero mientras tanto no tiene el file en el maestro.

Debe modificar el file en la bifurcación, de modo que exista un conflicto de fusión con la eliminación en el enlace troncal.

Lo mismo sucederá si, por ejemplo, elimina una statement de algo en un file de cabecera en el tronco (porque nada lo necesita), y agrega una dependencia en esa statement a algunos files que no son de encabezado en la twig. Cuando se fusiona, dado que la twig no toca (esa parte del) encabezado, simplemente eliminará la statement y las cosas se romperán.

Siempre que tenga cosas en varios lugares que sean interdependientes y se mantengan sincronizadas, es muy fácil fusionarlas para introducir problemas silenciosamente. Es solo una de las cosas que debe saber y verificar cuando se fusiona. Lo ideal es utilizar afirmaciones en time de compilation u otras comprobaciones de time de compilation que hagan que cualquier falla sea inmediatamente aparente.

El ejemplo de Casey no funcionó en mi caso: no pude test.txt de master , porque ya no estaba en esa twig:

 $ git checkout master test.txt error: pathspec 'test.txt' did not match any file(s) known to git. 

Afortunadamente, pude sacar el file de la branchA de branchA :

 $ git checkout branchA $ git merge --no-commit master $ git checkout HEAD test.txt $ git add test.txt $ git commit 

Mi solución a esto fue simplemente modificar los files que necesitaba save (agregué un comentario que era necesario de todos modos) y comprometer esos cambios en la twig de destino, generando así un conflicto de fusión que podría resolverse fácilmente con un git add y un commit normal .

Mi historia fue algo así. Los nombres de las sucursales han sido cambiados para proteger a los inocentes.

  1. crear y confirmar files para una nueva característica para dominar
  2. se da count de que esta adición va a estar más involucrada de lo originalmente planeado, por lo tanto, se ramificó a feature_branch
  3. Se eliminaron los files del maestro para no interrumpir el flujo de trabajo normal con RB y tal
  4. El time pasa, más commits en master, ninguno en feature_branch
  5. Reanudar el trabajo en la function, git merge master en feature_branch hace que los files originales sean eliminados (por supuesto), git reset --hard to before the merge
  6. Aplicado la solución descrita arriba