¿Puedo eliminar files individuales de una twig git sin eliminarlos al fusionarme en otra twig?

Estoy en medio de un proyecto en el que hay dos twigs de desarrollo principales, ya que el proyecto consiste en una biblioteca y una implementación de la biblioteca, las cuales se están desarrollando en paralelo en sucursales separadas.

Mi flujo de trabajo es que fusiono la twig de la biblioteca con --no-ff en la twig de implementación ( core nombre) una vez que se han agregado suficientes características a la biblioteca, y la twig de la biblioteca idealmente nunca debería ver ningún file desde la implementación, porque de lo contrario ambas twigs estaría haciendo cambios en los mismos files de implementación. Desafortunadamente, ese no es el caso desde que comencé el proyecto desde una carpeta fuente existente que tenía algunos files de la biblioteca Y una implementación parcialmente iniciada, y olvidé eliminar los files de implementación cuando inicialmente se dividieron las dos twigs de trabajo desde el maestro.

Flujo de trabajo:

 $ git checkout library 

..hacer algunos cambios ..

 $ git commit -am "updated library" $ git checkout core $ git merge --no-ff library 

En este punto, generalmente tengo que lidiar con los conflictos que resultan de las actualizaciones de la biblioteca al cambiar los files de implementación en la twig de la library mientras se fusionan con los cambios en la twig core , y tener los mismos files actualizados, aunque la twig core haya hecho sus propias actualizaciones a esos files.

¿Cómo puedo eliminar el directory de implementación de la twig de la library sin eliminarlos cuando los fusiono en la twig de implementación?

¿Cómo puedo eliminar el directory de implementación de la twig de la biblioteca sin eliminarlos cuando los fusiono en la twig de implementación?

Puede realizar la fusión con un –no-commit, restaurar los files eliminados y completar la confirmación.

Ver " git merge: Eliminar files que quiero save " como un ejemplo concreto.

 git checkout dev1 git merge --no-commit dev2 git checkout dev1 implementationFile git add implementationFile git commit 

Parece que estás haciendo esto un poco mal, no deberías estar usando twigs para este propósito; en su lugar, debe usar 2 repositorys separados, uno de biblioteca y uno de implementación / cliente. El cliente tendría entonces el repository de la biblioteca como, por ejemplo, su submodule (aunque hay otros enfoques).

De esta forma no habría superposition en los files entre esos 2 repositorys, que es lo que quiere, decidiendo según sus requisitos.

Para convertir lo que actualmente está en forma de 2 twigs, usarías git filter-branch para filtrar de los files de la twig A que pertenecen a la twig B, y viceversa, así terminarías con 2 repos solamente teniendo files de la biblioteca o del cliente (implementación). Por supuesto, esto tiene la desventaja de modificar el historial, por lo que si quieres evitar eso, simplemente eliminarás usando git rm y git commit normales.

Evita la eliminación guiándote por ella:

Sí, puede hacerlo de manera bastante simple: debe evitar fusionar los commits que eliminan los files. Entonces, por supuesto, le conviene no hacer commits que hagan cambios y eliminen files.

Ejemplo:

Crea un repository git con una twig master que tenga dos files:

 ~$ mkdir gittest ~$ cd gittest ~/gittest$ git init Initialized empty Git repository in /home/kaz/gittest/.git/ ~/gittest$ echo foo > foo ~/gittest$ echo bar > bar ~/gittest$ git add foo bar ~/gittest$ git commit -m "root commit" [master (root-commit) 1c1860f] root commit 2 files changed, 2 insertions(+) create mode 100644 bar create mode 100644 foo 

Dispara una twig de topic desde la confirmación raíz:

 ~/gittest$ git branch topic 

Cree una segunda versión en el master de ambos files:

 ~/gittest$ echo foo >> foo ~/gittest$ echo bar >> bar ~/gittest$ git diff diff --git a/bar b/bar index 5716ca5..a486f1a 100644 --- a/bar +++ b/bar @@ -1 +1,2 @@ bar +bar diff --git a/foo b/foo index 257cc56..0d55bed 100644 --- a/foo +++ b/foo @@ -1 +1,2 @@ foo +foo ~/gittest$ git commit -a -m "hack 1" [master ded65d8] hack 1 2 files changed, 2 insertions(+) 

Cambiar al topic Eliminar bar y confirmar. Modifica foo de forma conflictiva con master y commit:

 ~/gittest$ git checkout topic Switched to branch 'topic' ~/gittest$ git rm bar rm 'bar' ~/gittest$ git commit -m "delete bar" [topic 8a4009d] delete bar 1 file changed, 1 deletion(-) delete mode 100644 bar ~/gittest$ echo "foo2" > foo ~/gittest$ git commit -a -m "replace foo" [topic abfa329] replace foo 1 file changed, 1 insertion(+), 1 deletion(-) 

