Recuperar um único arquivo de um repositório

220

Qual é o mecanismo mais eficiente (em relação aos dados transferidos e ao espaço em disco usado) para obter o conteúdo de um único arquivo em um repositório git remoto?

Até agora eu consegui pensar em:

git clone --no-checkout --depth 1 [email protected]:foo/bar.git && cd bar && git show HEAD:path/to/file.txt

Isso ainda parece um exagero.

Que tal obter vários arquivos do repositório?

dreftymac
fonte
3
Aaw. Eu adoraria se houvesse uma maneira integrada de fazer o equivalente a "remota de gato" e "remota de etiqueta".
conny
3
Eu tenho esse mesmo problema, quero ter o mesmo arquivo de licença em 2 repositórios; edite o arquivo em 1 repositório e faça com que ele atualize automaticamente a cópia no outro repositório.
GlassGhost
Possível duplicata de Como fazer checkout apenas de um arquivo do repositório git?
Ciro Santilli # 30/16

Respostas:

143

na versão 1.7.9.5 do git, isso parece funcionar para exportar um único arquivo de um controle remoto

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

Isso classificará o conteúdo do arquivo README.md.

Yisrael Dov
fonte
27
... Exceto que não funciona no GitHub. Dang. :( twitter.com/GitHubHelp/status/322818593748303873
Rob Howard
13
Isso não parece produzir o arquivo bruto, mas um arquivo tar com apenas um único arquivo.
Frerich Raabe
20
@FrerichRaabe basta adicionar `| tar -x` para o comando. git archive --remote=ssh://host/pathto/repo.git HEAD README.md | tar -x cat README.md
Renier 21/05
12
Você pode usar tar -xOa saída para STDOUT para tubulação, por exemploFILE=README.md && git archive --remote=ssh://host/pathto/repo.git HEAD "$FILE" | tar -xO "$FILE"
paulcm
2
Exatamente a resposta que eu estava procurando, mas sou "fatal: operação não suportada pelo protocolo". em resposta do Git. Argh.
Mhvelplund
68

Na sequência do Jakub 's resposta . git archiveproduz um arquivo tar ou zip, então você precisa canalizar a saída através do tar para obter o conteúdo do arquivo:

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

Salvará uma cópia de 'filename' do HEAD do repositório remoto no diretório atual.

A :path/to/directorypeça é opcional. Se excluído, o arquivo buscado será salvo em<current working dir>/path/to/directory/filename

Além disso, se você deseja ativar o uso de git archive --remoterepositórios Git hospedados pelo git-daemon, é necessário ativar a opção de configuração daemon.uploadarch. Consulte https://kernel.org/pub/software/scm/git/docs/git-daemon.html

Robert Knight
fonte
2
Se é um arquivo de texto e queremos salvá-lo em outra parte, é essencial usar: | tar -xO> ~ / destfile.ext
yucer
44

Se houver uma interface da web implantada (como gitweb, cgit, Gitorious, ginatra), você poderá usá-la para fazer o download de um único arquivo (visualização "bruta" ou "simples").

Se o outro lado o ativou , você pode usar a opção git archive 's' --remote=<URL>'(e possivelmente limitá-la a um diretório no qual o arquivo reside), por exemplo:

$ git archive [email protected]:foo/bar.git --prefix=path/to/ HEAD:path/to/ |  tar xvf -
Jakub Narębski
fonte
Nota: o exemplo não foi testado!
21749 Jakub Narębski
7
Para seus próprios repositórios, você precisa ativar especificamente o upload-archive se estiver usando o git-daemon (git: // style urls) com git config daemon.uploadarch trueno repositório remoto. Por padrão, o git daemon desabilita o arquivamento remoto com "fatal: erro remoto: acesso negado ou repositório não exportado: ..."
patthoyts
+1 A git archiveabordagem foi minha primeira tentativa - mas notei que exigir tarna máquina cliente não era exatamente conveniente para os usuários do Windows. Acabamos buscando no nosso cgitservidor local . Funciona, mas não é tão rápido quanto eu gostaria que fosse (e ainda requer execução unix2dosou semelhante em máquinas Windows, pois armazenamos arquivos com as terminações de linha Unix no repositório Git).
Frerich Raabe
1
@FrerichRaabe Use -o fetched.zip. Veja também a opção --format = <fmt>.
Akhan # 6/14
5
Pelo que vale, não parece que isso funcione nos repositórios hospedados no GitHub. Consulte help.github.com/articles/can-i-archive-a-repository and groups.google.com/forum/#!topic/github/z8vLHcX0HxY
vmrob
30

Não em geral, mas se você estiver usando o Github:

Para mim, wgeto URL bruto acabou sendo a melhor e mais fácil maneira de baixar um arquivo específico.

Abra o arquivo no navegador e clique no botão "Raw". Agora atualize seu navegador, copie o URL e faça um wgetou curlnele.

wget exemplo:

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

Exemplo de ondulação:

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

Ankur Agarwal
fonte
3
Essa é a solução mais fácil e funciona para qualquer txt bruto que você possa encontrar. curl https://example.com/raw.txt > savedFile.txt
JacobPariseau
O exemplo wget não funciona, mas o exemplo curl funciona.
Kyle Baker
Funciona muito bem para mim. Você colocou seu URL entre aspas na linha de comando?
Ankur Agarwal
isso não preservar a história git
crypdick
15

Para exportar um único arquivo de um controle remoto:

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

Isso fará o download do arquivo README.mdno seu diretório atual.

Se você deseja que o conteúdo do arquivo seja exportado para STDOUT:

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

Você pode fornecer vários caminhos no final do comando.

Kousha
fonte
9

Parece uma solução para mim: http://gitready.com/intermediate/2009/02/27/get-a-file-from-a-specific-revision.html

git show HEAD~4:index.html > local_file

onde 4significa quatro revisões a partir de agora e ~é um til como mencionado no comentário.

Mars Robertson
fonte
Observe que NÃO é o 'sinal de menos' '-' entre 'HEAD' e '4', mas o 'til' '~'. Aparentemente eu não li os docs git bem o suficiente, ou meus óculos precisam de atualização ;-)
Dennis
18
Porém, isso não parece obter o arquivo de um repositório remoto, como o OP precisa.
Mike Weller
Ou: git show HEAD:./my_other_file > local_filese o arquivo não está na sua dir raiz :)
kenorb
1
Solicitação de tipo para todos os downvoters - por favor, explicar e esclarecer o que não é OK - estamos aqui para aprender e compartilhar :)
Mars Robertson
9
@MichalStefanow: Mike Weller tem; especificamente, isso não funciona em um repositório remoto. Você precisa de um clone local, no mínimo, mesmo se tiver controles remotos configurados nele.
Rob Howard
6

