Ma situation était, j'ai un git repo converti de SVN en HG en GIT, et je voulais extraire un seul fichier source. J'ai également eu des caractères étranges comme aÌ (une incompatibilité d'encodage Unicode ä) et des espaces dans les noms de fichiers. Cela ne semble pas particulièrement facile, et c'est la raison pour laquelle je vais répondre à ma propre question malgré de nombreuses questions similaires concernant git [index-filtre | subdirectory-filter | filtre-arbre], comme je devais utiliser tous les précédents pour y parvenir! Donc, la question est: "Comment puis-je extraire un fichier d'un dépôt et le placer à la racine du nouveau repo?"Comment extraire un fichier avec l'histoire de commit d'un repo git avec index-filter & co
Répondre
D'abord une note rapide, que même un sort comme dans un commentaire sur Splitting a set of files within a git repo into their own repository, preserving relevant history
SPELL='git ls-tree -r --name-only --full-tree "$GIT_COMMIT" | grep -v "trie.lisp" | tr "\n" "\0" | xargs -0 git rm --cached -r --ignore-unmatch'
git filter-branch --prune-empty --index-filter "$SPELL" -- --all
ne va pas aider avec les fichiers nommés comme imaging/DrinkkejaI<0300>$'\302\210'.txt_74x2032.gif
. La pièce aI<0300>$'\302\210'
était une seule lettre: ä
.
Ainsi, afin d'extraire un seul fichier, en plus de filtrer branche aussi je devais faire:
git filter-branch -f --subdirectory-filter lisp/source/model HEAD
Vous pouvez également utiliser --tree-filtre: (le test est nécessaire, parce que le fichier était dans un autre répertoire plus tôt, voir How can I move a directory in a Git repo for all commits?)
MV_FILTER='test -f source/model/trie.lisp && mv ./source/model/trie.lisp . || echo "Nothing to do."'
git filter-branch --tree-filter $MV_FILTER HEAD --all
Pour voir tous les noms d'un fichier ont eu, utilisez:
git log --pretty=oneline --follow --name-only git-path/to/file | grep -v ' ' | sort -u
Comme décrit à http://whileimautomaton.net/2010/04/03012432
également suivre les étapes sur la suite:
$ git reset --hard
$ git gc --aggressive
$ git prune
$ git remote rm origin # Otherwise changes will be pushed to where the repo was cloned from
Je ne suis pas sûr de savoir comment suivre ces instructions, le texte de cette réponse semble poser plusieurs voies possibles. Je ne vois aucune procédure. – ThorSummoner
Peut-être que vous devriez voir la documentation git sur la commande filter-branch et sur l'historique de réécriture: - http://git-scm.com/docs/git-filter-branch - http://git-scm.com/ book/fr/v2/Git-Tools-Réécriture-Historique – peterhil
Notez que les choses deviennent beaucoup plus facile si vous combinez cela avec l'étape supplémentaire de déplacer le fichier souhaité (s) dans un nouveau répertoire.
Cela peut être un cas d'utilisation assez courant (par exemple déplacer le fichier unique souhaité vers le répertoire racine).
je l'ai fait (en utilisant git 1.9) comme celui-ci (premier déplacement du fichier (s), puis en supprimant le vieil arbre):
git filter-branch -f --tree-filter 'mkdir -p new_path && git mv -k -f old_path/to/file new_path/'
git filter-branch -f --prune-empty --index-filter 'git rm -r --cached --ignore-unmatch old_path'
Vous pouvez même utiliser facilement des caractères génériques pour les fichiers désirés (sans déconner avec grep -v).
Je penserais que ceci ('mv' et 'rm') pourrait également être fait dans une branche de filtre mais il n'a pas fonctionné pour moi.
Je ne l'ai pas essayé avec des caractères étranges mais j'espère que cela aide de toute façon. Rendre les choses plus faciles semble toujours être une bonne idée pour moi.
Indice:
Cette action prend beaucoup de temps sur les gros dépôts. Donc, si vous voulez faire plusieurs actions (comme obtenir un tas de fichiers et les réorganiser dans 'new_path/subdirs'), c'est une bonne idée de faire la partie 'rm' dès que possible pour obtenir un arbre plus petit et plus rapide.
Je l'ai également essayé sur Ubuntu 12.04 et git 1.7.x avec les résultats suivants: * le problème de permission refusée apparaît aussi sur Ubuntu * git 1.7.x didn ' Je fais bien avec les commandes que j'ai mentionnées ci-dessus (comme 1 seul fichier correspondant a toujours été renommé dans le répertoire où il devrait être déplacé. Donc je recommande git 1.9.x que je cours sur ma machine Windows – Roman
retravaillé mon poste parce que la plupart de mes problèmes semblent provenir de mes compétences bash inexistantes -> utiliser '&&' au lieu de '|' pour combiner les commandes maintenant – Roman
La première étape ne marche pas k pour moi en git 2.2.1. Il n'y a pas de changement au repo. – xixixao
Une plus rapide et plus facile à comprendre filtre qui fait la même chose:
git filter-branch --index-filter '
git read-tree --empty
git reset $GIT_COMMIT -- $your $files $here
' \
-- --all -- $your $files $here
Celui-ci est le meilleur – podarok
Cela a fonctionné parfaitement pour moi. J'ai ajouté un argument '--prune-empty' pour supprimer les validations vides. –
@AaronJensen Les '--all - $ your $ files $ here' de la dernière ligne sont passés à la' git rev-list' que 'filter-branch' exécute, donc les branches de la branche filter du filtre ont déjà été élaguées . C'est beaucoup plus rapide que de faire charger inutilement l'index par le filtre-branche et d'exécuter le filtre et de créer de nouveaux arbres et un commit avant de tout jeter pour les commits qui n'ont pas touché ces fichiers. Pourtant, ça ne fait pas de mal de l'ajouter. – jthill
- 1. Git: fichier commit avec LR avec msys/cygwin Git
- 2. Commit git-svn changements à SVN repo
- 3. GIT annuler un commit
- 4. Patch fourchu repo avec git
- 5. Comment git commit un seul fichier/répertoire
- 6. Git: comment fusionner avec le repo distant?
- 7. Extraire un ancien commit efface le nouveau dans git - pourquoi?
- 8. Comment pousser à repo après avoir fait 'git commit --amend'
- 9. Git problèmes avec repo vide
- 10. supprimer un passé commit git avec de gros fichiers
- 11. Utiliser git-svn avec un repo existant manquant .git/svn/
- 12. Comment configurer git un hook post-commit avec buildbot
- 13. Liaison de sous-dossiers repo avec git
- 14. Est-ce qu'un hook git pre-commit peut ajouter un fichier au repo?
- 15. convertir git repo actuel en un compatible avec git-buildpackage
- 16. Comment utiliser un repo Git cloné comme "maître" et rester synchronisé avec un repo Git distant sur un site client?
- 17. git-svn dcommiter un seul commit git
- 18. reverting push'd git commit
- 19. Supprimer un fichier existant d'un Git Repo
- 20. git commit répertoire
- 21. git push remote repo
- 22. Git - suppression d'un commit
- 23. Est-il possible de cloner uniquement certains commit d'un repo git avec profondeur 1?
- 24. Comment extraire un seul fichier dans GIT
- 25. git: vérifie si commit xyz en repo distant?
- 26. Git commit de python
- 27. Le commit de Grit semble être le dernier commit de Git repo?
- 28. Comment remplacer git repo?
- 29. commit git supprimer tous les fichiers dans repo
- 30. Magasin git repo dans un repo?
Pourquoi voulez-vous extraire seul fichier à partir du repo? – svick
C'est tout ce dont j'ai besoin. Et btw, http://stackoverflow.com/questions/5998987/splitting-a-set-of-files-within-a-git-repo-into-the-own-repository-preserving n'est pas un clone de n'importe quel sous-répertoire- question de filtrage. L'extraction de fichiers nécessite à la fois l'étape --subdirectory-filter et un --index-filter ou --tree-filter. – peterhil
Ou plutôt tout ce que je veux, parce que je vais faire un paquet du fichier unique qui fournit un trie. Je veux aussi l'utiliser dans d'autres projets, et publier dans Github et j'ai du code dans le repo que je ne veux pas faire open source (du moins pour l'instant). – peterhil