git-subtree tirón combinación conflicto

Así que utilicé git-subtree para tener varias twigs de repoB en subdirectorys de repoA, como tal

git clone repoA cd repoA // some commits to repoA here git subtree add --prefix=src/dirA repoB branchA 

Hice algunos commits en repoA usando

 git subtree push --prefix=src/dirA repoB branchA 

Algún time después, cometí algo para repoB / branchA de otro repoC, donde también se agregó branchA usando git-subtree.

Ahora, bash

 git subtree pull --prefix=src/dirA repoB branchA 

Sin embargo, tengo un conflicto de fusión sin razón aparente. Los cambios son simples y no entran en conflicto en absoluto, como lo confirma el parche.

No estoy seguro de cómo solucionar este error. Ya encontré dos otros cuatro hilos que tratan el mismo problema / similar:

  1. git-subtree tirón complicaciones
  2. git subreeree pull -P whatever <repo> <ref> siempre fusiona conflicto
  3. conflicto de git-subtree al sacar del repository central
  4. Git Subtree Merging reporta conflictos al fusionar un simple cambio upstream (este es sobre la estrategia de fusión de subtree, ver abajo)

No estoy seguro de que esto esté relacionado con SHA-1 diferentes ya que no modifiqué mis confirmaciones ni las edité; enlaces 1 a 3.

Mi problema es más parecido al enlace 4, donde git mágicamente no puede hacer una fusión simple. Sin embargo, el enlace 3 habla sobre la estrategia de combinación de subtree, no del subtree de git en particular, por lo que no estoy seguro de si esto es aplicable en mi situación.

La situación parece ser la misma:

 <<<<<<< HEAD ======= // changes from commit I try to pull from repoB/branchA >>>>>>> {commit SHA-1 from commit I try to pull from repoB/branchA} 

Entonces noté que BASE está descaradamente mal en una window de combinación de tres vías (kdiff3). Sin embargo, si ese es el caso, ¿por qué no intentas aplicar todas las confirmaciones anteriores desde la base? Emisor

 git log --oneline 

después de la combinación fallida, pero antes de fusionar / intentar fusionar, no se muestran confirmaciones duplicadas antes de la confirmación del error. La versión del file que se muestra como BASE es el file tal como estaba cuando emití por primera vez

 git subtree add --prefix=src/dirA repoB branchA 

dentro de repoA.

Entonces, ¿qué está pasando? Parece estar relacionado con que el subtree de git no puede encontrar mis commits por algún motivo, sin embargo, no intenta aplicar el commit desde BASE a HEAD ~ 1, sino solo al commit que realmente me falta, HEAD.

¿Cómo puedo solucionar este error sin atornillar el historial de ninguno de los repositorys? ¿Por qué no puedes get este simple compromiso y en su lugar cree que es un conflicto de fusión?

Cualquier idea será muy apreciada.

Ok, entonces me di count de esto. Fue un problema en dos frentes. Antes que nada, mi tree se veía así:

Status quo

Tuve una confirmación en mi tree que tocaba src/dirA , pero aún no se había presionado cuando repoB/branchA ya se había movido.

Descubrí que la git subtree pull no encontraría la base correcta, porque busca un ancestro común, por lo tanto, usó la versión cuando fusioné los treees por última vez, es decir, cuando git subtree add inicialmente el git subtree add .

Ahora, para resolver el problema del antecesor común, uno tiene que git subtree split --rejoin , que realiza una fusión superficial, por lo que git encuentra de nuevo la base correcta, es decir, después de las confirmaciones repoA de repoA a repoB/branchA .

Sin embargo, como pueden ver en mi caso, una git subtree split --rejoin seguido de una git subtree pull no resuelve mis problemas:

Historia rota después de la extracción del subárbol de git.

Debido al hecho de que la git subtree split crea un historial sintético de todas las confirmaciones que tocan src/dirA independientemente del hecho de si se presionaron o no, las sums de SHA-1 divergen. Divido el historial sintético en su propia split para fines de demostración.

git subtree pull por supuesto tendrá éxito después de git subtree split --rejoin . Sin embargo, el siguiente git subtree push fallará, porque las historias de repoB y el tree sintético son completamente diferentes después de eso.

Por lo tanto, tuve que volver antes de la ejecución ofensiva no empujada y extraer los cambios en mi twig desde allí. Esto se complica por el hecho de que la git subtree split --rejoin todavía es necesaria, porque la git subtree pull través de git merge aún no puede determinar la base correcta por sí misma.

Solución final a mi problema

De modo que la forma en que resolví mi problema fue revisando el compromiso directamente antes de la src/dirA compromiso src/dirA comprometido src/dirA . Luego hice una git subtree split --rejoin seguida de un git subtree pull . Esto, por supuesto, agrega dos fusiones en mi tree principal, que no pude descifrar cómo concentrarme en una combinación, y por lo que leí en el código fuente, no parece haber una solución fácil para ese problema.

Después de la git subtree pull exitosa git subtree pull , volví a basar las confirmaciones restantes de mi twig master en master_fix . Ahora las sums de SHA-1 coinciden a lo largo de la historia compartida de repoA/master_fix y repoB/branchA .

Por supuesto, esto tiene los inconvenientes habituales de una rebase: si alguien más estuviera trabajando en master , su historial se arruinaría con la git branch -m master_fix master .