克隆远程仓库的特定版本

238

大约一个月前,我克隆了一个远程的git仓库。这个远程仓库经历了很多变化并且现在变得不稳定。现在我需要另一个仓库的副本,其版本与我一个月前克隆的那个完全相同。

我该怎么做?


可能是 https://dev59.com/dnA75IYBdhLWcg3wFEsI 的重复问题。 - Nicolas Raoul
可能是如何克隆具有特定修订/更改集的git存储库?的重复问题。 - Ciro Santilli OurBigBook.com
9个回答

280
你可以将你的代码库“重置”到任何一个你想要的提交状态(例如一个月前的状态)。 使用git-reset命令进行操作:git-reset
git clone [remote_address_here] my_repo
cd my_repo
git reset --hard [ENTER HERE THE COMMIT HASH YOU WANT]

34
你没有提到,但这只会重置默认克隆的master分支。如果除了master之外的其他分支是你的主开发分支,则在运行git reset命令之前必须先检出该分支。 - Steve Folly
19
为什么不对想要的提交进行简单的检查? - nemoo
10
当您在Git中切换到特定的提交时,您将处于“分离的HEAD”状态。 - Rui Carneiro
8
最好使用git checkout -b new_branch hash命令,它可以基于给定的哈希值创建一个全新的分支,而不会影响任何其他分支。如果移动现有分支的HEAD,可能会在将来推送到远程服务器时出现问题。 - Loïc Faure-Lacroix
1
如果提交已经被推送到远程分支,你可以使用git pull origin [branch],否则,据我所知,它就丢失了。 - Rui Carneiro
显示剩余2条评论

134

您可以简单地使用

git checkout  commithash

在这个序列中

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

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


16
我最喜欢这个答案。我认为应该避免使用 git reset --hard,而改用 git checkout commit-hashgit reset --hard 会删除部分 Git 历史记录,有时并不是理想的选择。 - Jordan Stewart

40
使用 git log 查找要回滚的版本,并记录提交哈希值。之后,您有两个选项:
  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
但是请注意,您现在处于分离的 HEAD 状态,这对只读操作来说是可以的。但是,当您打算从此版本开始进行更改时,您需要创建一个新的分支。有关更多信息,请参见 http://sitaramc.github.com/concepts/detached-head.html。 - Rudi
@Rudi:谢谢。这只是一个示例,用来展示用法。已更新以进行说明。 - jweyrich
要回到“工作状态”,您只需执行 git checkout develop 命令,其中 develop 是您的分支名称。 - Steve Tauber
1
@SteveTauber 嗯,假设你有一个不同的分支是工作的,那么改变到那个分支就足够了。 - jweyrich

34
如果你需要获取的版本是分支或标签,则:
git clone -b branch_or_tag_name repo_address_or_path

4

uploadpack.allowReachableSHA1InWant

自从 Git 2.5.0 版本以来,这个配置变量就可以在服务器上启用,在这里可以看到 GitHub功能请求启用此功能的GitHub提交Bitbucket Server 自版本5.5+开始启用了它。 使用方法:
# 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"

2
你可以这样解决它:
git reset --hard sha

其中 sha 指的是哈希值,例如:85a108ec5d8443626c690a84bc7901195d19c446

你可以使用以下命令获取所需的哈希值:

git log

2
与集中式版本控制系统不同,Git 克隆整个仓库,因此您不仅可以获取当前远程文件,还可以获取整个历史记录。您的本地仓库将包含所有这些内容。
可能有标签来标记特定版本。如果没有,您可以在本地创建它们。一个好的方法是使用 git log 或者更加直观的工具如 gitk(也许可以使用 gitk --all 来查看所有分支和标签)。如果您能够找到当时使用的提交哈希值,您可以使用 git tag 进行标记,然后在新的工作副本中检出这些标记(例如 git checkout -b new_branch_name tag_name 或者直接使用哈希值而非标记名称)。

0

你要求取的源代码仍然在git仓库中可用,但是你需要所感兴趣的提交的SHA1。我假设你可以从当前拷贝中获取SHA1?

如果你能获取到SHA1,那么你可以创建一个分支/重置到该提交以获得相同的仓库。

命令如Rui的回答所述


0

可能 git reset 可以解决你的问题。

git reset --hard -#commit hash-

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接