撤销和取消暂存

4
您可以使用git revert --no-commit来撤销特定更改,这样做会更新工作副本和索引,但不会提交还原。然而,是否有办法将其进一步,仅更新工作副本而不更新索引?(即更改将未被暂存)。我知道您可以使用git checkout获取特定提交的工作副本,但这也会创建一个分离的头部。我只想更新带有还原更改的工作副本。

你是指 git revert --no-commit 吗? - torek
@JB.: git checkout <commit> -- <path(s)> 会提取旧文件,但“写入”索引,暂存更改。然后您必须使用 git reset 取消暂存的更改。 - torek
@torek 哦,对了。那还剩什么?git cat-file和一些手写的管道吗?我不知道有任何直接从存储库到工作树的命令。 - JB.
那么,或者创建一个额外的克隆并检查旧版本。 - torek
2个回答

3

您可以使用临时索引来保留原始索引不受影响:

true_index=$(git rev-parse --git-dir)/index
export GIT_INDEX_FILE=.mytmpindex    
cp "$true_index" .mytmpindex
git revert -n  <some-commit-id>
rm .mytmpindex
unset GIT_INDEX_FILE

如果您没有要保留的暂存更改,可以直接执行以下操作:

git revert -n <some-commit-id>
git reset

最初的 git reset 的目的是什么? - Explosion Pills
@ExplosionPills:这是为了构建新的索引文件,但可能更快、更符合您的要求,只需复制当前实际的索引文件即可,因此我已经进行了编辑。 - CB Bailey
这很酷,但比起只需执行 git revert -n 后跟着 git reset(使用 --soft 或许更好),它更加复杂/繁琐。那么这种方法是否有什么优势呢? - Explosion Pills
但是 git reset --soft 不会恢复您的原始索引,也不会像 git reset 一样将其重置为当前的 HEAD。 (正如您所指出的那样,git revert -n 会影响您当前的索引。) - CB Bailey
我明白了,通常这应该使用一个干净的工作副本来完成。 - Explosion Pills
@ExplosionPills:你所说的“干净的工作副本”是指既没有暂存的更改,也没有未暂存的更改吗? - CB Bailey

2
如果你想达到的树状态已经存在于你的历史记录中(例如,你要还原最新的提交并且一定要这样做),只需连续使用两个重置(reset)命令:
wished_index=$(git rev-parse HEAD)
git reset --hard $wished_tree
git reset $wished_index

如果没有,你仍然可以使用“revert”,只是之后需要修复索引:
git revert $commit
git reset HEAD^

两种方法都需要一个干净的工作目录(否则使用git stash命令),并且会留下一个脏的工作目录。


这将丢失原始索引中未提交的更改。 - CB Bailey
是的。但是 OP 知道如何使用 git stash - JB.
但是你没有使用git stash吗?另外,你漏掉了创建“wished_tree”的部分。不太可能已经有一个树表示撤销对当前索引的给定提交。 - CB Bailey

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