Comment extraire un répertoire spécifique avec git

193

J'ai un projet avec git, et je veux juste cloner ou extraire un répertoire spécifique, comme myproject / javascript, tout comme le fait subversion.
faire quelques changements, valider et repousser.
C'est possible?

bluefoot
la source
3
une caisse clairsemée peut vous intéresser (même si vous devez tout récupérer): voir stackoverflow.com/questions/2416815
...

Réponses:

205
  1. cd dans le haut de votre copie de dépôt
  2. git fetch
  3. git checkout HEAD path/to/your/dir/or/file

    • Où " path/..." dans (3) commence au répertoire juste en dessous de la racine du dépôt contenant votre " .../file"

    • Notez qu'au lieu de "HEAD", le code de hachage d'une validation spécifique peut être utilisé, et vous obtiendrez alors la révision (fichier) ou les révisions (dir) spécifiques à cette validation.

Vergueishon
la source
1
Je viens de réaliser que j'ai mal compris la question. Ma réponse traite plutôt de la façon d'extraire un seul fichier, qui peut ensuite être modifié et validé.
vergueishon le
Vous avez abordé le titre de la question, ce qui est assez bon. Cela m'a juste sauvé, donc en ce qui me concerne, c'est la bonne réponse - d'autant plus qu'il s'agissait d'un succès sur Google pour ce problème.
Morgon
21
Cela obtient cependant tout le repo. Pour un projet de 2 Go, cela ne permet pas de gagner beaucoup de temps.
Pithikos
5
Pour ceux qui lisent ces commentaires et ne savent pas comment cela ne répond pas à la question, cette solution ne vous donne qu'une copie de ce seul dossier, mais ce n'est pas une copie de travail, ce qui signifie que vous ne pouvez pas modifier et re -commettre. Donc, comme @Morgon l'a dit, il aborde le titre de la question (vous NE POUVEZ extraire qu'un seul répertoire), mais ne répond pas au corps de la question ("faites quelques changements, validez et repoussez").
msb
@StanHolodnak --n'est cependant pas obligatoire. Il force les bits après cela à être interprétés comme un chemin. Donc, oui, si vous avez un fichier avec le nom --helpque vous souhaitez récupérer, le préfixe avec ces tirets serait nécessaire:git checkout HEAD -- --help
Tim Visée
105

Dans un répertoire vide:

git init
git remote add [REMOTE_NAME] [GIT_URL]
git fetch REMOTE_NAME
git checkout REMOTE_NAME/BRANCH -- path/to/directory
écossais
la source
cela fonctionne si vous souhaitez uniquement utiliser la version distante d'un fichier pour remplacer le fichier local, je pense
Jean
cela tire également le dossier, comment ne pas télécharger le dossier, mais uniquement les choses à l'intérieur du dossier?
Al Kasih
Il n'y a pas besoin fetchni de checkoutcommandes, nous pouvons simplement faire la demande d'extraction après la remote addcommande pour obtenir toute la branche master.
Iqra.
2
Comme Pithkos le souligne dans la réponse acceptée, cette réponse téléchargera également le référentiel distant ENTIER sur votre machine locale. La réponse de shingara est la plus claire: il n'y a aucun moyen de retirer à distance une partie d'un repo. Cependant, pour ceux qui ne se soucient pas de la bande passante de la récupération ENTIÈRE et qui souhaitent créer une copie de travail d'une partie du cache local, la réponse acceptée vous montre comment. Mais je veux juste préciser que l'historique complet du dépôt (dans un format compressé) doit être téléchargé sur votre machine.
Gabe Halsmer
39

Après avoir beaucoup cherché une réponse, ne pas trouver, abandonner, réessayer et ainsi de suite, j'ai finalement trouvé une solution à cela dans un autre fil SO:

Comment git-pull tous sauf un dossier

Pour copier-coller ce qu'il y a:

git init
git remote add -f origin <url>
git config core.sparsecheckout true
echo <dir1>/ >> .git/info/sparse-checkout
echo <dir2>/ >> .git/info/sparse-checkout
echo <dir3>/ >> .git/info/sparse-checkout
git pull origin master

Pour faire ce que OP veut (travailler sur un seul répertoire), ajoutez simplement ce répertoire à .git/info/sparse-checkout, lorsque vous effectuez les étapes ci-dessus.

Un grand merci à @cforbish!

