Não é específico para alterar conjuntos ou revisões, mas clonar o mais recente em um ramo específico pode ser tão eficaz ou seja git clone -b 10.1 https://github.com/MariaDB/server.git --depth=1 mariadb-server-src
Deseja que a história seja superficial, ou seja, contenha apenas a revisão 3 no seu exemplo ou também os pais?
sschuberth
Se o repositório em questão estiver sendo clonado de dentro de outro repositório e você desejar clonar esse repositório interno em um sha específico, os sub-módulos git farão exatamente isso de maneira auto-mágica.
precisa saber é o seguinte
Respostas:
203
ATUALIZAÇÃO 2 Desde o Git 2.5.0, o recurso descrito abaixo pode ser ativado no lado do servidor com variável de configuração uploadpack.allowReachableSHA1InWant, aqui a solicitação do recurso GitHub e o GitHub confirmam a ativação desse recurso . Observe que alguns servidores Git ativam essa opção por padrão, por exemplo, o Bitbucket Server a ativou desde a versão 5.5+ . Veja esta resposta no Stackexchange para um exemplo de como ativar a opção de configuração.
ATUALIZAÇÃO 1 Para versões Git, 1.7 < v < 2.5use git clone e git reset, conforme descrito na resposta de Vaibhav Bajpai
Se você não deseja buscar o repositório completo, provavelmente não deve usá-lo clone. Você sempre pode usar a busca para escolher a ramificação que deseja buscar. Eu não sou um especialista em hg, então não sei os detalhes, -rmas no git você pode fazer algo assim.
# make a new blank repository in the current directory
git init
# add a remote
git remote add origin url://to/source/repository
# fetch a commit (or branch or tag) of interest
# Note: the full history up to this commit will be retrieved unless
# you limit it with '--depth=...' or '--shallow-since=...'
git fetch origin <sha1-of-commit-of-interest>
# reset this repository's master branch to the commit of interest
git reset --hard FETCH_HEAD
@artur: Você não acha que funciona, ou você já tentou e não funciona?
CB Bailey
37
Com o git 1.4, descobri que era capaz de usar o git fetch origin <SHA1>para alternar para qualquer revisão que desejava, depois de buscar o mestre no controle remoto e fazer isso reset --hardpara instanciar a ramificação localmente. Não pude buscar diretamente as revisões individuais. Com o git 1.7, git fetch origin <SHA1>não funcionou, conforme relatado pelo @artur; você precisa usar git checkout <SHA1>seguido de a reset --hard.
Esta resposta está desatualizada. Isso não funciona com o git 1.7 nem o git 1.8, nem com o protocolo https: // nem ssh. ("Não foi possível encontrar a ref remota df44398762393c67af487edeb0831ad9579df4aa" - não é uma ref, é uma confirmação.)
Isso funciona apenas se o commit estiver na ramificação principal, caso contrário, irá atrapalhar a referência local. Por que o git reset e não o git checkout em primeiro lugar?
Joky
72
Esta não é uma boa opção para grandes repositórios, pois puxa tudo.
Incógnito
11
Esta solução deve estar no topo. Ninguém se importa que "não seja o ideal", é o que o OP pediu. Especificamente: "como clonar o repositório git com revisão específica"?
Florian Segginger 18/03/16
20
@FlorianSegginger Se estou procurando clonar uma revisão específica, provavelmente não quero clonar tudo, mas apenas essa revisão. Para mim, essa foi a pergunta. Esta solução responde a uma pergunta diferente: "Como vejo uma revisão específica no meu repo?". Buscar o repositório inteiro é exatamente o que muitas pessoas aqui querem evitar.
Renato
11
Não aborda a questão real IMHO, já que poder especificar uma revisão durante o clone também me permite usar o --depthque é muito importante para grandes repositórios. Esta solução requer puxar todos os objetos e redefinir para uma revisão anterior. Isso consome muito tempo e desperdiça largura de banda da rede.
void.pointer
54
A clonagem de um repositório git, apropriadamente, clona o repositório inteiro: não há como selecionar apenas uma revisão para clonar. No entanto, depois de executar git clone, você pode fazer o check-out de uma revisão específica fazendo isso checkout <rev>.
Não quero clonar apenas uma revisão. Eu só quero especificar o limite de clonagem. Em outras palavras, quero clonar tudo até a revisão especificada.
John
6
Você não pode fazer isso. git cloneagarra o repositório inteiro. Depois de obtê-lo, você poderá fazer o checkout de uma revisão específica.
4
Uma coisa a notar; O Git geralmente é bastante eficiente para armazenar histórico, por isso não é como se você economizasse uma quantidade enorme de espaço clonando apenas metade das revisões.
22610 Amber
Não se trata de "economizar espaço" - trata-se apenas de fazer uma revisão específica - como se uma nova mudança introduzisse um bug e, portanto, eu não quero essa nova mudança - você está dizendo que o Git não pode fazer isto? Isso não pode estar certo - por que ter controle de origem, se você não pode reverter para uma versão mais antiga?
precisa saber é o seguinte
11
"não existe uma maneira de selecionar apenas uma revisão para clonar" - sim, existe:git clone --single-branch ...
morxa 2/16/16
33
Para clonar apenas um único commit específico em uma ramificação ou marca específica, use:
git clone --depth=1 --branch NAME https://github.com/your/repo.git
Infelizmente, NAMEsó pode ser o nome do ramo ou o nome da marca (não confirma o SHA).
Omita a --depthbandeira para fazer o download de todo o histórico e faça check-out dessa ramificação ou tag:
git clone --branch NAME https://github.com/your/repo.git
Isso funciona com a versão recente do git (eu fiz isso com a versão 2.18.0).
Isso precisa de mais votos. Isso é muito melhor do que outras respostas desatualizadas.
Étienne
32
Se você quer buscar tudo, desde o início até um ponto específico, a resposta de Charles Bailey é perfeita. Se você deseja fazer o inverso e recuperar um subconjunto do histórico desde a data atual, você pode usar git clone --depth [N] onde N é o número de rotações do histórico que deseja. Contudo:
--profundidade
Crie um clone superficial com um histórico truncado para o número especificado de revisões. Um repositório superficial tem várias limitações (você não pode clonar ou buscar dele, nem empurrá-lo nem empurrá-lo), mas é adequado se você estiver interessado apenas no histórico recente de um grande projeto com um longo histórico e desejar envie correções como patches.
Passo 4 não funcionou para mim, mas até a etapa 3 fez o truque - Graças
Gene Bo
@ BrainSlugs83: O passo 4 cria um ramo local chamado mastere muda para ele.
precisa saber é
3
@phill: Por que o git reset --hard? Os documentos para isso dizem "Redefine o índice e a árvore de trabalho. Quaisquer alterações nos arquivos rastreados na árvore de trabalho desde que <commit> [cujo padrão é HEAD, que agora é <sha1 rev>] são descartadas". Mas neste momento não fizemos nenhuma alteração desde a clonagem, então qual é o objetivo? Trunca a ramificação atual em <sha1 rev>?
precisa saber é
19
TL; DR - Basta criar uma tag no repositório de origem contra a confirmação que você deseja clonar e usar a tag no comando buscar. Você pode excluir a tag do repositório original posteriormente para limpar.
Bem, em 2014 e parece que a resposta aceita por Charles Bailey a partir de 2010 está bem e verdadeiramente desatualizada agora e a maioria (todas?) Das outras respostas envolve clonagem, o que muitas pessoas esperam evitar.
A solução a seguir alcança o que o OP e muitos outros estão procurando, que é uma maneira de criar uma cópia de um repositório, incluindo histórico, mas apenas até um determinado commit.
Aqui estão os comandos que usei com o git versão 2.1.2 para clonar um repositório local (por exemplo, um repositório em outro diretório) até um certo ponto:
# in the source repository, create a tag against the commit you want to check out
git tag -m "Temporary tag" tmptag <sha1>
# create a new directory and change into that directory
cd somewhere_else;mkdir newdir;cd newdir
# ...and create a new repository
git init
# add the source repository as a remote (this can be a URL or a directory)
git remote add origin /path/to/original/repo
# fetch the tag, which will include the entire repo and history up to that point
git fetch origin refs/tags/tmptag
# reset the head of the repository
git reset --hard FETCH_HEAD
# you can now change back to the original repository and remove the temporary tag
cd original_repo
git tag -d tmptag
Esperamos que esta solução continue funcionando por mais alguns anos! :-)
como a anterior - por que fazer check-out depois de clonar. Depois de clonar, você tem todo o histórico no repositório local. Por que essa resposta tem muitos votos positivos?
Em seguida, crie meu novo repositório em branco, com minha cópia local como origem
cd <path to create repo>
mkdir reduced-repo
cd reduced-repo
git init
git remote add local_copy <path to create repo>/ui
git fetch local_copy origin_point
Nesse ponto, eu recebi essa resposta. Notei isso porque se você usar um SHA-1 no lugar do ramo acima, nada acontece, então a resposta significa que funcionou
/ var / www / html / ui-hacking $ git fetch local_copy origin_point
remote: Contando objetos: 45493, concluído.
remote: Compactando objetos: 100% (15928/15928), concluído.
remoto: Total 45493 (delta 27508), reutilizado 45387 (delta 27463)
Objetos de recebimento: 100% (45493/45493), 53,64 MiB | 50,59 MiB / s, concluído.
Resolução de deltas: 100% (27508/27508), concluído.
De / var / www / html / ui
* ponto de origem da ramificação -> FETCH_HEAD
* [novo ramo] ponto de origem -> ponto de origem / origem
Agora, no meu caso, eu precisava colocar isso de volta no gitlab, como um novo repositório.
O que significava que eu poderia reconstruir meu repositório a partir do origin_point usando o git --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -kcherry pick remotamente e depois usar o git push originupload de todo o lote de volta para sua nova casa.
Você pode explicar o que você quer dizer com "FETCH_HEAD fica confuso"? E como você git fetch local_copy origin_pointdifere do JamesGs git fetch origin refs/tags/tmptag?
precisa saber é o seguinte
O git fetch local_copy origin_pointdeixa em um estado com um reduced-repodiretório vazio , contendo apenas um .git. Há outra coisa que faltava para estas instruções ...
not2qubit
2
Minha versão foi uma combinação de respostas aceitas e mais votadas. Mas é um pouco diferente, porque todo mundo usa SHA1, mas ninguém diz como obtê-lo
por que buscar depois de clonar. Depois de clonar, você tem todo o histórico no repositório local. Por que essa resposta tem dois votos positivos?
madhairsilence
0
# clone special tag/branch without history
git clone --branch=<tag/branch>--depth=1<repository># clone special revision with minimal histories
git clone --branch <branch><repository>--shallow-since=yyyy-MM-ddTHH:mm:ss # get the commit time
cd <dir>
git reset --hard <revision>
você não pode obter uma revisão sem históricos se não estiver definido uploadpack.allowReachableSHA1InWant=trueno lado do servidor, enquanto pode criar uma tag para ela e clonar a tag especial.
Não faço ideia por que você está recebendo votos negativos aqui; isto era exatamente o que eu esperava ver no meu caso de uso: Obter uma versão específica do kernel Linux de uma versão que eles não tiveram o bom senso de marcar como lançamento (parece ser um problema para o pessoal da RPi), sem baixando toda a história de vários gigabytes do Linux. Aliás, deu certo.
Fordi
11
--depth=1não é mencionado na resposta, então por que você diria que essa resposta funcionou se você adicionou mais itens que não foram mencionados aqui? Estou feliz que tenha funcionado para você, mas essa resposta é enganosa e não responde à pergunta, mesmo em parte. Daí os votos negativos.
Emil Styrke
5
@Fordi: Não. Ao usar esta resposta, você obtém exatamente a mesma árvore que obteria de uma baunilha git clone <url> <local_dir_name>, tente você mesmo. A única diferença é que o controle remoto (mostrado usando git remote) será chamado de sequência sha1 enigmática em vez do nome "origem" que é habitual. Em outras palavras, o <sha1-of-the-commit>mencionado nesta resposta não tem qualquer influência sobre quais revisões são buscadas no servidor ou qual filial será retirada.
Emil Styrke
6
@Fordi: Acabei de fazer git clone -o 896066ee1cf4d653057dac4e952f49c96ad16fa7 https://github.com/torvalds/linux.git linux --depth=1. Isso me dá uma revisão 8a28d674e não896066ee como você e esta resposta afirma.
Emil Styrke
4
enfatizando que "origem" não tem nada a ver com "revisão" e esta resposta está completamente errada.
git clone -b 10.1 https://github.com/MariaDB/server.git --depth=1 mariadb-server-src
Respostas:
ATUALIZAÇÃO 2 Desde o Git 2.5.0, o recurso descrito abaixo pode ser ativado no lado do servidor com variável de configuração
uploadpack.allowReachableSHA1InWant
, aqui a solicitação do recurso GitHub e o GitHub confirmam a ativação desse recurso . Observe que alguns servidores Git ativam essa opção por padrão, por exemplo, o Bitbucket Server a ativou desde a versão 5.5+ . Veja esta resposta no Stackexchange para um exemplo de como ativar a opção de configuração.ATUALIZAÇÃO 1 Para versões Git,
1.7 < v < 2.5
use git clone e git reset, conforme descrito na resposta de Vaibhav BajpaiSe você não deseja buscar o repositório completo, provavelmente não deve usá-lo
clone
. Você sempre pode usar a busca para escolher a ramificação que deseja buscar. Eu não sou um especialista em hg, então não sei os detalhes,-r
mas no git você pode fazer algo assim.fonte
git fetch origin <sha1>
funciona; parece que você precisa passar uma referência nomeada, como uma marca ou nome de filial. Veja kerneltrap.org/mailarchive/git/2009/1/13/4707444git fetch origin <SHA1>
para alternar para qualquer revisão que desejava, depois de buscar o mestre no controle remoto e fazer issoreset --hard
para instanciar a ramificação localmente. Não pude buscar diretamente as revisões individuais. Com o git 1.7,git fetch origin <SHA1>
não funcionou, conforme relatado pelo @artur; você precisa usargit checkout <SHA1>
seguido de areset --hard
.Para voltar novamente ao commit mais recente
fonte
--depth
que é muito importante para grandes repositórios. Esta solução requer puxar todos os objetos e redefinir para uma revisão anterior. Isso consome muito tempo e desperdiça largura de banda da rede.A clonagem de um repositório git, apropriadamente, clona o repositório inteiro: não há como selecionar apenas uma revisão para clonar. No entanto, depois de executar
git clone
, você pode fazer o check-out de uma revisão específica fazendo issocheckout <rev>
.fonte
git clone
agarra o repositório inteiro. Depois de obtê-lo, você poderá fazer o checkout de uma revisão específica.git clone --single-branch ...
Para clonar apenas um único commit específico em uma ramificação ou marca específica, use:
Infelizmente,
NAME
só pode ser o nome do ramo ou o nome da marca (não confirma o SHA).Omita a
--depth
bandeira para fazer o download de todo o histórico e faça check-out dessa ramificação ou tag:Isso funciona com a versão recente do git (eu fiz isso com a versão
2.18.0
).fonte
Se você quer buscar tudo, desde o início até um ponto específico, a resposta de Charles Bailey é perfeita. Se você deseja fazer o inverso e recuperar um subconjunto do histórico desde a data atual, você pode usar
git clone --depth [N]
onde N é o número de rotações do histórico que deseja. Contudo:fonte
Apenas para resumir as coisas (git v. 1.7.2.1):
git clone
onde você quer o repo (deixa tudo atualizado - eu sei, não o que é desejado, estamos chegando lá)git checkout <sha1 rev>
da rev que você quergit reset --hard
git checkout -b master
fonte
master
e muda para ele.git reset --hard
? Os documentos para isso dizem "Redefine o índice e a árvore de trabalho. Quaisquer alterações nos arquivos rastreados na árvore de trabalho desde que <commit> [cujo padrão é HEAD, que agora é<sha1 rev>
] são descartadas". Mas neste momento não fizemos nenhuma alteração desde a clonagem, então qual é o objetivo? Trunca a ramificação atual em<sha1 rev>
?TL; DR - Basta criar uma tag no repositório de origem contra a confirmação que você deseja clonar e usar a tag no comando buscar. Você pode excluir a tag do repositório original posteriormente para limpar.
Bem, em 2014 e parece que a resposta aceita por Charles Bailey a partir de 2010 está bem e verdadeiramente desatualizada agora e a maioria (todas?) Das outras respostas envolve clonagem, o que muitas pessoas esperam evitar.
A solução a seguir alcança o que o OP e muitos outros estão procurando, que é uma maneira de criar uma cópia de um repositório, incluindo histórico, mas apenas até um determinado commit.
Aqui estão os comandos que usei com o git versão 2.1.2 para clonar um repositório local (por exemplo, um repositório em outro diretório) até um certo ponto:
Esperamos que esta solução continue funcionando por mais alguns anos! :-)
fonte
Você pode usar simplesmente
git checkout <commit hash>
nesta sequência
bash git clone [URLTORepository] git checkout [commithash]
o hash de confirmação tem esta aparência "45ef55ac20ce2389c9180658fdba35f4a663d204"
fonte
O uso de 2 das respostas acima ( como clonar repositório git com revisão / conjunto de alterações específico? E como clonar repositório git com revisão / conjunto de alterações específico? ) Me ajudou a criar uma definição. Se você deseja clonar até um ponto, esse ponto deve ser uma marca / ramificação, não apenas um SHA ou o FETCH_HEAD fica confuso. Após o conjunto de busca git, se você usar um nome de filial ou marca, obterá uma resposta; se você simplesmente usar um SHA-1, não obterá resposta.
Aqui está o que eu fiz: - criar um clone completo do repositório completo, a partir da origem real
Em seguida, crie uma filial local, no ponto que for interessante
Em seguida, crie meu novo repositório em branco, com minha cópia local como origem
Nesse ponto, eu recebi essa resposta. Notei isso porque se você usar um SHA-1 no lugar do ramo acima, nada acontece, então a resposta significa que funcionou
Agora, no meu caso, eu precisava colocar isso de volta no gitlab, como um novo repositório.
O que significava que eu poderia reconstruir meu repositório a partir do origin_point usando o
git --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -k
cherry pick remotamente e depois usar ogit push origin
upload de todo o lote de volta para sua nova casa.Espero que ajude alguém
fonte
git fetch local_copy origin_point
difere do JamesGsgit fetch origin refs/tags/tmptag
?git fetch local_copy origin_point
deixa em um estado com umreduced-repo
diretório vazio , contendo apenas um.git
. Há outra coisa que faltava para estas instruções ...Minha versão foi uma combinação de respostas aceitas e mais votadas. Mas é um pouco diferente, porque todo mundo usa SHA1, mas ninguém diz como obtê-lo
agora você pode ver todas as filiais e confirmações
Finalmente, você conhece o SHA1 da confirmação desejada
fonte
Eu uso esse trecho com o GNU make para fechar qualquer tag de revisão, ramificação ou hash
foi testado na versão 2.17.1 do git
fonte
git clone https://github.com/ORGANIZATION/repository.git
(clone o repositório)cd repository (navigate to the repository)
git fetch origin 2600f4f928773d79164964137d514b85400b09b2
git checkout FETCH_HEAD
fonte
você não pode obter uma revisão sem históricos se não estiver definido
uploadpack.allowReachableSHA1InWant=true
no lado do servidor, enquanto pode criar uma tag para ela e clonar a tag especial.fonte
É simples. Você só precisa definir o upstream da ramificação atual
Isso é tudo
fonte
git
usa a palavraorigin
em vez de popularmente conhecidorevision
A seguir, um trecho do manual
$ git help clone
fonte
--depth=1
não é mencionado na resposta, então por que você diria que essa resposta funcionou se você adicionou mais itens que não foram mencionados aqui? Estou feliz que tenha funcionado para você, mas essa resposta é enganosa e não responde à pergunta, mesmo em parte. Daí os votos negativos.git clone <url> <local_dir_name>
, tente você mesmo. A única diferença é que o controle remoto (mostrado usandogit remote
) será chamado de sequência sha1 enigmática em vez do nome "origem" que é habitual. Em outras palavras, o<sha1-of-the-commit>
mencionado nesta resposta não tem qualquer influência sobre quais revisões são buscadas no servidor ou qual filial será retirada.git clone -o 896066ee1cf4d653057dac4e952f49c96ad16fa7 https://github.com/torvalds/linux.git linux --depth=1
. Isso me dá uma revisão8a28d674
e não896066ee
como você e esta resposta afirma.