Git Clone: ​​Apenas os arquivos, por favor?

141

Eu quero clonar um repositório GIT e NÃO acabar com um .gitdiretório. Em outras palavras, eu apenas quero os arquivos. Existe uma maneira de fazer isso?

git clone --no-checkoutfiz exatamente o oposto do que eu quero (me deu apenas o .gitdiretório).

Estou tentando fazer isso em um repositório remoto , não local, o que significa que não é uma duplicata de " Como fazer uma" exportação git "(como" svn export ") " (mesmo que a solução possa acabar sendo a mesmo).

Dan Rosenstark
fonte
@ Greg Hewgill Estou tentando fazer isso de um repositório remoto. Não tenho certeza se isso faz com que essa pergunta seja única.
Dan Rosenstark 16/10/10
1
Embora esta é uma questão nova, mas acho que isso vale a pena conferir: stackoverflow.com/questions/11497457/...
eonil
1
Veja minha resposta de atualização : git archiveagora é (Q4 2017) mais precisa e não inclui pastas vazias.
VonC 28/09
1
Você é bem vindo. Aparentemente, o seu comentário foi marcado e removido ... chat.stackoverflow.com/transcript/134259?m=39402889#39402889
VonC

Respostas:

75

O comando git que seria o mais próximo do que você está procurando seria git archive.
Veja o projeto de backup que usa o git : ele incluirá em um arquivo todos os arquivos (incluindo submódulos se você estiver usando o git-archive-allscript)

Você pode usar esse arquivo em qualquer lugar, devolvendo apenas arquivos, sem .gitdiretório.

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

Se você precisar de pastas e arquivos apenas do primeiro nível:

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

Para listar apenas as pastas de primeiro nível de um repositório remoto:

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

Nota: isso não funciona no GitHub (não suportado)

Portanto, você precisará clonar (superficialmente para acelerar a etapa de clone) e arquivar localmente :

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

Outra opção seria fazer um clone superficial (como mencionado abaixo), mas localizando a pasta .git em outro lugar.

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

A pasta repo incluiria apenas o arquivo, sem .git.

Nota: git --git-dir é uma opção do comandogit , não git clone.


Atualização com o Git 2.14.X / 2.15 (quarto trimestre de 2017): evitará adicionar pastas vazias .

" git archive", especialmente quando usado com o pathspec, armazenava um diretório vazio em sua saída, mesmo que o próprio Git nunca o faça.
Isso foi corrigido.

Veja commit 4318094 (12 de setembro de 2017) de René Scharfe (``) .
Sugerido por: Jeff King ( peff) .
(Mesclado por Junio ​​C Hamano - gitster- na confirmação 62b1cb7 , 25 de setembro de 2017)

archive: não adicione diretórios vazios aos arquivos

Enquanto o git não rastreia diretórios vazios, git archivepode ser levado a colocar alguns em arquivos.
Embora isso seja suportado pelo banco de dados de objetos, ele não pode ser representado no índice e, portanto, é improvável que ocorra na natureza.

Como diretórios vazios não são suportados pelo git, eles também não devem ser gravados em arquivos.
Se um diretório vazio for realmente necessário, ele poderá ser rastreado e arquivado colocando um .gitignorearquivo vazio nele.

VonC
fonte
4
Isso funcionou para mim. Eu acrescentaria mais uma coisa. Se você não se importa com a pasta .git, então eu usaria este comando:git --git-dir=/dev/null clone --depth=1 /url/to/repo
HumanSky
Isso não remove a pasta
.git
@VonC Eu tentei: git --git-dir = / dev / null clone --depth = 1 / url / to / repo
aliasav
1
Correndo git archive --remote=https://github.com/pornel/dssim.git @ | tar -teu entendo tar: This does not look like a tar archive. Não funciona com o GitHub? Além disso, o que @significa?
André Werlang
2
@ AndréWerlang 7 anos depois ... Não tenho muita certeza do @: removi-o. Além disso, o GitHub não suporta um controle remoto git archive: editei a resposta para propor uma alternativa.
VonC
59
git archive --format=tar --remote=<repository URL> HEAD | tar xf -

tirado daqui