Eu uso isso

$ 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'
Steven Penny
fonte
Funciona para mim mesmo sem ajustes do wgetrc:wget https://raw.github.com/bk322/bk_automates/master/bkubuntu/bkubuntu.bash
Adobe
1
Minha mensagem é mais útil: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
Isso funciona apenas para repositórios públicos. Para repositórios particulares, você precisa de autenticação.
Ricardo Otero
5

Uma variante diferenciada de algumas das respostas aqui que responde à pergunta do OP:

git archive [email protected]:foo/bar.git \
  HEAD path/to/file.txt | tar -xO path/to/file.txt > file.txt
Willem van Ketwich
fonte
Isso não funciona, o github não suporta o arquivo git.
Philipp Flenker 12/09
2
Err .. git é usado para mais do que apenas GitHub
Willem van Ketwich
1
Você define explicitamente --remote a um github URL em sua resposta embora ;-)
Philipp Flenker
1
Obrigado pelo feedback. Alterou a resposta em conformidade.
Willem van Ketwich
2

Se o seu repositório suportar tokens (por exemplo, GitLab), gere um token para o usuário, navegue até o arquivo que você fará o download e clique na saída RAW para obter o URL. Para baixar o arquivo, use:

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

Eu resolvi desta maneira:

git archive --remote=ssh://[email protected]/user/mi-repo.git BranchName /path-to-file/file_name | tar -xO /path-to-file/file_name > /path-to-save-the-file/file_name

Se desejar, você pode substituir "BranchName" por "HEAD"

matiasmasca
fonte
2

Parece-me a maneira mais fácil de usar o seguinte:

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

