Pergunta

Como um subconjunto da pergunta destacar-subdirectory Já foi feita antes e considerando o fato de que, embora muitas perguntas tenham sido feitas sobre o processo de dividir e mesclar repositórios Git, não consegui encontrar um que toca o assunto de dividir quando os submódulos estão presentes.

Então, no seguinte cenário:

.git/
.gitmodules
folder/
    data/
    content/
        other_data/
        submoduleA/
        submoduleB/

Eu gostaria de obter dois repositórios com a seguinte estrutura:

.git/
data/

e

.git/
.gitmodules
content/
    other_data/
    submoduleA/
    submoduleB/

O primeiro caso não é um problema e pode ser resolvido facilmente com o método descrito em destacar-subdirectory.

O segundo não tanto. A existência de submódulos e o fato de que .gitmodules contém o caminho completo para folder/content/submoduleA e folder/content/submoduleB faz parte da história ser inconsistente, pois .gitmodules refere-se a uma estrutura de diretório inexistente (uma vez que o ramo de filtro é usado).

Então, eu gostaria de saber se existe uma maneira de fazer isso sem causar história inconsistente.

Foi útil?

Solução

Eu suspeito (não testado) que um segundo git filter-branch teria a oportunidade de modificar o .gitmodules Conteúdo para cada compromisso do novo repo.

Mas na verdade um git submodule split O comando estava em discussão no início de 2009.

Uso proposto:

git submodule split [--url submodule_repo_url] submodule_dir \
    [alternate_dir...]

Substituir submodule_dir com um submódulo recém-criado, mantendo toda a história de submodule_dir.
Este comando também reescreve cada compromisso na história do repositório atual para incluir a revisão correta de sumodule_dir e o apropriado .gitmodules entradas.

No entanto, eu não vejo isso no mais recente o que está cozinhando.
O script no patch proposto pode lhe dar uma idéia do tipo de reescrita de árvores necessária para atualizar o .gitmodules Arquivo embora.

Outras dicas

Eu tive exatamente o mesmo problema que o Unode e consegui resolvê -lo com o seguinte procedimento:

git clone git@github.com:kdeldycke/kev-code.git
cd kev-code
git filter-branch --tree-filter "test -f ./.gitmodules && mv ./.gitmodules ./cool-cavemen/gitmodules || echo 'No .gitmodules file found'" -- --all
git filter-branch --force --prune-empty --subdirectory-filter cool-cavemen --tag-name-filter cat -- --all init..HEAD
git filter-branch --force --tree-filter "test -f ./gitmodules && mv ./gitmodules ./.gitmodules || echo 'No gitmodules file found'" -- --all
git filter-branch --force --tree-filter "test -f ./.gitmodules && sed -i 's/cool-cavemen\///g' ./.gitmodules || echo 'No .gitmodules file found'" -- --all
git remote rm origin
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
git remote add origin git@github.com:kdeldycke/cool-cavemen.git
git push -u origin master --force --tags

Como você vê, o truque é renomear temporariamente o .gitmodules arquivo e uso sed Para reescrever seu conteúdo. Você pode obter todos os detalhes e o Contexto deste procedimento no meu blog.

Para elaborar a resposta de Kevin: supondo que nenhum submódulo jamais existisse lá fora cool/cavemen - A pasta que está sendo destacada (caso contrário, uma edição mais elaborada de .gitmodules será necessária para remover essas seções extras), isso pode ser alcançado Muito de mais rápido e em uma etapa usando um index-filter:

$ git filter-branch --subdirectory-filter cool/cavemen --index-filter $'
hash=$(git rev-parse --verify $GIT_COMMIT:.gitmodules 2>/dev/null) &&
 git update-index --add --cacheinfo 100644 $(git cat-file -p $hash |
 sed \'s/cool\\/cavemen\\///g\' | git hash-object -w --stdin) .gitmodules ||
true' --tag-name-filter cat --prune-empty -- --all

Como um benefício adicional, se cool/cavemen não existia em todas cool/cavemen será analisado.

Se for esse o caso, você pode executar o seguinte para remover referências inalteradas:

$ git for-each-ref --format='%(refname)' | 
 grep -vF "$(git for-each-ref --format='%(refname)' refs/original |
 sed 's/refs\/original\///g')" | xargs -n 1 git update-ref -d
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top