Git克隆特定版本的远程存储库


180

我大约一个月前克隆了一个远程git存储库。远程存储库经历了许多更改,现在变得不稳定。现在,我需要存储库的另一个副本,该副本的版本与我一个月前克隆的版本相同。

我该怎么做呢?



Answers:


241

您可以将存储库“重置”为所需的任何提交(例如1个月前)。

为此使用git-reset

git clone [remote_address_here] my_repo
cd my_repo
git reset --hard [ENTER HERE THE COMMIT HASH YOU WANT]

27
您没有提到它,但这只会重置master分支,该分支默认在克隆上签出。如果master您的主要开发分支以外的其他分支必须在此之前首先签出git reset
Steve Folly,2010年

16
为什么不对所需的提交做简单的结帐?
nemoo

10
因为您在签出特定提交后将处于“分离式HEAD”状态。
鲁·卡内罗

6
@RuiCarneiro最好使用git checkout -b new_branch hash您基于哈希创建一个新分支而不接触任何其他分支。当现有分支的头将内容推送到远程服务器时,移动它的头部可能会导致问题。
卢瓦克福雷-拉克鲁瓦

1
@YuriGhensev如果提交已被推送到远程分支,则可以执行git pull origin [branch]afaik,否则它将丢失。
Rui Carneiro

93

您可以简单地使用

git checkout  commithash

按此顺序

git clone `URLTORepository`
cd `into your cloned folder`
git checkout commithash

提交哈希看起来像这样“ 45ef55ac20ce2389c9180658fdba35f4a663d204”


8
我最喜欢这个答案。我认为git reset --hard应避免使用,而应改为git checkout commit-hash。A git reset --hard会删除部分git历史记录,这有时是不希望的。
乔丹·斯图尔特

8
git init不必要
Lautaro Paskevicius

37

使用git log找到你想要回滚到修改,并注意到提交哈希值。之后,您有2个选项:

  1. 如果您打算在该修订版后提交任何内容,建议您签出到新分支:git checkout -b <new_branch_name> <hash>

  2. 如果您不打算在该修订版之后提交任何内容,则可以简单地在不使用分支的情况下签出:git checkout <hash>-注意:这会将您的存储库置于“分离的HEAD”状态,这意味着该存储库当前未连接到任何分支-那么您还要做一些额外的工作将新的提交合并到一个实际的分支中

例:

$ git log
commit 89915b4cc0810a9c9e67b3706a2850c58120cf75
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:15:01 2010 -0300

    Added a custom extension.

commit 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Author: Jardel Weyrich <suppressed>
Date:   Wed Aug 18 20:13:48 2010 -0300

    Missing constness.

$ git checkout 4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7
Note: moving to '4553c1466c437bdd0b4e7bb35ed238cb5b39d7e7'
which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 4553c14... Missing constness.

这样,您就不会丢失任何信息,因此,当它变得稳定时,您可以移至新版本。


2
但也要注意,您处于独立状态,这对于只读操作是可以的。但是,当您打算从此修订版开始进行更改时,则需要创建一个新分支。有关更多信息,请参见sitaramc.github.com/concepts/detached-head.html
鲁迪

@Rudi:谢谢。这只是显示用法的一个示例。更新以提及它。
jweyrich 2010年

要回到“工作状态”,您可以git checkout develop在develop分支的名称所在的位置。
史蒂夫·陶伯

1
@SteveTauber好,假设您一个正在运行的其他分支,更改为该分支确实足够。
jweyrich 2014年

18

如果您需要获取的版本是分支或标记,则:

git clone -b branch_or_tag_name repo_address_or_path

2

与集中式版本控制系统不同,Git会克隆整个存储库,因此您不仅可以获取当前的远程文件,还可以获取整个历史记录。您的本地存储库将包括所有这一切。

当时可能有标记来标记特定版本。如果没有,您可以自己在本地创建它们。做到这一点的一个好方法是使用git log诸如此类的工具,或者更直观地使用gitk(例如gitk --all查看所有分支和标签)。如果可以发现当时使用的提交哈希,则可以使用标记它们git tag <hash>,然后将其检出到新的工作副本中(例如,git checkout -b new_branch_name tag_name或直接使用哈希而不是标记名称)。



1

uploadpack.allowReachableSHA1InWant

由于Git 2.5.0可以在服务器上启用此配置变量,因此这里GitHub功能请求GitHub提交启用了此功能

从5.5+版本开始,Bitbucket Server启用了它

用法:

# Make remote with 4 commits, and local with just one.
mkdir server
cd server
git init
touch 1
git add 1
git commit -m 1
git clone ./ ../local
for i in {2..4}; do
    touch "$i"
    git add "$i"
    git commit -m "$i"
done

# Before last commit.
SHA3="$(git log --format='%H' --skip=1 -n1)"
# Last commit.
SHA4="$(git log --format='%H' -n1)"

# Failing control without feature.
cd ../local
# Does not give an error, but does not fetch either.
git fetch origin "$SHA3"
# Error.
git checkout "$SHA3"

# Enable the feature.
cd ../server
git config uploadpack.allowReachableSHA1InWant true

# Now it works.
cd ../local
git fetch origin "$SHA3"
git checkout "$SHA3"
# Error.
git checkout "$SHA4"

0

所需的源树在git存储库中仍然可用,但是,您将需要感兴趣的提交的SHA1。我假设您可以从当前的克隆中获取SHA1?

如果您可以获得该SHA1,则可以在其中创建分支/重置以具有相同的存储库。

根据Rui的回答命令


0

可能git reset解决您的问题。

git reset --hard -#commit hash-
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.