Asistente de Git necesario: ¿cómo fusionar una twig con una estructura de directory diferente?

Érase una vez, había dos twigs:

--[stable]--hotfix1--h2--h3 \ \--[develop]--refactor1--r2--r3 

Necesito fusionar stable en develop , pero estoy en un pequeño aprieto.

develop ha sido refactorizado con una estructura de directory diferente. y Git no puede seguir el cambio.

 (stable) |-app | |-scripts | |-site | |-**ALL THE CODE (develop) |-app | |-modules | |**ALL THE CODE 

esperado: cuando ejecuto git merge , git aplica las revisiones en stable a la nueva ruta de file en develop .

real: Git marca los files con las revisiones como "eliminados por nosotros" porque tienen la estructura de directorys anterior.

¿Cómo puedo hacer para que Git aplique las revisiones en stable a la nueva estructura de directorys en develop ?

Podría funcionar simplemente cambiar la estructura del directory para stable develop stable para coincidir (en una confirmación), entonces podría fusionarlos. Simplemente haría esto manualmente (con un buscador de files), pero si realmente te mueres por usar commands git para toda la tarea, podrías encontrar la confirmación de develop que cambió la estructura del directory, seleccionarla en forma stable y luego la fusión probablemente se aplicaría correctamente (con algunos conflictos de combinación posiblemente).

Puedes ayudar a Git simulando una combinación con todo lo que ya se ha cambiado de nombre. Usando Bash por ejemplo,

 # Mark this as the branch to be merged. git update-ref --stdin <<<'create MERGE_HEAD stable' printf '%s\t\t%s\n' $(git rev-parse MERGE_HEAD) "branch 'stable'" | >$(git rev-parse --git-dir)/MERGE_MSG git fmt-merge-msg \ $([[ $(git config --bool merge.log) = true ]] && echo --log) # This outputs a tree object with some paths transformed. refactor-tree() { ( index1= index2= trap 'rm -f "${index1}" "${index2}"' 0 index1=$(mktemp) index2=$(mktemp) GIT_INDEX_FILE=${index1} git read-tree "$@" GIT_INDEX_FILE=${index2} git read-tree --empty GIT_INDEX_FILE=${index1} git ls-files -s -z | while IFS=$'\t' read -d '' -r info file; do [[ ${file} = app/scripts/site/* ]] && file=app/modules/${file#*/*/*/} printf '%s\t%s\0' "${info}" "${file}" done | GIT_INDEX_FILE=${index2} git update-index --index-info GIT_INDEX_FILE=${index2} git write-tree ) } # Update the index for the 3-way merge. git read-tree -m --aggressive -u \ $(refactor-tree $(git merge-base MERGE_HEAD HEAD)) \ $(git write-tree) \ $(refactor-tree MERGE_HEAD) # Resolve the merge. git merge-index -o git-merge-one-file -a # Commit the results. git commit 

Lo anterior se probó en un repository de demostración creado así:

 git init mkdir -p app/scripts/site cat >app/scripts/site/README.md <<EOF Hello, world! ============= EOF git add app/scripts/site/README.md git commit -m 'base' git checkout -b stable sed -i -e '1s/w/W/' app/scripts/site/README.md git add app/scripts/site/README.md git commit -m 'hotfix' git checkout master -b develop git mv app/scripts/site app/modules rm -rf app/scripts git commit -m 'refactor' cat >>app/modules/README.md <<EOF blah blah blah EOF git add app/modules/README.md git commit -m 'blah' 

Tenga en count que si elimina la línea ============= , la combinación fallará debido a un conflicto en ese file, pero obtiene marcadores de context como de costumbre. Puedes resolverlo a mano e intentar volver a cometerlo.