A resposta de Yisrael Dov é direta, mas não permite a compressão. Você pode usá-lo --format=zip, mas não pode descompactá-lo diretamente com um comando de pipe como pode com o tar, portanto, você deve salvá-lo como um arquivo temporário. Aqui está um 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

Isso funciona com diretórios também.

naught101
fonte
1

Para um arquivo único, basta usar o comando wget.

Primeiro, siga a foto abaixo para clicar em "bruto" para obter o URL, caso contrário, você fará o download do código incorporado no html. insira a descrição da imagem aqui

Em seguida, o navegador abrirá uma nova página com o URL iniciado por https://raw.githubusercontent.com/ ...

basta digitar o comando no terminal:

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

Um pouco o arquivo será colocado na sua pasta.

malajisi
fonte
Sim, isso também funciona bem no Python, ou em outras linguagens de programação, com uma funcionalidade REST. Por exemplo, para fazer o download módulos de diferentes repositórios ..
Lars GJ
1

Se o seu repositório Git estiver hospedado no Azure-DevOps (VSTS), você poderá recuperar um único arquivo com a API Rest .

O formato desta API se parece com o seguinte:

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

Por exemplo:

 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
Shayki Abramczyk
fonte
Requer token de API, não é?
Yuriy Pozniak
Depende de como você executa a API
Shayki Abramczyk 7/11/19
0

Eu uso curl, ele funciona com repositórios públicos ou com autenticação básica https através de uma interface da web.

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

Eu testei no github e no bitbucket, funciona em ambos.

JasonS
fonte
0

Se você deseja obter um arquivo de um hash + um repositório remoto específico, tentei o git-archive e não funcionou.

Você teria que usar o git clone e, uma vez que o repositório é clonado, você teria que usar o git-archive para fazê-lo funcionar.

Postei uma pergunta sobre como fazê-lo mais simples no arquivo git a partir de um hash específico do controle remoto

Fernanda Martins
fonte
0

para bitbucket diretamente do navegador (usei o safari ...), clique com o botão direito do mouse em 'View Raw "e escolha" Download Linked File ":

insira a descrição da imagem aqui

ingconti
fonte
0

Se você não se importa em clonar o diretório inteiro, essa pequena função bash / zsh terá como resultado final a clonagem de um único arquivo no diretório atual (clonando o repo em um diretório temporário e removendo-o posteriormente).

Pro: você só obtém o arquivo que deseja

Contras: Você ainda precisa esperar o repo inteiro clonar

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
}
Christopher Shroba
fonte
Essa resposta pode ajudar a tornar o clone esparso, sem sobrecarga.
Yuriy Pozniak
0

Solução Github Enterprise

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}"
Oliver Pearmain
fonte
Onde encontramos o GITHUB_PERSONAL_ACCESS_TOKEN?
ShadSterling 23/03
1
Você pode criar um token de acesso pessoal acessando https: // <seu servidor de github> / settings / tokens e pressionando o botão "Gerar novo token".
Oliver Pearmain
Hmm, temos automações que recebem um nome de usuário e senha, que são usados ​​para autenticar em vários sistemas que usam o mesmo SSO, então eu esperava uma maneira de automatizar a geração de um token com um nome de usuário e senha.
ShadSterling 25/03
0

Se seu objetivo é apenas fazer o download do arquivo, há um aplicativo sem complicações chamado gget:

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

O exemplo acima baixaria um arquivo único do hugorepositório.

https://github.com/dpb587/gget

Granitosaurus
fonte
-1

Relacionado à resposta de Steven Penny, eu também uso o wget. Além disso, para decidir qual arquivo enviar a saída, eu uso -O.

Se você estiver usando o gitlabs, outra possibilidade para o URL é:

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

A menos que você tenha o certificado ou acesse a partir de um servidor confiável para a instalação do gitlabs, você precisará --no-check-certificate, como disse o @Kos. Prefiro isso do que modificar o .wgetrc, mas isso depende das suas necessidades.

Se for um arquivo grande, você pode considerar usar a opção -c com o wget. Para poder continuar baixando o arquivo de onde você o deixou, se a intenção anterior falhar no meio.

Hector Llorens
fonte