2011-09-15 1 views
2

J'ai un répertoire contenant des bibliothèques utilitaires qui ont été développées dans une branche dans un dépôt git, mais il s'avère qu'elles appartiennent vraiment à un répertoire différent dans un projet différent. J'ai lu et essayé plusieurs fois le Moving Files from one Git Repository to Another, Preserving History de Greg Bayer, mais je suis incapable de préserver l'historique. J'essaye de faire tout cela sous des branches non-master pour être plus sûr car le projet n'est pas encore prêt à fusionner avec le master.Comment déplacer un sous-répertoire d'une branche dans un référentiel git vers une branche dans un référentiel différent, en conservant l'historique?

Voici ce que je fais jusqu'à présent:

Préparation du "DirectoryName" répertoire pour être déplacé de la branche "SomeBranch" du référentiel "Repo1":

cd ~/Desktop 
git clone [email protected]:username/Repo1.git 
cd Repo1 
git checkout -b SomeBranch origin/SomeBranch 
git remote rm origin 
git filter-branch --subdirectory-filter DirectoryName 
mkdir DirectoryName 
git mv *.php *.txt DirectoryName 
git add DirectoryName 
git commit -m "Stripped everything down to just DirectoryName." 

La fusion de la " DirectoryName » répertoire dans la "" branche du "référentiel de SomeBranch Repo2":

cd ~/Desktop 
git clone [email protected]:username/Repo2.git 
cd Repo2 
git checkout -b SomeBranch origin/SomeBranch 
git remote rm origin 
git remote add Repo1 ../Repo1/ 
git pull Repo1 SomeBranch 
git remote rm Repo1 

Lorsque je fais cela, je peux tout décompacter avec succès à "DirectoryName" dans Repo1 (et je peux le ramener à Repo2 aussi), mais l'histoire est perdue. Si je fais un git log -- DirectoryName ou git log -- DirectoryName/SomeFile.php, je vois seulement le "Tout dépouillé à seulement DirectoryName." commettre). Donc, il ya clairement quelque chose qui ne va pas avec ma commande git filter-branch, mais je ne suis pas assez familier avec ça pour savoir quoi. Toutes les suggestions seraient grandement appréciées car nous subissons des changements fondamentaux dans notre base de code, donc je vais devoir le faire relativement fréquemment pendant un certain temps lorsque les choses bougent (mais nous voulons préserver l'historique).

Mise à jour: Comme je l'ai mentionnégit log -- DirectoryName (ou git log -- DirectoryName/SomeFile.php, soit en Repo1 ou Repo2) ne présente aucune autre engage que « tout Bx_boom juste DirectoryName. » commettre, mais si je fais git log je vois l'histoire de commit correcte. Est-ce que j'utilise incorrectement git log ou y a-t-il une corruption qui empêche les commits de s'afficher correctement?

Une autre mise à jour:git log -- DirectoryName-t montrent les commits corrects dans mon original, non modifié Repo1, mais il ne le fait pas montrent les commits correctes après la git filter-branch (et je l'ai essayé git filter-branch --subdirectory-filter DirectoryName -- --all mais mucks avec le " master "branche aussi bien et ne semble pas nécessaire ... même résultat). Cela dit, l'histoire de commit est là après avoir exécuté git filter-branch, je peux tout voir avec git log master.. cela ne semble plus se rapporter au répertoire ou aux fichiers. Des idées?

Répondre

2

Il semble que ce que vous avez fait est bien, c'est juste un malentendu à propos de git log qui pose problème. Git stocke juste l'état de l'arbre à chaque validation, plutôt que d'enregistrer les changements qui ont pris l'arbre de l'état dans une validation à la suivante. Toutefois, si vous utilisez git log pour trouver l'historique d'un fichier ou d'un répertoire particulier, vous pouvez lui indiquer d'essayer de rechercher les changements de nom lorsque l'historique du fichier semble manquer. Vous pouvez le faire avec:

git log --follow -- DirectoryName 

Ou si cela ne fonctionne pas, essayez pour un seul fichier, par exemple

git log --follow -- DirectoryName/whatever.txt 
+0

Eh oui, c'est tout! Il me manquait juste le fait que 'git log' ne suivrait pas automatiquement les renames et tel (et en utilisant' git filter-branch' il faut renommer puisque les fichiers finissent alors dans la racine de l'arbre). – morgant

0

Voilà comment je le ferais:

  1. Créer des correctifs pour tous les commits qui touchent les fichiers dans le sous-répertoire:

    $ c=1; git log --format=%h -- subdir/*|tac|while read commit; do 
    git format-patch --stdout -1 $commit > $(printf '%04d' $c).patch 
    c=$((c+1)) 
    done 
    

    Notez que s'il y a un seul commits qui touche à la fois les fichiers dans le sous-répertoire et à l'extérieur de sous-répertoire, le correctif inclura également le fichier diff sur l'autre fichier, donc vous devrez supprimer ces fichiers, ou faire une branche de filtre pour supprimer ces fichiers faible:

  2. Utilisez git am pour appliquer les patchs sur la branche dans l'autre repo:

    $ git am *.patch 
    
Questions connexes