2010-07-10 8 views
12

J'ai deux dépôts git qui sont liés tangentiellement. A savoir, le contenu de l'un était un prédécesseur de l'autre. Je voudrais d'une manière ou d'une autre préfixer l'histoire complète du dépôt A au dépositaire B, de sorte que l'astuce de A serait un parent du tout premier ensemble de modifications du référentiel B? Les histoires dans les deux sont assez linéaires.Comment concaténer deux histoires git?

Est-ce possible?

Répondre

9

Vous pouvez essayer d'utiliser le fichier de greffe (.git/info/grafts) où vous pouvez remplacer le parent d'un commit (comme le premier de projectB ayant pour parent le dernier de projectA)

Voir aussi « What are .git/info/grafts for? » et « How to prepend the past to a git repository? » pour en savoir plus sur cette manipulation.


skaleecomments à propos de l'article "Git: Grafting repositories" (de SO utilisateur Ben Straub) pour un exemple concret.

Maintenant, ce que nous voulons faire est de changer le premier commettras dans le repo « nuevo » (« New commit #1 ») de sorte que son parent est le dernier commettras dans le repo « vieux » (« Old # 3 »). Temps pour certains voodoo:

git fetch ../old master:ancient_history 

Git vous permet rapportez de tout autre dépôt git, que ce repo est lié ou non! Brillant! Cela nous laisse avec ceci:

enter image description here

Notez comment nous avons changé le nom de la vieille branche maître à ancient_history. Si nous ne l'avions pas fait, git aurait essayé de fusionner les deux, et probablement abandonné dans le dégoût.

Maintenant, nous avons toujours un problème.
Les deux arbres ne sont pas connectés, et en fait, une traction git n'obtiendra même pas du tout la branche ancient_history. Nous avons besoin d'un moyen de faire un lien entre les deux.

Git dispose d'une fonction appelée greffe, qui fausse fondamentalement un lien parent entre deux commits.
Pour faire un, il suffit d'insérer une ligne dans le fichier .git/info/grafts dans ce format:

[ref] [parent] 

ces deux doivent être le hachage complète des commits en question. Donc, nous allons les trouver:

$ git rev-list master | tail -n 1 
d7737bffdad86dc05bbade271a9c16f8f912d3c6 

$ git rev-parse ancient_history 
463d0401a3f34bd381c456c6166e514564289ab2 

$ echo d7737bffdad86dc05bbade271a9c16f8f912d3c6 \ 
     463d0401a3f34bd381c456c6166e514564289ab2 \ 
     > .git/info/grafts 

(en une ligne, comme suggested par ssokolow)

echo $(git rev-list master | tail -n 1) $(git rev-parse ancient_history) > .git/info/grafts 

Il.Maintenant notre histoire ressemble à ceci:

enter image description here

Clonage ce résultat repo dans ce:

enter image description here

Woops. Il s'avère que les greffes ne sont efficaces que pour le référentiel local. Nous pouvons résoudre ce problème avec l'application judicieuse des git fast-import:

$ git fast-export --all > ../export 

$ mkdir ../nuevo-complete 

$ cd ../nuevo-complete 

$ git init 

$ git fast-import < ../export 
git-fast-import statistics: [...] 

(en une ligne, comme suggested par ssokolow)

git filter-branch $(git rev-parse ancient_history)..HEAD 

Cela convertit efficacement notre lien historique « faux » en sont seules.
Tous les ingénieurs devront re-cloner à partir de ce nouveau référentiel, puisque les hachages seront tous différents, mais c'est un petit prix à payer pour aucun temps d'arrêt et un historique complet.

enter image description here

Comme Qix commentaires below:

fast-import semble importer uniquement les informations git, mais ne vérifie rien sur.
git init à l'origine vous met sur le maître, donc vous avez besoin d'un git reset --hard HEAD pour réellement vérifier les fichiers après vous fast-import.

+0

Travaillé très bien pour moi, merci VonC, ne pensait pas que ce serait aussi simple. – SilentGhost

+1

Ensuite, vous pouvez réécrire l'histoire en utilisant 'git filter-branch' pour rendre ce greffon permanent ... mais cela réécrit l'histoire. –

+0

article court et soigné qui m'a vraiment aidé à comprendre ce que les greffes sont et étape par étape comment se joindre à ces histoires: http://ben.straubnet.net/post/939181602/git-grafting-repositories – skalee

Questions connexes