我想使用公共(public)仓库,让我的master分支回到过去的某个提交。我已经检查了选项,对我来说,最好的事情是对所需的提交进行简单的 checkout ,然后提交到master分支。但是,当我执行 check out 操作时,它不会删除在指定的提交哈希之后已添加到master中的某些文件。
因此,例如,如果我想重新提交aaa1
:
$ cd working-copy-top-dir
$ git checkout master
$ git checkout -- .
$ git clean -fd
$ git checkout aaa1 .
$ git clean -fd
但是此时,在
aaa1
之后添加的某些文件仍在工作副本中。 checkout
命令是什么,用于将工作副本数据恢复为aaa1
时的状态?$ git --version
git version 2.7.2.windows.1
最佳答案
TL; DR:首先删除所有内容
当您使用git checkout aaa1 .
时,您告诉Git将aaa1
转换为提交,找到该提交(更确切地说是其树),然后将该提交中的每个文件复制到索引/暂存区和工作树中。
让我们说,仅出于论证的目的,您从包含两个文件master
和README
的hello
开始:
$ git checkout master
[output snipped]
$ ls
README hello
$ cat README
Yay, you read me!
$ cat hello
world
$
再说一遍,commit
aaa1
存在并且其中有两个文件README
和addendum
。它的README
表示Thank you for reading.
让我们进行结帐:$ git checkout aaa1 -- .
[output snipped]
$ ls
README addendum hello
(我添加了
--
:这里实际上并不是必需的,但这是一个好习惯。)README
的内容是更新后的README
。文件addendum
也已被提取。文件hello
不会被删除,并且与master
中的版本保持不变。升级了README
和hello
的阶段:$ git status --short
M README
A addendum
但没有删除
hello
:$ git ls-files --stage
100644 ac6f2cf1acbe1b6f11c7be2288fbae72b982823c 0 README
100644 7ddf1d71e0209a8512fe4862b4689d6ff542bf99 0 addendum
100644 cc628ccd10742baea8241c5924df992b5c019f71 0 hello
即使使用
git clean
,也使用-x
不会产生任何效果。没有未暂存的文件(hello
已暂存,只是未修改)。您特别想获得工作树来匹配commit
aaa1
,一个字节一个字节地匹配。为此,您必须找到现在在索引中但不在aaa1
中的文件,然后将其删除。但是,有一种更简单的方法:删除所有内容。然后,使用
git checkout aaa1 -- .
从aaa1
中提取所有内容。这将从aaa1
填充索引和工作树:所有需要还原到删除之前的文件的方式都将还原(还原为aaa1
的方式,与HEAD
的方式相同) 。任何需要更改以匹配aaa1
中文件的方式的文件都将还原(恢复为aaa1
中它们的方式,这是不同的)。$ git rm -rf .
rm 'README'
rm 'addendum'
rm 'hello'
$ git checkout aaa1 -- .
$ git ls-files --stage
100644 ac6f2cf1acbe1b6f11c7be2288fbae72b982823c 0 README
100644 7ddf1d71e0209a8512fe4862b4689d6ff542bf99 0 addendum
$ git status --short
M README
A addendum
D hello
现在,您可以提交,并且您将对
master
进行新的提交,无论之前有什么提交,其提交都与aaa1
完全相同的树。(这是否是一个好主意,完全是另一回事,但这将使您获得所需的状态。)
关于git checkout不会删除应该删除的文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37201104/