Migrar branches SVN para Git

Contexto

Durante uma migração de SVN para Git, enfrentei a seguinte situação:

No SVN, quando um branch é criado, ele contém um único commit sendo a base de código inteira.

No Git, um branch é apenas um link simbólico (tipo de) para um commit. Portanto, quando um branch é criado a partir do master, o histórico do branch é igual ao do master.

Depois de migrar os branches SVN no repositório Git, cada branch tinha um ponto de partida diferente, o que complicou as coisas quando o branch teve que ser mesclado de volta no master (muitos conflitos de arquivos existentes em ambos os branches).

Então eu escrevi um script para recriar o branch com base no commit a partir do qual foram criados.

Explicações

Obtenha o primeiro commit da filial

Primeiro, eu tive que encontrar o primeiro commit do branch:

BRANCH_FIRST_COMMIT=`git rev-list $BRANCH | tail -n 1`

Encontre o commit de onde BRANCH_FIRST_COMMIT vem

Então, eu tive que encontrar no pai, quando o ramo foi criado. Para isso, fiz um loop na lista de rev do alvo a partir do último:

COMMIT=$TARGET
DIFF
='1'
while [ ! -z "$DIFF" ]
do
COMMIT
=`git rev-list $COMMIT^ | head -n 1`
DIFF
=`git diff $BRANCH_FIRST_COMMIT $COMMIT | head -n 1`
done

Recrie a filial

Uma vez que o commit foi encontrado, eu recriei o branch deste commit. Eu fiz isso criando um novo branch e selecionando todos os commits do branch original (exceto o primeiro, que é a criação do branch) no recém-criado:

git branch tmp-$BRANCH $COMMIT
git checkout tmp
-$BRANCH
git rev
-list $BRANCH_FIRST_COMMIT..$BRANCH | tac | awk 'NR > 0 { print }' | xargs -I [] sh -c "git cherry-pick []"

Substitua os ramos

Por fim, substituí o branch original pelo recém-criado:

git checkout $BRANCH
git branch
-m $BRANCH-old
git checkout tmp
-$BRANCH
git branch
-m $BRANCH

Versão global

O script completo pode ser encontrado em https://gist.github.com/padawin/9899f82913d237c1fd5c