在我的一个开发分支中,我对我的代码库进行了一些更改。在我能够完成我正在开发的功能之前,我必须将我当前的分支切换到 master 来演示一些功能。但是仅使用“git checkout master”就保留了我在开发分支中所做的更改,从而破坏了 master 中的一些功能。所以我所做的是在我的开发分支上提交更改,并使用提交消息“临时提交”,然后为演示签出 master。
现在我已经完成了演示并回到我的开发分支上工作,我想删除我所做的“临时提交”,同时仍然保留我所做的更改。那可能吗?
git stash
git stash
是一个很好的工具,但“正在进行的工作”一次性提交也是一种相当合法的设备。
git stash
。
stash
值得注意的一点是它完全是本地的,并且很容易因 repo 删除或重新创建或硬件故障或丢失而导致代码丢失。 IMO,它真的应该只用于非常短期的 WIP。在去度假之前喜欢 WIP 提交:P .. 称之为大脑转储提交!
就这么简单:
git reset HEAD^
注意:某些 shell 将 ^
视为特殊字符(例如某些 Windows shell 或 ZSH with globbing enabled),因此在这些情况下您可能必须引用 "HEAD^"
或使用 HEAD~1
。
没有 --hard
或 --soft
的 git reset
移动您的 HEAD
以指向指定的提交,而不更改任何文件。 HEAD^
指的是您当前提交的(第一个)父提交,在您的情况下是临时提交之前的提交。
请注意,另一个选项是照常进行,然后在下一个提交点运行:
git commit --amend [-m … etc]
它将改为编辑最近的提交,具有与上述相同的效果。
请注意,如果您已经将错误的提交推送到其他人可能已将其拉出的地方,这(与几乎所有 git 答案一样)可能会导致问题。尽量避免这种情况
有两种处理方法。哪个更容易取决于您的情况
重置
如果您要删除的提交是最后一次提交,并且您还没有做任何额外的工作,您可以简单地使用 git-reset
git reset HEAD^
将您的分支带回当前 HEAD 之前的提交。但是,它实际上并没有更改工作树中的文件。结果,该提交中的更改显示为已修改-就像“取消提交”命令。事实上,我有一个别名可以做到这一点。
git config --global alias.uncommit 'reset HEAD^'
然后,您以后可以只使用 git uncommit
来备份一个提交。
挤压
压缩提交意味着将两个或多个提交合并为一个。我经常这样做。在您的情况下,您提交了一半完成的功能,然后您将完成它并使用正确的永久提交消息再次提交。
git rebase -i <ref>
我在上面说是因为我想明确表示这可能是任意数量的提交。运行 git log
并找到您要删除的提交,复制其 SHA1 并使用它来代替 <ref>
。 Git 将带您进入交互式变基模式。它将显示您当前状态与您放置 <ref>
的任何内容之间的所有提交。因此,如果 <ref>
是 10 次提交之前,它将显示所有 10 次提交。
在每次提交之前,都会有 pick
字样。找到您要删除的提交并将其从 pick
更改为 fixup
或 squash
。使用 fixup
只需丢弃提交消息并将更改合并到列表中的直接前任中。 squash
关键字做同样的事情,但允许您编辑新组合提交的提交消息。
请注意,当您退出编辑器时,提交将按照它们在列表中显示的顺序重新提交。因此,如果您进行了临时提交,然后在同一分支上进行了其他工作,并在以后的提交中完成了该功能,那么使用 rebase 将允许您重新排序提交并压缩它们。
警告:
变基会修改历史记录 - 不要对您已经与其他开发人员共享的任何提交执行此操作。
藏匿
将来,为避免此问题,请考虑使用 git stash
临时存储未提交的工作。
git stash save 'some message'
这会将您当前的更改存储在您的存储列表中。以上是最明确的 stash 命令版本,允许使用注释来描述您要存储的内容。您也可以只运行 git stash
而不执行其他任何操作,但不会存储任何消息。
您可以使用...浏览您的存储列表
git stash list
这将显示您所有的存储,它们在哪些分支上完成,以及每行开头的消息和该存储的标识符,看起来像 stash@{#}
其中 # 是它在存储数组中的位置。
要恢复存储(可以在任何分支上完成,无论最初创建存储的位置如何),您只需运行...
git stash apply stash@{#}
同样,# 是存储数组中的位置。如果您要恢复的存储在 0
位置 - 也就是说,如果它是最近的存储。然后你可以在不指定存储位置的情况下运行命令,git 会假设你的意思是最后一个:git stash apply
。
因此,例如,如果我发现自己在错误的分支上工作 - 我可能会运行以下命令序列。
git stash
git checkout <correct_branch>
git stash apply
在您的情况下,您在分支周围移动了一点,但同样的想法仍然适用。
希望这可以帮助。
git config --global alias.uncommit reset HEAD^
只是取消提交重置的别名。相反,请执行 git config --global alias.uncommit 'reset HEAD^'
我想你正在寻找这个
git reset --soft HEAD~1
它撤消最近的提交,同时将该提交中所做的更改保持在暂存状态。
git reset HEAD^
只会提示“更多?” - 不管什么意思
^
是 DOS 中的转义字符。当与新行配对时,它用作前面命令的继续提示。键入 git reset HEAD^^
应该可以在 Windows 上运行。
是的,您可以在不删除更改的情况下删除您的提交:
git reset @~
git reset --soft
或 git reset --keep
有何不同?
您正在寻找 git reset HEAD^ --soft
或 git reset HEAD^ --mixed
。
如 docs 中所述,reset 命令有 3 种模式:
git reset HEAD^ --soft
撤消 git commit
。工作树(项目文件夹)+索引(--cached)中仍然存在更改
git reset HEAD^ --mixed
撤消 git commit
+ git add
。工作树中仍然存在更改
git reset HEAD^ --hard
就像您从未对代码库进行过这些更改一样。更改已从工作树中消失。
2020 简单方法:
git reset <commit_hash>
(您要保留的最后一次提交的提交哈希)。
如果提交被推送,您可以执行以下操作:
git push -f
您将在本地保留现在未提交的更改
就我而言,我已经推送到了仓库。哎哟!
您可以通过执行以下操作恢复特定提交,同时将更改保留在本地文件中:
git revert -n <sha>
通过这种方式,我能够保留我需要的更改并撤消已经推送的提交。
git revert bad-commit-sha
,然后到 git revert -n revert-commit-just-created-sha
,然后从那里修复。你让我半途而废。谢谢!
-n
选项,该选项将还原将执行的更改暂存但未提交。然后,您可以选择保留或丢弃哪些还原更改
对于那些使用 zsh 的人,您必须使用以下内容:
git reset --soft HEAD\^
此处解释:https://github.com/robbyrussell/oh-my-zsh/issues/449
如果 URL 失效,重要的部分是:
转义命令中的 ^ 您也可以使用 HEAD~ 这样您就不必每次都转义它。
git reset HEAD^
为我在 zsh 中工作,可能已修复。
zsh 5.3 (x86_64-apple-darwin18.0)
.zshrc
,很多人可能会从中受益。示例:github.com/GregHilston/toolbox/blob/master/dot/zshrc#L147
使用 git 2.9 (确切地说是 2.9.2.windows.1) git reset HEAD^
提示更多;不确定这里的预期输入。请参考下面的截图
https://i.stack.imgur.com/BfNIt.png
找到了其他解决方案 git reset HEAD~#numberOfCommits
,我们可以使用该解决方案来选择您想要重置的本地提交的数量,方法是保持您的更改不变。因此,我们有机会丢弃所有本地提交以及有限数量的本地提交。
https://i.stack.imgur.com/m27db.png
https://i.stack.imgur.com/HvasB.png
另一种方法来做到这一点。
在临时提交的顶部添加提交,然后执行:
git rebase -i
将两个提交合并为一个(命令将打开带有明确说明的文本文件,编辑它)。
git reset HEAD^
优雅。 Git rebase 在这里有很大的错误空间。
在某些情况下,我只想在第一次提交时撤消对特定文件的更改,以将它们添加到第二次提交并拥有更清晰的 git 日志。
在这种情况下,我要做的是:
git checkout HEAD~1 <path_to_file_to_put_in_different_commit>
git add -u
git commit --amend --no-edit
git checkout HEAD@{1} <path_to_file_to_put_in_different_commit>
git commit -m "This is the new commit"
当然,即使在 rebase -i
中间,在提交拆分时带有编辑选项,这也能很好地工作。
首先,您可以使用以下命令查看日志 -
git reflog
这显示了所有提交,然后找出您要撤消的提交以及与之关联的 Head 编号,然后输入以下命令
git reset HEAD@{#NumberOfCommitYouWantToUndo}
例如git reset HEAD@{3}
git reset HEAD@{#} 显示重置后所有未暂存的更改
More?
。无论我在那个提示符下输入什么,都会给我fatal: ambiguous argument 'HEADwhateverItypedIn': unknown revision or path not in the working tree.
^
视为特殊字符的外壳。您可以引用参考"HEAD^"
,或使用替代语法HEAD~1
unquotedgit reset HEAD\^
不得不转义字符