web-dev-qa-db-fra.com

Comment déplacer un fichier d'un référentiel git vers un autre tout en préservant l'historique

J'essaie de déplacer un seul fichier (appelez-le foo.txt) d'un référentiel à un autre (non lié), en préservant son historique. question d'ebneter montre comment faire cela pour un sous-répertoire. question de taw a quelques astuces et suggestions, mais pas une procédure étape par étape à suivre. question de jkeating avait l'air prometteur, mais n'a pas fonctionné pour moi. Les recherches Google sont vides pour ce cas d'utilisation particulier. Ce que je recherche, c'est une séquence claire de commandes pour y parvenir.

La séquence de commandes que j'ai commencé à suivre était la suivante:

$ git clone source-repo/ source-repo-copy
$ cd source-repo-copy
$ git filter-branch --tree-filter 'test ! "$@" = "foo.txt" && \
  git rm --cached --ignore-unmatch $@ || true' --Prune-empty

La logique de ma commande de filtrage est de git rm tous les fichiers qui ne sont pas foo.txt. J'ai ajouté le || true à la commande pour la forcer à avoir une valeur de retour nulle pour satisfaire la branche de filtre.

Mon intention était de définir source-repo-copy comme une télécommande pour mon référentiel cible (target-repo), et en supposant que git filter-branch a filtré tout sauf foo.txt, récupère et fusionne le repo-copie source dans le repo-cible. Malheureusement, le git filter-branch la commande semblait n'avoir aucun effet. Il a fonctionné sans erreur et est apparu à Grind à travers les 600+ commits dans le repo source, mais quand il a fini, le git log et les fichiers dans source-repo-copy se ressemblaient. Tous les fichiers, sauf foo.txt, ne devraient-ils pas être manquants et tous les commits qui ne l'ont pas touché ne devraient-ils pas être supprimés du journal?

À ce stade, je ne sais pas comment procéder. Aucune suggestion?

45
Randall Cook

Cela a fonctionné pour moi, mais avec tout un répertoire.

Comme indiqué ici

~$ cd neu
~/neu$ git filter-branch --subdirectory-filter FooBar HEAD
~/neu$ git reset --hard
~/neu$ git remote rm Origin
~/neu$ rm -r .git/refs/original/
~/neu$ git reflog expire --expire=now --all
~/neu$ git gc --aggressive
~/neu$ git Prune
~/neu$ git remote add Origin git://github.com/FooBar/neu.git

EDIT: Pour un seul fichier:

Filtrez d'abord le répertoire:

 git filter-branch --Prune-empty --subdirectory-filter myDirectory -- --all

Filtrer le fichier unique:

 git filter-branch -f --Prune-empty --index-filter "git rm --cached --ignore-unmatch $(git ls-files | grep -v 'keepthisfile.txt')"

Faites un peu de nettoyage:

 git reset --hard
 git gc --aggressive
 git Prune

Cela devrait le faire.

36
blang