使用公共仓库,我想让我的主分支回到过去的某个提交。我已经查看了选项,对我来说最好的事情看起来是对所需提交的简单检查,然后提交到主分支。但是,当我执行检出时,它不会删除在指定的提交哈希之后添加到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
答案 0 :(得分:8)
当您使用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
$
让我们进一步说,提交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
已暂存,它只是已修改)。
您特别希望让工作树与提交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
具有完全相同的树。
(这是否是好主意完全是另一回事,但它会让你达到理想状态。)
答案 1 :(得分:3)
您想将您的回购卷回滚到该状态吗?或者你只是希望你的本地回购看起来像那样?
请参阅https://git-scm.com/docs/git-reset了解git reset。
案例1: 如果你这样做
git reset --hard [commit hash]
它将使您的本地代码和本地历史记录与该提交时一样。但是如果你想把它推给拥有新历史的其他人,它就会失败。
案例2:如果你这样做
git reset --soft [commit hash]
它会使您的本地文件更改为当时的文件,但保留您的历史记录等。
答案 2 :(得分:0)
Git checkout will not remove files added since a previous commit。要做到这一点,我需要git revert
。
但是我发现git checkout thehash .
更容易使用,并且从那个散列开始就不难看出添加了哪些文件:
git diff --name-status HEAD thehash
答案 3 :(得分:0)
git stash 可能是清理工作树的最快方法。 然后 git checkout -b $ newbranch $ commit-sha1-you-want 创建一个你要使用的分支。 完成所有工作后, git stash pop 恢复工作树。
答案 4 :(得分:0)
我发现这个命令将索引和工作副本更新为我想要的提交,在这种情况下由变量 treeish
给出:
# use with care: destroys any uncommitted changes
git read-tree "$treeish" --reset -u
要在不更新索引的情况下更新工作副本,您可以这样做:
index_bak=$(git write-tree)
git read-tree "$treeish" --reset -u
git read-tree "$index_bak" --reset