msb
la source
2
Je le poste ici principalement parce que chaque fois que j'essaie de faire une recherche sur Google, c'est un excellent résultat, et ce fil n'est même pas près d'être affiché. :( Je me sens mal de copier-coller, mais je pense que ce sont les meilleures pratiques?
msb
1
C'est la seule solution propre. J'ai essayé les réponses ci-dessus. Après avoir vérifié ma branche avec les autres réponses, je ne pouvais pas extraire et j'avais plusieurs nouveaux fichiers qui devaient être validés. Avec cette solution, tout semble parfait. Mais NOTE: quelle que soit la branche qui a été extraite, git pensera que vous y êtes master. Assurez-vous simplement git branch --set-upstream-to=origin/<branch>de tirer correctement
seebiscuit
12

Ce n'est pas possible. Vous devez extraire tout le référentiel ou rien.

Shingara
la source
1
Même si vous avez besoin de tout récupérer , un tirage sur un arbre de travail de caisse clairsemé serait-il intéressant dans ce cas? Voir stackoverflow.com/questions/2416815/…
VonC
10
Pour ajouter à cela, la raison pour laquelle vous ne pouvez pas extraire uniquement un répertoire est que git utilise le suivi sémantique des données, pas le suivi sémantique des fichiers, de sorte que vous pouvez déplacer de manière transparente du code (ou d'autres données) dans et hors des fichiers sans avoir à en dire la source système de suivi (jusqu'à ce que vous mettiez à jour bien sûr.) Pour cette raison, le code peut également entrer et sortir des répertoires de manière transparente, donc saisir un seul répertoire n'a pas autant de sens. J'espère que cela t'aides.
OmnipotentEntity
12
@OmnipotentEntity Désolé , mais à mon humble avis , il ne a du sens. La mise en œuvre ne doit pas limiter l'utilisation. Git sait ce que sont les répertoires (du moins lors de la création d'une copie de travail locale), il n'y a donc aucune raison pour qu'il ne puisse pas effectuer une opération similaire sur le serveur et simplement envoyer la sortie appropriée. Certes, ce n'est pas actuellement implémenté, mais cela est dû à un manque de fonctionnalité, pas à une impossibilité fondamentale. Personnellement, je pense que c'est une fonctionnalité assez importante mais bon, c'est une des raisons pour lesquelles j'évite git quand c'est possible.
base
10

Peut-être que cette commande peut être utile:

git archive --remote=MyRemoteGitRepo --format=tar BranchName_or_commit  path/to/your/dir/or/file > files.tar

"Et voilà"

fabrice belle
la source
2
Cela télécharge un répertoire spécifique de fichiers à des fins d'archivage, cela ne tire pas une copie que vous pouvez modifier et repousser.
leetNightshade
Très cool. Probablement pas acceptable comme solution à l'OP, mais c'est en fait ce que je recherchais car j'ai juste besoin de rechercher le contenu d'un gros dossier dans un dépôt encore plus grand que je ne veux certainement pas récupérer, et je n'ai pas besoin de modifier / pousser.
Oliver
8

Si vous souhaitez obtenir les dernières modifications d'un répertoire sans le saisir, vous pouvez faire:

$ git -C <Path to directory> pull
feralamillo
la source
4

git clone --filter à partir de Git 2.19

Cette option ignorera en fait la récupération des objets inutiles sur le serveur.

J'ai écrit une réponse détaillée expliquant l'état actuel du support sur: Comment cloner un sous-répertoire uniquement d'un référentiel Git?

Il est très probable que tout ce qui sera mis git cloneen œuvre dans ce domaine aura également des git pullanalogues.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
2

Essayé et testé cela fonctionne!

mkdir <directory name> ;  //Same directory name as the one you want to pull
cd <directory name>;
git remote add origin <GIT_URL>;
git checkout -b '<branch name>';
git config core.sparsecheckout true;
echo <directory name>/ >> .git/info/sparse-checkout;
git pull origin <pull branch name>

J'espère que cela a été utile!

Nnaik
la source
0

Parfois, vous voulez simplement jeter un coup d'œil aux copies précédentes de fichiers sans avoir à passer par les diffs.

Dans un tel cas, il est tout aussi facile de créer un clone d'un référentiel et d'extraire le commit spécifique qui vous intéresse et de jeter un œil au sous-répertoire de ce référentiel cloné. Parce que tout est local, vous pouvez simplement supprimer ce clone lorsque vous avez terminé.

Abizern
la source
-1

Pour tout ce qui a du mal avec les chemins de fichiers théoriques et les exemples comme je l'ai fait, voici un exemple du monde réel: Microsoft propose ses documents et exemples sur git hub, malheureusement, ils rassemblent tous leurs fichiers d'exemple pour un grand nombre de sujets dans ce référentiel:

https://github.com/microsoftarchive/msdn-code-gallery-community-s-z

Je n'étais intéressé que par les fichiers Microsoft Dynamics js dans le chemin

msdn-code-gallery-community-s-z/Sdk.Soap.js/

alors j'ai fait ce qui suit

créer un

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

fichier dans mon dossier référentiels sur le disque

git sparse-checkout init

dans ce répertoire en utilisant cmd sous windows

Le contenu du fichier de

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

est

Sdk.Soap.js/*

enfin faire un

git pull origin master
DM
la source