Tenho um aplicativo da web que explora outros aplicativos da web de uma maneira particular. Ele contém alguns demos da web em uma demos
pasta e um dos demos agora deve ter seu próprio repositório. Eu gostaria de criar um repositório separado para este aplicativo de demonstração e torná-lo umsubpacote submódulo do repositório principal sem perder seu histórico de commits.
É possível manter o histórico de commits dos arquivos na pasta de um repositório e criar um repositório a partir dele e usá-lo como um submódulo ?
git
git-submodules
revision-history
GabLeRoux
fonte
fonte
Respostas:
Solução Detalhada
Na seguinte resposta, você saberá como extrair uma pasta de um repositório e fazer um repositório git a partir dela e então incluí-la como um submódulo em vez de uma pasta.
Inspirado no artigo de Gerg Bayer Movendo Arquivos de um Repositório Git para Outro, Preservando a História
No início, temos algo assim:
Nas etapas abaixo, irei me referir a isso
someLib
como<directory 1>
.No final, teremos algo assim:
Crie um novo repositório git de uma pasta em outro repositório
Passo 1
Obtenha uma nova cópia do repositório para dividir.
Passo 2
A pasta atual será o novo repositório, portanto, remova o remoto atual.
etapa 3
Extraia o histórico da pasta desejada e submeta-o
Agora você deve ter um repositório git com os arquivos
directory 1
da raiz do seu repo com todo o histórico de commits relacionado.Passo 4
Crie seu repositório online e envie seu novo repositório!
Você pode precisar definir o
upstream
branch para seu primeiro envioLimpo
<git repository A>
(opcional, ver comentários)Queremos eliminar traços (arquivos e comprometer história) de
<git repository B>
partir<git repository A>
de modo história para esta pasta está lá apenas uma vez.Isso se baseia na remoção de dados confidenciais do github.
Vá para uma nova pasta e
Substitua
<directory 1>
pela pasta que você deseja remover.-r
fará isso recursivamente dentro do diretório especificado :). Agora empurre paraorigin/master
com--force
Boss Stage (veja a nota abaixo)
Crie um submódulo de
<git repository B>
em<git repository A>
Verifique se tudo funcionou conforme o esperado e
push
Nota
Depois de fazer tudo isso, percebi no meu caso que era mais apropriado usar o npm para gerenciar minhas próprias dependências. Podemos especificar urls e versões do git , ver os urls do git package.json como dependências .
Se você fazê-lo desta forma, o repositório que você deseja usar como um requisito deve ser um módulo npm para que ele deve conter um
package.json
arquivo ou você obterá este erro:Error: ENOENT, open 'tmp.tgz-unpack/package.json'
.tldr (solução alternativa)
Você pode achar mais fácil usar o npm e gerenciar dependências com urls git :
npm init
dentro de ambos os repositóriosnpm install --save git://github.com/user/project.git#commit-ish
onde você deseja que suas dependências sejam instaladasfonte
cd someLib
antes da Etapa 2? Você diz "A pasta atual será o novo repositório", mas na verdade não será; o novo repositório (submódulo) está dentro dessa pasta.refs/original/...
que é criado na etapa 3.A solução de @GabLeRoux esmaga os branches e os commits relacionados.
Uma maneira simples de clonar e manter todos os branches e commits extras:
1 - Certifique-se de ter este alias git
2 - Clone o remoto, puxe todos os branches, mude o remoto, filtre seu diretório, empurre
fonte
A solução de GabLeRoux funciona bem, exceto se você usar
git lfs
e tiver arquivos grandes no diretório que deseja desanexar. Nesse caso, após a etapa 3, todos os arquivos grandes permanecerão como arquivos de ponteiro em vez de arquivos reais. Eu acho que é provavelmente devido ao.gitattributes
arquivo sendo removido no processo de ramificação do filtro.Percebendo isso, acho que a seguinte solução funciona para mim:
Copiar o
.gitattributes
que git lfs usa para rastrear arquivos grandes para o.git/
diretório para evitar que sejam excluídos.Quando filter-branch estiver pronto, não se esqueça de colocar de volta o
.gitattributes
se você ainda quiser usar git lfs para o novo repositório:fonte