Domanda

Come sottoinsieme della domanda distacco-subirectory Già fatto prima e considerando il fatto che anche se sono state fatte molte domande sul processo di scissione e fusione di repository Git, non sono riuscito a trovarne uno che tocchi l'argomento della scissione quando sono presenti sottomoduli.

Quindi nel seguente scenario:

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

Vorrei ottenere due repository con la seguente struttura:

.git/
data/

e

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

Il primo caso non è un problema e può essere risolto facilmente con il metodo descritto in distacco-subirectory.

Il secondo non così tanto. L'esistenza di sottomoduli e il fatto che .Gitmoduli contengono il percorso completo per folder/content/submoduleA e folder/content/submoduleB fa sì che parte della storia sia incoerente poiché .Gitmodules si riferisce a una struttura di directory inesistente (una volta utilizzata il filamento del filtro).

Quindi vorrei sapere se c'è un modo per farlo senza causare una storia incoerente.

È stato utile?

Soluzione

Sospetto (non testato) che un secondo git filter-branch avrebbe l'opportunità di modificare il .gitmodules contenuto per ogni commit del nuovo repository.

Ma in realtà a git submodule split Il comando era in discussione all'inizio del 2009.

Uso proposto:

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

Sostituire submodule_dir con un sottomodulo appena creato, mantenendo tutta la storia di submodule_dir.
Questo comando riscrive anche ogni commit nella cronologia del repository attuale per includere la revisione corretta di sumodule_dir e l'appropriato .gitmodules inserimenti.

Tuttavia, non lo vedo nel Ultimo cosa c'è cucina.
Lo script nella patch proposta può darti un'idea del tipo di riscrittura dell'albero necessario per aggiornare il .gitmodules file però.

Altri suggerimenti

Ho avuto lo stesso identico problema di Usode e sono riuscito a risolverlo con la seguente procedura:

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

Come vedi, il trucco è di rinominare temporaneamente il .gitmodules file e usa sed per riscrivere il suo contenuto. Puoi ottenere tutti i dettagli e il contesto di questa procedura sul mio blog.

Per elaborare la risposta di Kevin: supponendo che non esistessero mai sottomoduli all'esterno cool/cavemen - La cartella staccata (altrimenti editing più elaborato di .Gitmoduli sarà necessaria per rimuovere quelle sezioni extra), questo può essere raggiunto tanto più veloce e in un passaggio usando un 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

Come ulteriore vantaggio, se cool/cavemen non esisteva in ogni revisione o ramo solo quelle revisioni o filiali che contenevano cool/cavemen sarà guardato.

In questo caso potresti voler eseguire quanto segue per rimuovere i riferimenti invariati:

$ 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top