Como realocar um repo para uma subárvore e mantê-lo em sincronia

Oi,

Acabei de ter um pequeno problema.
Trabalhando em um projeto que incorpora algum código estrangeiro, criei um repositório para gerenciar esse código, pois o desenvolvedor líder não forneceu um.
A integração do código-fonte foi feita diretamente na raiz do repositório que fiz.
Posteriormente, o desenvolvedor forneceu um repositório público com apenas uma pequena diferença. Todo o código estava em uma subpasta.
Procurando uma maneira de manter em sincronia meu repositório diretamente do seu próprio, e como todos os mecanismos git que encontrei funcionam apenas com subárvores descendentes, criei o seguinte script:

#! /bin/bash
# this script will help you to rebase a repository to a subtree of it
# check for provided directory
if [ -z "$1" ]
then
echo
"Need the directory to get content rebased !"
exit 1
fi
DIR
=`echo $1 | sed 's//$//'`
BRANCH
=$(git rev-parse --abbrev-ref HEAD)
NEWBRANCH
="new-$BRANCH-rebased"

# check provided directory exists
if [ -z `git ls-tree master | grep -o $DIR` ]
then
echo
"$DIR does not seem to exist on branch : $BRANCH !"
exit 1
fi

# check for existing target branch
git show
-ref --verify --quiet "refs/heads/$NEWBRANCH"
if [[ $? != 0 ]]
then
HASH
="$(git rev-parse $BRANCH)"
# checkout the target tree in a new branch
git checkout
-b $NEWBRANCH $HASH
else
# rebase the branch
git checkout $NEWBRANCH
&& git rebase -p $BRANCH
fi

# check we are on the right branch
if [[ `git rev-parse --abbrev-ref HEAD` == "$NEWBRANCH" ]]
then
FILTER
="find $DIR/ -maxdepth 1 -type f | xargs -I{} -e mv {} . ; mv $DIR/* .; rmdir $DIR"
git filter
-branch -f --prune-empty --tree-filter "$FILTER" -- && git gc --aggressive
fi

Como usar

  1. copie e cole este código em um script bash (não se esqueça de torná-lo executável).
  2. mude o diretório para o repositório clonado e verifique o branch que você deseja que seja a fonte
  3. execute o script passando a pasta para obter o conteúdo na raiz de um novo branch

O que este script faz

Ele cria uma nova árvore com base na subárvore da pasta e a publica em um novo branch chamado ‘new-SOURCE_BRANCH-rebased’, onde SOURCE_BRANCH é o nome do branch em que você estava antes de executar este script.
Em seguida, ele realoca todas as informações de log originais para manter a consistência.

Se você executar este script uma segunda vez a partir do branch de origem, ele atualizará o branch de destino.

Eric

EDITAR: a última versão deste script está disponível no github aqui: git-rebasetosubtree.sh