Git Clone: ​​Juste les fichiers, s'il vous plaît?

141

Je veux cloner un dépôt GIT et ne PAS me retrouver avec un .gitrépertoire. En d'autres termes, je veux juste les fichiers. Y a-t-il un moyen de faire cela?

git clone --no-checkoutfait exactement le contraire de ce que je veux (m'a donné juste le .gitrépertoire).

J'essaie de le faire pour un dépôt distant , pas local, ce qui signifie que ce n'est pas un double de " Comment faire une" exportation git "(comme" svn export ") " (même si la solution pourrait finir par être la même).

Dan Rosenstark
la source
5
duplication possible de Comment faire une "exportation git" (comme "exportation svn")
Greg Hewgill
@Greg Hewgill J'essaie de le faire à partir d'un dépôt distant. Je ne sais pas si cela rend cette question unique, cependant.
Dan Rosenstark
1
Bien que ce soit une question plus récente, mais je pense que cela vaut la peine de vérifier: stackoverflow.com/questions/11497457/…
eonil
1
Voir ma réponse de mise à jour : git archiveest maintenant (Q4 2017) plus précise et n'inclura pas de dossiers vides.
VonC le
1
Je vous en prie. Apparemment, votre commentaire a été signalé et supprimé ... chat.stackoverflow.com/transcript/134259?m=39402889#39402889
VonC

Réponses:

75

La commande git qui serait la plus proche de ce que vous recherchez le ferait git archive.
Voir sauvegarde du projet qui utilise git : il inclura dans une archive tous les fichiers (y compris les sous-modules si vous utilisez le git-archive-allscript)

Vous pouvez ensuite utiliser cette archive n'importe où, en ne renvoyant que des fichiers, pas de .gitrépertoire.

git archive --remote=<repository URL> | tar -t

Si vous avez besoin de dossiers et de fichiers uniquement du premier niveau:

git archive --remote=<repository URL> | tar -t --exclude="*/*"

Pour répertorier uniquement les dossiers de premier niveau d'un référentiel distant:

git archive --remote=<repository URL> | tar -t --exclude="*/*" | grep "/"

Remarque: cela ne fonctionne pas pour GitHub (non pris en charge)

Vous auriez donc besoin de cloner (peu profond pour accélérer l'étape de clonage), puis d'archiver localement :

git clone --depth=1 [email protected]:xxx/yyy.git
cd yyy
git archive --format=tar aTag -o aTag.tar

Une autre option serait de faire un clonage superficiel (comme mentionné ci-dessous), mais en localisant le dossier .git ailleurs.

git --git-dir=/path/to/another/folder.git clone --depth=1 /url/to/repo

Le dossier de dépôt n'inclurait que le fichier, sans .git.

Remarque: git --git-dir est une option de la commandegit , non git clone.


Mise à jour avec Git 2.14.X / 2.15 (Q4 2017): cela évitera d'ajouter des dossiers vides .

" git archive", surtout lorsqu'il est utilisé avec pathspec, stockait un répertoire vide dans sa sortie, même si Git lui-même ne le fait jamais.
Cela a été corrigé.

Voir commit 4318094 (12 sept. 2017) de René Scharfe (``) .
Suggéré par: Jeff King ( peff) .
(Fusionné par Junio ​​C Hamano - gitster- dans commit 62b1cb7 , 25 sept. 2017)

archive: n'ajoutez pas de répertoires vides aux archives

Bien que git ne suive pas les répertoires vides, il git archivepeut être amené à en mettre dans des archives.
Bien que cela soit pris en charge par la base de données d'objets, il ne peut pas être représenté dans l'index et il est donc peu probable qu'il se produise à l'état sauvage.

Comme les répertoires vides ne sont pas pris en charge par git, ils ne doivent pas non plus être écrits dans des archives.
Si un répertoire vide est vraiment nécessaire, il peut être suivi et archivé en y plaçant un .gitignorefichier vide .

VonC
la source
4
Cela a fonctionné pour moi. J'ajouterais encore une chose. Si vous ne vous souciez pas du tout du dossier .git, j'utiliserais cette commande:git --git-dir=/dev/null clone --depth=1 /url/to/repo
HumanSky
Cela ne supprime pas le dossier
.git
@VonC J'ai essayé: git --git-dir = / dev / null clone --depth = 1 / url / to / repo
aliasav
1
git archive --remote=https://github.com/pornel/dssim.git @ | tar -tJe cours tar: This does not look like a tar archive. Cela ne fonctionne pas avec GitHub? Aussi, qu'est-ce que cela @signifie?
André Werlang
2
@ AndréWerlang 7 ans plus tard ... Je ne suis pas trop sûr de la @: je l'ai supprimée. De plus, GitHub ne prend pas en charge une télécommande git archive: j'ai édité la réponse pour proposer une alternative.
VonC
59
git archive --format=tar --remote=<repository URL> HEAD | tar xf -

pris d' ici

Jon Penn
la source
2
--format=tarest inutile. "tar" est la sortie par défaut, pas besoin de spécifier.
VasiliNovikov
1
la tuyauterie tar xest suffisante
Jens Bannmann
42

vous pouvez créer un clone superficiel pour n'obtenir que les dernières révisions:

 git clone --depth 1 git://url

puis supprimez simplement le répertoire .git ou utilisez git archivepour exporter votre arborescence.

tricot
la source
Comment éviter cette erreur lorsque je la mets à jour en répétant le clone: ​​"fatal: le chemin de destination 'XYZ' existe déjà et n'est pas un répertoire vide."
Sohail Si
1
@SohailSi: soit cloner vers un nouvel emplacement, soit supprimer l'ancien répertoire. Vous feriez probablement mieux de simplement récupérer les nouvelles révisions, si vous souhaitez mettre à jour votre copie locale.
knittl
3

Pourquoi ne pas effectuer un clonage puis supprimer le .gitrépertoire pour ne disposer que d'une copie de travail nue?

Edit: Ou en fait, pourquoi utiliser le clone? C'est un peu déroutant quand vous dites que vous voulez un repo git mais sans .gitrépertoire. Si vous voulez dire que vous voulez juste une copie d'un état de l'arborescence, pourquoi ne pas le faire cp -Rdans le shell au lieu du clone git, puis supprimez-le .gitensuite.

Andrew
la source
Merci pour ça. Les fichiers sont dans un référentiel git. J'espérais pouvoir diriger les utilisateurs de Mac pour obtenir une copie du dépôt en une seule ligne, sans que cela devienne un dépôt GIT.
Dan Rosenstark
Vous ne devriez pas avoir des gens qui obtiennent directement le code du dépôt s'ils ne peuvent pas l'utiliser (c'est-à-dire qu'ils n'ont pas le dépôt Git).
alternative
@Amoss Lancement d'une archive tar pour que les gens ne prennent pas constamment le dernier code?
alternatif
1
@mathepic: et pour publier une archive tar, vous avez besoin d'un moyen d'obtenir une copie de travail propre du référentiel - ce qui est exactement la question qui a été posée.
Andrew
1
Lire la réponse ci-dessous et faire un peu de recherche sur Google a conduit à une autre question: stackoverflow.com/questions/160608/... Si vous jetez un œil à l'utilisation de git archive --remote, alors il fait exactement ce que vous (et l'affiche originale ) sont en train de chercher. Edit: c'est ce que Jon a répondu plus bas.
Andrew
2

Il semble que vous vouliez juste une copie du code source. Si tel est le cas, pourquoi ne pas simplement copier le répertoire et exclure le répertoire .git de la copie?

JaredPar
la source
5
C'est ce que je demande: comment faire ça avec git ... Je peux déjà dire qu'il n'y a pas de moyen intégré de le faire à partir des réponses que j'obtiens. Merci quand même!
Dan Rosenstark
2

git checkout -f

Il existe une autre façon de faire cela en séparant le dépôt de l'arborescence de travail.

Cette méthode est utile si vous devez mettre à jour régulièrement ces fichiers git sans git. Par exemple, je l'utilise lorsque j'ai besoin d'extraire des fichiers source et de créer un artefact, puis de copier l'artefact dans un dépôt différent juste pour le déploiement sur un serveur, et je l'utilise également lorsque je pousse le code source vers un serveur lorsque je veux le code source à récupérer et à intégrer dans le répertoire www.

Nous allons créer deux dossiers, un pour le git et un pour les fichiers de travail:

mkdir workingfiles
mkdir barerepo.git

initialisez un dépôt git nu:

cd barerepo.git
git --bare init 

Créez ensuite un hook de post-réception:

touch hooks/post-receive
chmod ug+x hooks/post-receive

Modifiez la post-réception dans votre éditeur préféré:

GIT_WORK_TREE=/path/to/workingfiles git checkout -f
# optional stuff:
cd down/to/some/directory
[do some stuff]

Ajoutez ceci comme télécommande:

git remote add myserver ssh://user@host:/path/to/barerepo.git

Désormais, chaque fois que vous poussez vers ce dépôt nu, il extrait l'arborescence de travail /workingfiles/. Mais /workingfiles/lui-même n'est pas sous contrôle de version; en cours d' exécution git statusen /workingfiles/donnera l'erreur fatal: Not a git repository (or any parent up to mount point /data). Ce ne sont que des fichiers simples.

Contrairement à d'autres solutions, la rm -r .gitcommande n'est pas nécessaire, donc s'il /workingfiles/y a un autre dépôt git, vous n'avez pas à vous soucier de la commande utilisée pour supprimer les fichiers git de l'autre dépôt.

claquer
la source
1
D'accord. Un hook post-receive sur un repo nu est possible ici. +1
VonC
beaucoup de travail si vous essayez juste d'obtenir les fichiers
Rainb
Ce n'est pas beaucoup de travail si vous ne voulez que les fichiers régulièrement.
Slam