我不清楚git revert
的工作原理。例如,我想要回滚到距离头部六个提交的提交,撤销中间提交中的所有更改。
假设它的SHA哈希值为56e05fced214c44a37759efa2dfc25a65d8ae98d
。那么为什么我不能只是执行类似以下的操作:
git revert 56e05fced214c44a37759efa2dfc25a65d8ae98d
我不清楚git revert
的工作原理。例如,我想要回滚到距离头部六个提交的提交,撤销中间提交中的所有更改。
假设它的SHA哈希值为56e05fced214c44a37759efa2dfc25a65d8ae98d
。那么为什么我不能只是执行类似以下的操作:
git revert 56e05fced214c44a37759efa2dfc25a65d8ae98d
如果想在当前HEAD的基础上提交一个不同提交记录的精确状态,同时撤销所有中间提交记录,那么可以使用 reset
命令创建正确的索引状态来进行提交。
# Reset the index and working tree to the desired tree
# Ensure you have no uncommitted changes that you want to keep
git reset --hard 56e05fced
# Move the branch pointer back to the previous HEAD
git reset --soft "HEAD@{1}"
git commit -m "Revert to 56e05fced"
git reset --hard 56e05fced
,之后跳过最后一个 git reset --hard
命令。那么,这样做不就等同于(而且还可以少敲一条命令)吗? - Mark Longairgit reset --hard
之后,你可以执行 git clean -f -d
命令来清理任何残留的未跟踪文件。此外,非常感谢,这帮助我解决了危机! - nzifnabgit reset --soft HEAD@{1}
命令?也就是说,始终使用值为 1 吗? - deprecatedgit reset --soft HEAD@{1}
将指针移回调用git reset 56e05fced
前的"HEAD"。如果使用更高的数字(例如 git reset --soft HEAD@{2}
),则会将新提交附加到以前的提交上。也就是说,增加数字实际上会丢弃N-1
个提交,其中N
是您用数字替换1
的数字。请运行git reflog
查看git reset 56e05fced
添加的引用日志条目。 - 0b10011HEAD@{1}
"引用为"'HEAD{@1}'
",那么它对我(可能是所有zsh用户)将无法起作用。 - jilengit-revert 的作用是创建一个撤销给定提交所做更改的提交,从而创建一个与给定提交相反(或互补)的提交。因此,
git revert <SHA-1>
应该可以并且实际上是有效的。
如果你想要回到一个指定的提交版本,并且由于这部分历史记录尚未发布,你需要使用git-reset,而不是git-revert:
git reset --hard <SHA-1>
请注意,使用--hard
选项将使您失去工作目录中的任何未提交更改。
顺便提一下,也许不是很明显,但无论文档在哪里说到<commit>
或<commit-ish>
(或<object>
),您都可以放置一个SHA-1标识符(完整或缩短)。
git push -f
强制推送新的重置分支,但是请注意:这可能会意外删除其他用户的提交,或者如果没有删除新的提交,它将强制其他用户重新同步他们的工作与重置分支,所以请先确保你的协作者已经同意这样做。 - user456814git revert <SHA-1>
是最干净和最简单的解决方案。它的好处是能够清晰地展示历史记录,同时撤销的提交也会像正常提交一样显示出来。也不需要强制推送。 - undefined回滚到特定的提交(commit)最好的方法是:
git reset --hard <commit-id>
那么:
git push <reponame> -f
push -f
可能会破坏历史记录。不过,有时这正是你想要的 :) - Jared Beck此命令会还原指定的提交,也就是添加与其相反的提交。如果你想检出早期版本,请执行以下操作:
git checkout 56e05fced214c44a37759efa2dfc25a65d8ae98d
git branch
,你会清楚地看到它。你可以执行例如git checkout -b mybranch 56e05
这样的命令来在分支中获取它。 - Michael Krelin - hacker更新:
如果中间没有合并提交,这个答案提供了一种更简单的方法:https://dev59.com/im855IYBdhLWcg3w1oLa#21718540
但是如果有一个或多个合并提交,那个答案就不适用了,所以请使用这个(适用于所有情况)。
原始答案:
# Create a backup of master branch
git branch backup_master
# Point master to '56e05fce' and
# make working directory the same with '56e05fce'
git reset --hard 56e05fce
# Point master back to 'backup_master' and
# leave working directory the same with '56e05fce'.
git reset --soft backup_master
# Now working directory is the same '56e05fce' and
# master points to the original revision. Then we create a commit.
git commit -a -m "Revert to 56e05fce"
# Delete unused branch
git branch -d backup_master
git reset --hard
和git reset --soft
在这里是神奇的。第一个命令改变了工作目录,但同时也改变了head(当前分支)。我们通过第二个命令来修复head。git revert 56e05fce..HEAD
更好,因为它仅撤销了一个提交。 - knoctegit revert 56e05f..HEAD
它会还原56e05f
和HEAD
之间的所有提交(不包括范围开始点56e05f
)。
--no-edit
选项以避免必须编写单独的提交消息,或者你可以使用 --no-commit
一次性提交所有还原。 - user456814~/.gitconfig
文件的别名部分中:rollback = "!git revert --no-commit $1..HEAD #"
- 现在我只需要直觉地运行 $ git rollback a1s2d3
即可。 - DannyBgit checkout 56e05fced -- .
git add .
git commit -m 'Revert to 56e05fced'
为了证明它起作用:
git diff 56e05fced
56e05fced
以来新增的文件,就像 git reset --hard
或 git revert
命令一样。如果你真的想恢复到 56e05fced
的状态,而不是使用 git checkout
,那么你应该使用那些命令。 - user456814应该很简单:
git reset --hard 56e05f
这将使您回到特定的时间点。
git checkout 56e05f
echo ref: refs/heads/master > .git/HEAD
git commit
git reset --hard 56e05f
做的一样,只是这种方法更不安全并且更加hacky。你最好使用Charle的解决方案 或者 Jakub的解决方案。 - user456814