J'ai un référentiel et je voudrais détacher un de ses répertoires dans un nouveau repo. This est un endroit parfait pour commencer, il y a une mise en garde, cependant: le répertoire que je veux détacher a été renommé à un moment donné. Et si je suis la solution de ce poste avec le nouveau nom du répertoire, il semble que je perds l'historique avant le nouveau nom. Des idées d'un tweak pour le faire fonctionner dans cette situation?Détacher le sous-répertoire (qui a été renommé!) Dans un nouveau dépôt
Répondre
git filter-branch
peut fonctionner sur des plages de commits; donc ce que nous pouvons faire est de filtrer le « avant » et « après » séparément, et l'utilisation de greffons pour les virer de bord ainsi:
git branch rename $COMMIT_ID_OF_RENAME
git branch pre-rename rename~
## First filter all commits up to rename, but not rename itself
git filter-branch --subdirectory-filter $OLDNAME pre-rename
## Add a graft, so our rename rev comes after the processed pre-rename revs
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts
## The first filter-branch left a refs backup directory. Move it away so the
## next filter-branch doesn't complain
mv .git/refs/original .git/refs/original0
## Now filter the rest
git filter-branch --subdirectory-filter $NEWNAME master ^pre-rename
## The graft is now baked into the branch, so we don't need it anymore
rm .git/info/grafts
Ceci est légèrement plus complexe si vous avez besoin de filtrer plusieurs branches ou étiquettes; Les branches avant le renommage peuvent être incluses dans la première branche de filtre, tandis que les suivantes doivent être incluses avant la ^rename
dans la seconde branche de filtre.
Une autre option serait d'ajouter un filtre d'index (ou un filtre d'arborescence) à la place qui vérifie les deux répertoires, anciens et nouveaux, et garde celui qui est présent.
Puisque vous n'avez pas fourni un référentiel de test, voici un script bon sens vérification rapide pour ce scénario:
#!/bin/bash
set -u
set -e
set -x
rm -rf .git x y foo
git init
mkdir x
echo initial > x/foo
git add x/foo
git commit -m 'test commit 1'
echo tc2 >> x/foo
git commit -a -m 'test commit 2'
mv x y
git rm x/foo
git add y/foo
git commit -a -m 'test rename'
git branch rename HEAD
echo post rename >> y/foo
git commit -a -m 'test post rename'
git branch pre-rename rename~
git filter-branch --subdirectory-filter x pre-rename
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts
mv .git/refs/original .git/refs/original0
git filter-branch --subdirectory-filter y master ^pre-rename
rm .git/info/grafts
git log -u
Si cette procédure ne fonctionne pas pour vous, alors il est susceptible d'être autre chose étrange à propos de l'historique de votre référentiel que vous n'avez pas décrit, comme un autre changement de nom qui se cache dans l'historique.
Nous (Matthieu Flatt et moi) a écrit un programme pour le faire: https://github.com/samth/git-slice
- 1. Comment puis-je savoir si un fichier a été renommé?
- 2. Comment puis-je savoir si un fichier a été renommé?
- 3. Le dépôt Git a été brisé soudainement
- 4. fichier python a été renommé, comment obtenir 'renommer l'heure'
- 5. Comment suivre qui a été poussé dans un dépôt de Gitose?
- 6. Je fais savoir à git qu'un fichier a été renommé - Le fichier OS X est renommé de minuscules à majuscules
- 7. Comment fusionner les deux fichiers différents après que le fichier a été renommé
- 8. Nouveau dépôt git dans le répertoire racine pour subsumer un dépôt existant dans un sous-répertoire
- 9. ankhsvn: le dépôt a été plié en interne
- 10. Exemple de code de phoneGap qui a été renommé en tant que cordova
- 11. Le fichier de projet '' a été renommé ou n'est plus dans la solution
- 12. Mercurial: pouvez-vous suivre les modifications à travers un fichier qui a été renommé en un autre fichier suivi?
- 13. Détacher une ligne de BindingSource ou de DataTable, qui a été supprimée indépendamment
- 14. array_push retourne seulement le dernier élément qui a été poussé dans le nouveau tableau?
- 15. Charger un fichier qui a été inclus dans le .jar?
- 16. Comment savoir qui a extrait le dépôt dans SVN
- 17. Comment accéder à un fichier depuis une boîte de dépôt qui a déjà été téléchargée via une boîte de dépôt?
- 18. SVN - créer un nouveau dépôt
- 19. Puis-je créer un dépôt github nommé identique à celui qui existait mais qui a été supprimé?
- 20. Installer le paquet qui a été retiré du dépôt CRAN facilement
- 21. Où est le module __builtin__ dans Python3? Pourquoi a-t-il été renommé?
- 22. VB FileSystem.Copy - comment obtenir le nouveau nom de fichier renommé
- 23. Vérifier si un nouveau SMS a été lu
- 24. svn checkout sur le sous-répertoire, qui est ensuite renommé
- 25. Comment mettre à jour l'éditeur GEF si le fichier a été renommé?
- 26. Nouveau dépôt principal
- 27. Mercurial commit sur le nouveau dépôt
- 28. bzr: Détacher un sous-répertoire du référentiel dans un nouveau référentiel
- 29. Comment puis-je déterminer si un élément de la bibliothèque a été déplacé/renommé?
- 30. C# - Bouclage à travers le paramètre d'objet qui a été passé à partir du nouveau thread
Hmm, j'ai essayé votre méthode avec des greffes (dont je ne sais rien) et il ne fonctionne pas pour moi. Après le traitement de l'un des commits "avant" est vide, les fichiers d'un autre ont été déplacés dans la racine du repo; Je ne peux pas le comprendre. Je pensais avant d'utiliser un filtre à arbre mais je n'ai aucune expérience avec ça; auriez-vous intérêt à élaborer me montrer quelques indications? – akoprowski
Etes-vous sûr que le commit précédent utilisait le sous-répertoire correct? Pouvez-vous poster votre repo git quelque part? – bdonlan
Yup, renommer était sur le commit qui a fait le renommage et le pré-renommer juste avant. Le repo est énorme et en partie privé, donc je ne peux pas vraiment le publier n'importe où: | – akoprowski