Récupérer un seul fichier d'un référentiel


221

Quel est le mécanisme le plus efficace (en ce qui concerne les données transférées et l'espace disque utilisé) pour obtenir le contenu d'un seul fichier à partir d'un référentiel git distant?

Jusqu'à présent, j'ai réussi à trouver:

git clone --no-checkout --depth 1 git@github.com:foo/bar.git && cd bar && git show HEAD:path/to/file.txt

Cela semble toujours exagéré.

Qu'en est-il d'obtenir plusieurs fichiers du référentiel?


3
Aaw. J'adorerais qu'il y ait un moyen intégré de faire l'équivalent de "cat-remote" et "tag-remote".
conny

3
J'ai ce même problème, je veux avoir le même fichier de licence dans 2 dépôts; éditez le fichier dans 1 référentiel puis faites-le mettre à jour automatiquement la copie dans l'autre référentiel.
GlassGhost

Réponses:


144

dans la version 1.7.9.5 de git, cela semble fonctionner pour exporter un seul fichier depuis une télécommande

git archive --remote=ssh://host/pathto/repo.git HEAD README.md

Cela contiendra le contenu du fichier README.md.


27
... Sauf que cela ne fonctionne pas sur GitHub. Dang. :( twitter.com/GitHubHelp/status/322818593748303873
Rob Howard

13
Cela ne semble pas donner le fichier brut mais plutôt un fichier tar avec un seul fichier.
Frerich Raabe

20
@FrerichRaabe vient d'ajouter `| tar -x` à la commande. git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -x cat README.md
renier

12
Vous pouvez utiliser tar -xOpour sortir vers STDOUT pour la tuyauterie, par exempleFILE=README.md && git archive --remote=ssh://host/pathto/repo.git HEAD "$FILE" | tar -xO "$FILE"
paulcm

2
Exactement la réponse que je cherchais, mais je reçois "fatal: opération non prise en charge par le protocole". en réponse de Git. Argh.
mhvelplund

69

Dans le prolongement de la réponse de Jakub . git archiveproduit une archive tar ou zip, vous devez donc diriger la sortie via tar pour obtenir le contenu du fichier:

git archive --remote=git://git.foo.com/project.git HEAD:path/to/directory filename | tar -x

Enregistre une copie de «nom de fichier» à partir de la tête du référentiel distant dans le répertoire actuel.

le :path/to/directory pièce est facultative. S'il est exclu, le fichier récupéré sera enregistré dans<current working dir>/path/to/directory/filename

De plus, si vous souhaitez activer l'utilisation des git archive --remoteréférentiels Git hébergés par git-daemon, vous devez activer l'option de configuration daemon.uploadarch. Voir https://kernel.org/pub/software/scm/git/docs/git-daemon.html


2
S'il s'agit d'un fichier texte et que nous voulons l'enregistrer dans une autre partie, il est préférable d'utiliser: | tar -xO> ~ / destfile.ext
yucer

44

S'il y a une interface web déployée (comme gitweb, cgit, Gitorious, ginatra), vous pouvez l'utiliser pour télécharger un seul fichier (vue «brute» ou «simple»).

Si un autre côté l'a activé , vous pouvez utiliser l'option 's' de git archive--remote=<URL> (et éventuellement la limiter à un répertoire dans lequel se trouve un fichier), par exemple:

$ git archive --remote=git@github.com:foo/bar.git --prefix=path/to/ HEAD:path/to/ |  tar xvf -

Remarque: l'exemple n'a pas été testé!
Jakub Narębski

7
Pour vos propres référentiels, vous devez spécifiquement activer upload-archive si vous utilisez git-daemon (git: // style urls) avec git config daemon.uploadarch truesur le référentiel distant. Par défaut, le démon git désactive l'archive distante avec "fatal: erreur distante: accès refusé ou référentiel non exporté: ..."
patthoyts

+1 L' git archiveapproche a été mon premier essai - mais j'ai remarqué qu'exiger tarsur la machine client n'était pas vraiment pratique pour les utilisateurs de Windows. Nous avons fini par aller chercher sur notre cgitserveur local . Cela fonctionne, mais ce n'est pas aussi rapide que je le souhaiterais (et cela nécessite toujours d'être exécuté unix2dosou similaire sur les machines Windows puisque nous stockons des fichiers avec des terminaisons de ligne Unix dans le référentiel Git).
Frerich Raabe

1
@FrerichRaabe Utilisez -o fetched.zip. Voir également l'option --format = <fmt>.
akhan

5
Pour ce que ça vaut, il ne semble pas que cela fonctionne sur les référentiels hébergés par GitHub. Voir help.github.com/articles/can-i-archive-a-repository et groups.google.com/forum/#!topic/github/z8vLHcX0HxY
vmrob

30

Pas en général, mais si vous utilisez Github:

Pour moi, wgetl'URL brute s'est avérée être la meilleure et la plus simple façon de télécharger un fichier particulier.

Ouvrez le fichier dans le navigateur et cliquez sur le bouton "Raw". Actualisez maintenant votre navigateur, copiez l'URL et faites un wgetou curldessus.

exemple wget:

wget 'https://github.abc.abc.com/raw/abc/folder1/master/folder2/myfile.py?token=DDDDnkl92Kw8829jhXXoxBaVJIYW-h7zks5Vy9I-wA%3D%3D' -O myfile.py

Exemple de boucle:

curl 'https://example.com/raw.txt' > savedFile.txt


3
C'est la solution la plus simple et fonctionne pour tout txt brut que l'on pourrait trouver. curl https://example.com/raw.txt > savedFile.txt
JacobPariseau

L'exemple wget ne fonctionne pas, l'exemple curl le fait cependant.
Kyle Baker

Fonctionne très bien pour moi. Avez-vous mis votre URL entre guillemets sur la ligne de commande?
Ankur Agarwal

cela ne préserve pas l'histoire de
Git

15

Pour exporter un seul fichier depuis une télécommande:

git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -x

Cela va télécharger le fichier README.md dans votre répertoire actuel.

Si vous souhaitez que le contenu du fichier soit exporté vers STDOUT:

git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -xO

Vous pouvez fournir plusieurs chemins à la fin de la commande.


9

Cela ressemble à une solution pour moi: http://gitready.com/intermediate/2009/02/27/get-a-file-from-a-specific-revision.html

git show HEAD~4:index.html > local_file

4signifie quatre révisions à partir de maintenant et ~est un tilde comme mentionné dans le commentaire.


Assurez-vous de remarquer que ce n'est PAS le 'signe moins' '-' entre 'HEAD' et '4', mais le 'tilde' '~'. Apparemment, je n'ai pas assez bien lu les git docs, ou mes lunettes doivent être mises à jour ;-)
Dennis

18
Cela ne semble cependant pas obtenir le fichier à partir d'un référentiel distant, comme les besoins de l'OP.
Mike Weller

Ou: git show HEAD:./my_other_file > local_filesi le fichier n'est pas dans votre
répertoire

1
Aimable demande pour tous les downvoters - veuillez expliquer et clarifier ce qui ne va pas - nous sommes ici pour apprendre et partager :)
Mars Robertson

