假设我有一个版本号为A的存储库。我想将其更新到版本B,而最新版本是C.(版本A早于B,B早于C)。我是git的新手,所以我做了一些研究,找到了this,它激发了我一个解决方案:
git pull # update from A to the latest revision C
git reset --hard B
这确实有效。但由于我不能直接从git reset --hard B
直接更新到最新的先前更新仍然太重,我想知道可能有一些单行命令来满足我的需要。有什么提示吗?
答案 0 :(得分:20)
没有“将存储库更新为某个版本”。您的存储库包含所有版本,这是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
答案 1 :(得分:4)
您需要使用git checkout
。只是做:
git checkout B
你将进行修改。
答案 2 :(得分:2)
你的方法完全错了。您正在修改您不想修改的内容:您当前的分支(可能是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 newBranch
之后的简单git checkout B
来实现的。这会给你状态
*---A---*---*---B---*---*---C
^ ^ ^
| | |
master newBranch origin/master
^
|
HEAD
这只是提供一个名称来提交除其哈希值以外的B
。经过多次提交后,您的状态将如下所示:
*---A---*---*---B---*---*---C
^ | ^
| | |
master \ origin/master
\
*---*---D
^
|
newBranch
^
|
HEAD
关键是,在使用git checkout ...
签出其他分支/提交后,您可以通过调用D
轻松返回提交git checkout newBranch
,永久引用会停止{垃圾收集提交git
中的{1}}。
现在,为什么使用D
不好?首先,它会破坏您尚未提交的所有本地更改,恕不另行通知。其次,如果你不小心,它可能会让你失去历史。
例如,考虑一下您在上次推送到上游存储库后进行了一些更改,并希望查看一些历史提交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
返回到它