Jon Penn
fonte
2
--format=taré desnecessário. "tar" é a saída padrão, sem necessidade de especificar.
VasiliNovikov
1
tubulação em tar xé suficiente
Jens Bannmann
42

você pode criar um clone superficial para obter apenas as últimas revisões:

 git clone --depth 1 git://url

simplesmente exclua o diretório .git ou use-o git archivepara exportar sua árvore.

knittl
fonte
Como evitar esse erro quando o atualizo repetindo o clone: ​​"fatal: o caminho de destino 'XYZ' já existe e não é um diretório vazio."
Sohail Si
1
@ShahailSi: clone para um novo local ou remova o diretório antigo. Provavelmente, é melhor buscar as novas revisões, se quiser atualizar sua cópia local.
knittl
3

Por que não executar um clone e excluir o .gitdiretório para obter apenas uma cópia de trabalho?

Edit: Ou, de fato, por que usar clone? É um pouco confuso quando você diz que deseja um repositório git, mas sem um .gitdiretório. Se você quer apenas uma cópia de algum estado da árvore, por que não fazer isso cp -Rno shell em vez do clone git e depois excluir o .gitarquivo depois?

Andrew
fonte
Obrigado por isso. Os arquivos estão em um repositório git. Eu esperava poder direcionar os usuários de Mac para obter uma cópia do repositório em uma linha, sem que ele se tornasse um repositório GIT.
Dan Rosenstark 15/10/10
Você não deve ter pessoas que obtenham código diretamente do repositório se elas não puderem usá-lo (ou seja, não possuem o repositório Git).
alternativa
@ Amoss Liberando um tarball para que as pessoas não estejam constantemente pegando o código mais recente?
alternativa
1
@mathepic: e para liberar um tarball, você precisa de uma maneira de obter uma cópia de trabalho limpa do repositório - que é exatamente a pergunta que foi feita.
Andrew
1
Ler a resposta abaixo e depois pesquisar um pouco no Google levou a outra pergunta: stackoverflow.com/questions/160608/… Se você der uma olhada no uso do git archive --remote, ele faz exatamente o que você (e o pôster original ) estão procurando. Edit: que é o que Jon respondeu mais abaixo.
23313 Andrew
2

Parece que você só quer uma cópia do código fonte. Se sim, por que não copiar o diretório e excluir o diretório .git da cópia?

JaredPar
fonte
5
É isso que estou perguntando: como fazer isso com o git ... Já posso dizer que não há uma maneira integrada de fazer isso a partir das respostas que estou recebendo. Obrigado mesmo assim!
Dan Rosenstark 15/10/10
2

git checkout -f

Há outra maneira de fazer isso dividindo o repositório da árvore de trabalho.

Este método é útil se você precisar atualizar esses arquivos git-less git regularmente. Por exemplo, eu o uso quando preciso fazer o check-out dos arquivos de origem e criar um artefato, depois copio o artefato em um repositório diferente apenas para implantação em um servidor e também o uso ao enviar o código-fonte para um servidor quando desejo o código-fonte para efetuar o checkout e incorporar o diretório www.

Criaremos duas pastas, uma para o git e para os arquivos de trabalho:

mkdir workingfiles
mkdir barerepo.git

inicialize um repositório bare git:

cd barerepo.git
git --bare init 

Em seguida, crie um gancho pós-recebimento:

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

Edite o pós-recebimento no seu editor favorito:

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

Adicione isso como um controle remoto:

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

Agora, toda vez que você enviar para esse repositório simples, ele fará o checkout da árvore de trabalho para /workingfiles/. Mas /workingfiles/ele próprio não está sob controle de versão; correndo git statusem /workingfiles/dará o erro fatal: Not a git repository (or any parent up to mount point /data). São apenas arquivos simples.

Ao contrário de outras soluções, o rm -r .gitcomando não é necessário, portanto, se /workingfiles/houver algum outro repositório git, você não precisa se preocupar com o comando usado para remover os arquivos git do outro repositório.

bater
fonte
1
Acordado. Um gancho pós-recebimento em um repositório simples é possível aqui. +1
VonC
muito trabalho, se você está apenas tentando obter os arquivos
Rainb
Não é muito trabalhoso se você deseja apenas os arquivos regularmente.
Slam