9
@MichalStefanow: Mike Weller l'a; en particulier, cela ne fonctionne pas sur un référentiel distant. Vous avez au moins besoin d'un clone local, même si vous avez ensuite des télécommandes installées dessus.
Rob Howard

6

J'utilise ceci

$ cat ~/.wgetrc
check_certificate = off

$ wget https://raw.github.com/jquery/jquery/master/grunt.js
HTTP request sent, awaiting response... 200 OK
Length: 11339 (11K) [text/plain]
Saving to: `grunt.js'

Fonctionne pour moi même sans réglages de wgetrc:wget https://raw.github.com/bk322/bk_automates/master/bkubuntu/bkubuntu.bash
Adobe

1
Mon message est plus utile:ERROR: Certificate verification error for raw.github.com: unable to get local issuer certificate. To connect to raw.github.com insecurely, use '--no-check-certificate'.
Kos

3
Cela fonctionne uniquement pour les référentiels publics. Pour les référentiels privés, vous avez besoin d'une authentification.
Ricardo Otero

5

Une variante nuancée de certaines des réponses ici qui répond à la question du PO:

git archive --remote=git@archive-accepting-git-server.com:foo/bar.git \
  HEAD path/to/file.txt | tar -xO path/to/file.txt > file.txt

Cela ne fonctionne pas, github ne prend pas en charge l'archive git.
Philipp Flenker

2
Euh .. git est utilisé pour plus que GitHub
Willem van Ketwich

1
Vous définissez explicitement --remote sur une URL github dans votre réponse ;-)
Philipp Flenker

1
Merci pour les commentaires. Ont modifié la réponse en conséquence.
Willem van Ketwich,

2

Si votre référentiel prend en charge les jetons (par exemple GitLab), générez un jeton pour votre utilisateur, puis accédez au fichier que vous téléchargerez et cliquez sur la sortie RAW pour obtenir l'URL. Pour télécharger le fichier, utilisez:

curl --silent --request GET --header 'PRIVATE-TOKEN: replace_with_your_token' \
'http://git.example.com/foo/bar.sql' --output /tmp/bar.sql

2

J'ai résolu de cette façon:

git archive --remote=ssh://git@gitlab.com/user/mi-repo.git BranchName /path-to-file/file_name | tar -xO /path-to-file/file_name > /path-to-save-the-file/file_name

Si vous le souhaitez, vous pouvez remplacer "BranchName" par "HEAD"


2

Il me semble que le moyen le plus simple d'utiliser ce qui suit:

wget https://github.com/name/folder/file.zip?raw=true

1

La réponse de Yisrael Dov est simple, mais elle ne permet pas la compression. Vous pouvez l'utiliser --format=zip, mais vous ne pouvez pas le décompresser directement avec une commande de canal comme vous pouvez le faire avec tar, vous devez donc l'enregistrer en tant que fichier temporaire. Voici un script:

#!/bin/bash

BASENAME=$0

function usage {
    echo "usage: $BASENAME <remote-repo> <file> ..."
    exit 1
}

[ 2 -gt "$#" ] && { usage; }

REPO=$1
shift
FILES=$@

TMPFILE=`mktemp`.zip
git archive -9 --remote=$REPO HEAD $FILES -o $TMPFILE
unzip $TMPFILE
rm $TMPFILE

Cela fonctionne aussi avec les répertoires.


1

Pour un seul fichier, utilisez simplement la commande wget.

Tout d'abord, suivez la photo ci-dessous pour cliquer sur "raw" pour obtenir l'url, sinon vous téléchargerez le code intégré en html. entrez la description de l'image ici

Ensuite, le navigateur ouvrira une nouvelle page avec le début de l'url avec https://raw.githubusercontent.com/ ...

entrez simplement la commande dans le terminal:

#wget https://raw.githubusercontent.com/...

Un moment, le fichier sera mis dans votre dossier.


Oui, cela fonctionne aussi bien en Python, ou dans d'autres langages de programmation, avec une fonctionnalité REST. Par exemple pour télécharger des modules à partir de différents référentiels ..
Lars GJ

1

Si votre référentiel Git est hébergé sur Azure-DevOps (VSTS), vous pouvez récupérer un seul fichier avec l' API Rest .

Le format de cette API ressemble à ceci:

 https://dev.azure.com/{organization}/_apis/git/repositories/{repositoryId}/items?path={pathToFile}&api-version=4.1?download=true

Par exemple:

 https://dev.azure.com/{organization}/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/items?scopePath=/MyWebSite/MyWebSite/Views/Home/_Home.cshtml&download=true&api-version=4.1

Cela nécessite un jeton API, n'est-ce pas?
Yuriy Pozniak

Dépend de la façon dont vous exécutez l'API
Shayki Abramczyk

0

J'utilise curl, cela fonctionne avec les dépôts publics ou ceux qui utilisent l'authentification de base https via une interface web.

curl -L --retry 20 --retry-delay 2 -O https://github.com/ACCOUNT/REPO/raw/master/PATH/TO/FILE/FILE.TXT -u USER:PASSWORD

Je l'ai testé sur github et bitbucket, fonctionne sur les deux.


0

Si vous voulez obtenir un fichier à partir d'un hachage spécifique + un référentiel distant, j'ai essayé git-archive et cela n'a pas fonctionné.

Vous devrez utiliser git clone et une fois le référentiel cloné, vous devrez alors utiliser git-archive pour le faire fonctionner.

Je poste une question sur la façon de le faire plus simplement dans les archives git à partir d'un hachage spécifique à distance


0

pour bitbucket directement depuis le navigateur (j'ai utilisé safari ...) faites un clic droit sur 'View Raw' et choisissez 'Download Linked File':

entrez la description de l'image ici


0

Si cela ne vous dérange pas de cloner tout le répertoire, cette petite fonction bash / zsh aura pour résultat final de cloner un seul fichier dans votre répertoire actuel (en clonant le dépôt dans un répertoire temporaire et en le supprimant ensuite).

Pro: vous obtenez uniquement le fichier que vous souhaitez

Con: Vous devez encore attendre que le repo entier soit cloné

git-single-file () {
        if [ $# -lt 2 ]
        then
                echo "Usage: $0 <repo url> <file path>"
                return
        fi
        TEMP_DIR=$(mktemp -d)
        git clone $1 $TEMP_DIR
        cp $TEMP_DIR/$2 .
        rm -rf $TEMP_DIR
}

Cette réponse peut aider à créer un clone clairsemé, c'est-à-dire sans frais généraux.
Yuriy Pozniak

0

Solution d'entreprise Github

HTTPS_DOMAIN=https://git.your-company.com
ORGANISATION=org
REPO_NAME=my-amazing-library
FILE_PATH=path/to/some/file
BRANCH=develop
GITHUB_PERSONAL_ACCESS_TOKEN=<your-access-token>

URL="${HTTPS_DOMAIN}/raw/${ORGANISATION}/${REPO_NAME}/${BRANCH}/${FILE_PATH}"

curl -H "Authorization: token ${GITHUB_PERSONAL_ACCESS_TOKEN}" ${URL} > "${FILE_PATH}"

Où trouvons-nous le GITHUB_PERSONAL_ACCESS_TOKEN?
ShadSterling

1
Vous pouvez créer un jeton d'accès personnel en accédant à https: // <votre-serveur-github> / settings / tokens et en cliquant sur le bouton "Générer un nouveau jeton".
Oliver Pearmain

Hmm, nous avons des automatisations qui reçoivent un nom d'utilisateur et un mot de passe, qui sont utilisés pour s'authentifier auprès de plusieurs systèmes qui utilisent le même SSO, donc j'espérais un moyen d'automatiser la génération d'un jeton avec un nom d'utilisateur et un mot de passe.
ShadSterling

0

Si votre objectif est simplement de télécharger le fichier, il existe une application sans tracas appelée gget:

gget github.com/gohugoio/hugo 'hugo_extended_*_Linux-ARM.deb'

L'exemple ci-dessus téléchargerait un seul fichier à partir du hugoréférentiel.

https://github.com/dpb587/gget


-1

En relation avec la réponse de @Steven Penny, j'utilise également wget. De plus, pour décider quel fichier envoyer la sortie, j'utilise -O.

Si vous utilisez gitlabs, une autre possibilité pour l'url est:

wget "https://git.labs.your-server/your-repo/raw/master/<path-to-file>" -O <output-file>

À moins que vous n'ayez le certificat ou que vous n'accédiez à partir d'un serveur de confiance pour l'installation de gitlabs dont vous avez besoin --no-check-certificate comme @Kos l'a dit. Je préfère cela plutôt que de modifier .wgetrc mais cela dépend de vos besoins.

S'il s'agit d'un gros fichier, vous pourriez envisager d'utiliser l'option -c avec wget. Pour pouvoir continuer à télécharger le fichier d'où vous l'avez laissé si l'intention précédente a échoué au milieu.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.