繁体   English   中英

Git:将存储库更新为某个版本

[英]Git: update a repository to certain revision

假设我有一个版本号为A的存储库。我想将其更新到版本B,而最新版本是C.(版本A早于B,B早于C)。 我是git的新手,所以我做了一些研究,发现了这个 ,这激发了我一个解决方案:

git pull # update from A to the latest revision C
git reset --hard B

这确实有效。 但是因为我不能直接从A中git reset --hard B ,所以先前更新到最新仍然太重,我不知道可能有一些单行命令来满足我的需要。 有什么提示吗?

没有“将存储库更新为某个版本”。 您的存储库具有所有版本,这就是git fetch / git pull所做的。

如果您想在本地工作树中放置一个特定的repo版本,有几种方法可以做到这一点。 最接近您的问题是:

更新本地存储库:

git fetch origin

创建一个新的分支(从你当前所在的任何分支,我们稍后将重置,所以它无关紧要):

git branch yourbranchname
git checkout yourbranchname

上述两个操作可以缩写为一个(当前HEAD被假定为分支的源):

git checkout -b yourbranchname

然后将该分支的指针放在您需要的提交中( B ):

git reset --hard sha1-of-B

git reset --hard将始终有效,它不依赖于你的分支的历史,它工作的唯一条件是提交B在你的本地对象库中(即B必须存在并且必须从远程仓库获取这不是你的工作)。

正如@Hasturkun指出的那样,你也可以使用额外的参数直接从任意哈希分支:

git checkout -b yourbranchname SHA-1

你需要使用git checkout 做就是了:

git checkout B

你会有那个修改。

你的方法是完全错误的。 您正在修改您不想修改的内容:您当前的分支(可能是master分支)。

一个简单的线性git存储库就是这样一个提交链

*---A---*---*---B---*---*---C
    ^                       ^
    |                       |
  master              origin/master
    ^
    |
   HEAD

这是您调用git fetch之后的存储库状态。 请注意,包含所有中间步骤的整个历史记录就在您的本地硬盘驱动器上。 只是你只有一个状态在提交A签出( HEAD指向master指向A ),所以你看到的文件属于那个状态。

现在,如果您只想查看作为B提交的状态,您可以使用git checkout B检查该提交。 这会将您看到的文件更新为B状态,并在该提交时指向HEAD

*---A---*---*---B---*---*---C
    ^           ^           ^
    |           |           |
  master       HEAD   origin/master

HEAD总是引用git认为你所在的提交/分支,并在你调用git status时将它与你的工作目录进行比较。

如果您只想查看该提交,那么简单的git checkout B就足够了。 如果您确实想要进行已提交并希望保留的更改,则应引入新分支来记录这些更改。 这是通过git checkout B之后的简单git checkout -b newBranch实现的。 这将给你国家

*---A---*---*---B---*---*---C
    ^           ^           ^
    |           |           |
  master    newBranch origin/master
                ^
                |
               HEAD

这只是提供一个名称来提交B而不是其哈希值。 经过多次提交后,您的状态将如下所示:

*---A---*---*---B---*---*---C
    ^           |           ^
    |           |           |
  master         \    origin/master
                   \
                    *---*---D
                            ^
                            |
                        newBranch
                            ^
                            |
                           HEAD

关键是,在使用git checkout ...一些其他分支/提交后,您可以通过调用git checkout newBranch轻松返回提交D ,并且永久引用会从垃圾收集提交D停止git


现在,为什么使用git reset --hard坏? 首先,它会破坏您尚未提交的所有本地更改,恕不另行通知。 其次,如果你不小心,它可能会让你失去历史。

例如,考虑一下您在上次推送到上游存储库后进行了一些更改,并想查看一些历史提交B (与你的问题中的情况有些相反。)历史看起来像这样:

  *---A---*---*---B---*---*---C
      ^                       ^
      |                       |
origin/master               master
                              ^
                              |
                             HEAD

使用git reset --hard B ,您将获得以下状态:

  *---A---*---*---B-(-*---*---C )
      ^           ^
      |           |
origin/master   master
                  ^
                  |
                 HEAD

括号中的提交不再由任何分支直接或间接引用,并且可能随时被垃圾收集。 git可能不是非常积极的垃圾收集, 但如果它在你处于这种状态时进行垃圾收集,你没有办法让你恢复提交C ,它将永远丢失 你不希望这种情况发生,所以养成使用git reset --hard的习惯并不是一个好主意。

如果您使用git checkout ,分支master仍然会指向C ,您仍然可以使用简单的git checkout master返回它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM