Separar subdirectory (que se renombró!) En un nuevo repository

Tengo un repository y me gustaría separar uno de sus directorys en un nuevo repository. Este es un lugar perfecto para comenzar, sin embargo, hay una advertencia: el directory que quiero separar se renombró en algún momento. Y si sigo la solución de esa publicación con el nuevo nombre del directory, entonces parece que estoy perdiendo el historial antes de cambiar el nombre. ¿Alguna idea de un ajuste para que funcione en esta situación?

git filter-branch puede operar en ranges de commits; entonces, lo que podemos hacer es filtrar el 'antes' y el 'después' por separado, y usar injertos para unirlos entre sí:

 git branch rename $COMMIT_ID_OF_RENAME git branch pre-rename rename~ ## First filter all commits up to rename, but not rename itself git filter-branch --subdirectory-filter $OLDNAME pre-rename ## Add a graft, so our rename rev comes after the processed pre-rename revs echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts ## The first filter-branch left a refs backup directory. Move it away so the ## next filter-branch doesn't complain mv .git/refs/original .git/refs/original0 ## Now filter the rest git filter-branch --subdirectory-filter $NEWNAME master ^pre-rename ## The graft is now baked into the branch, so we don't need it anymore rm .git/info/grafts 

Esto es marginalmente más complejo si necesita filtrar múltiples twigs o tags; las twigs antes del cambio de nombre pueden includese en la primera twig de filter, mientras que las posteriores deben includese antes del ^rename de ^rename en la segunda twig de filter.

Otra opción sería agregar un filter de índice (o filter de tree) que verifique ambos directorys, antiguo y nuevo, y conserva el que esté presente.

Como no ha proporcionado un repository de testing, aquí hay un guión rápido de comprobación de cordura para este escenario:

 #!/bin/bash set -u set -e set -x rm -rf .git xy foo git init mkdir x echo initial > x/foo git add x/foo git commit -m 'test commit 1' echo tc2 >> x/foo git commit -a -m 'test commit 2' mv xy git rm x/foo git add y/foo git commit -a -m 'test rename' git branch rename HEAD echo post rename >> y/foo git commit -a -m 'test post rename' git branch pre-rename rename~ git filter-branch --subdirectory-filter x pre-rename echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts mv .git/refs/original .git/refs/original0 git filter-branch --subdirectory-filter y master ^pre-rename rm .git/info/grafts git log -u 

Si este procedimiento no funciona para usted, es probable que haya algo más extraño sobre su historial de repository que no haya descrito, como otro cambio de nombre oculto en el historial.

Nosotros (Matthew Flatt y yo) escribimos un progtwig para hacer esto: https://github.com/samth/git-slice