Historial de recapitulación sobre el topic :

 ~/gittest$ git log --oneline abfa329 replace foo 8a4009d delete bar 1c1860f root commit 

De vuelta al master

 ~/gittest$ git checkout master Switched to branch 'master' ~/gittest$ git log --oneline ded65d8 hack 1 1c1860f root commit 

Ahora, select cherry abfa329 replace foo del tema, evitando la 8a4009d delete bar .

 $ git cherry-pick abfa329 error: could not apply abfa329... replace foo hint: after resolving the conflicts, mark the corrected paths hint: with 'git add <paths>' or 'git rm <paths>' hint: and commit the result with 'git commit' 

Repara el conflicto en foo y confirma:

 ~/gittest$ cat foo <<<<<<< HEAD foo foo ======= foo2 >>>>>>> abfa329... replace foo ~/gittest$ cat > foo foo foo2 ~/gittest$ git add foo ~/gittest$ git commit -m "merged topic, avoiding deletion" [master 320818f] merged topic, avoiding deletion 1 file changed, 1 insertion(+), 1 deletion(-) 

Tenga en count que la bar todavía está allí:

 ~/gittest$ ls bar bar ~/gittest$ cat bar bar bar 

Use git reset para deshacer las eliminaciones no deseadas, durante o después de la fusión:

Si recoge una eliminación no deseada, puede deshacerla fácilmente.

Vamos a retrotraer nuestro ejemplo de twig master al hack 1 commit y reescribir eso para que la bar no se modifique en master , solo foo :

 ~/gittest$ git reset --hard ded65d8 HEAD is now at ded65d8 hack 1 ~/gittest$ git reset HEAD^ -- bar Unstaged changes after reset: M bar ~/gittest$ git commit --amend -m "hack1: bar only" [master 623908a] hack1: bar only 1 file changed, 1 insertion(+) ~/gittest$ git log --oneline 623908a hack1: bar only 1c1860f root commit ~/gittest$ git show -p commit 623908a3bf6b2fb81b0bf8309fa2e83cd602986a Author: Kaz <kaz@stackexchange.example.com> Date: Sat Dec 20 08:03:27 2014 -0800 hack1: bar only diff --git a/foo b/foo index 257cc56..0d55bed 100644 --- a/foo +++ b/foo @@ -1 +1,2 @@ foo +foo 

Ahora, fusionemos el topic sin sospechar que hay una eliminación no deseada:

 ~/gittest$ git merge topic error: Your local changes to the following files would be overwritten by merge: bar Please, commit your changes or stash them before you can merge. Aborting 

Oops! Me olvidé de git reset --hard después de deshacer la bar cambia. Toma dos:

 ~/gittest$ git reset --hard HEAD is now at 623908a hack1: bar only ~/gittest$ git merge topic Auto-merging foo CONFLICT (content): Merge conflict in foo Removing bar Automatic merge failed; fix conflicts and then commit the result. 

De acuerdo, la bar fusión se borró automáticamente (no hay conflicto porque la bar no se modifica en el master ). Hay un conflicto en foo , exactamente el mismo que en el caso de la cherry-pick , así que vamos a tratar con eso primero:

 ~/gittest$ cat > foo foo foo2 ~/gittest$ git add foo 

Ahora, deshace la eliminación de la bar . Tenga en count que la bar no está en el tree de trabajo y sigue siendo así por ahora:

 ~/gittest$ git reset HEAD^ -- bar Unstaged changes after reset: D bar 

Comprometemos todo:

 ~/gittest$ git commit -m "merged topic, except deletion of bar" [master 57b7fca] merged topic, except deletion of bar 

Ahora traemos bar nuevo:

 ~/gittest$ git reset Unstaged changes after reset: D bar 

Oops, quise decir --hard :

 ~/gittest$ git reset --hard HEAD is now at 57b7fca merged topic, except deletion of bar 

Revise el logging, con --graph :

 ~/gittest$ git log --graph --oneline * 57b7fca merged topic, except deletion of bar |\ | * abfa329 replace foo | * 8a4009d delete bar * | 623908a hack1: bar only |/ * 1c1860f root commit 

Verifique el contenido del file. foo se fusiona, la bar está allí:

 ~/gittest$ cat foo foo foo2 ~/gittest$ cat bar bar