在我的一个开发分支中,我对代码库做了一些更改。在我能够完成我正在处理的功能之前,我必须将我当前的分支切换到master以演示一些功能。但是仅仅使用"git checkout master"就保留了我在开发分支中所做的更改,从而破坏了master中的一些功能。所以我所做的就是在我的开发分支上提交更改,提交消息为"临时提交",然后签出演示的master。
现在我已经完成了演示并返回到我的开发分支,我想删除我所做的"临时提交",同时仍然保留我所做的更改。有可能吗?
- 下次:git stash。
- @Mattball,不一定。虽然git stash是一个很好的工具,"进行中的工作"放弃承诺也是一个相当合法的设备。
- 这是一个来自Github的巨大资源海峡:如何撤消和Git有关的任何内容
- @Mattball@Kostix是的,Stash特别不适合"长期"存储,因为它是整个回购的一个全球堆栈。我想把零钱藏在一个分支上,然后去其他分支机构,做其他任何事情,几天后回来,不用担心我可能会在过渡期间在其他分支机构上使用git stash。
- 关于stash,有一点值得注意,那就是它完全是本地的,并且很容易由于repo删除或重新创建或硬件故障或丢失而丢失代码。在我看来,它真的应该只用于非常短期的在制品。在去度假之前,喜欢WIP承诺:p.。称之为"大脑倾倒承诺"!
- 我马上就把一个临时分支机构变成一个临时分支机构,然后再变成一个临时分支机构,但这当然不是一个答案。
就这么简单:
没有--hard或--soft的git reset移动HEAD指向指定的提交,而不更改任何文件。HEAD^是指您当前提交的(第一个)父级提交,在您的情况下是临时提交之前的提交。
请注意,另一个选项是正常进行,然后在下一个提交点运行:
1
| git commit --amend [-m … etc] |
号
它将编辑最近的提交,与上面的效果相同。
注意,如果你已经把坏承诺推到了一个可能有人把它从中拉出来的地方,那么这(和几乎所有Git答案一样)可能会导致问题。尽量避免那样
- 这是迄今为止最简单的,但是如果你已经把承诺推到了一个遥控器上,而有人拉了它,我会非常犹豫,除了道歉什么都不做。
- @西科哲学,不要错过机会读到"重置去神秘化"在这个场合。
- 我要把这个确切的答案贴出来。做得好。一个简单的git reset HEAD^就可以了!
- 我做了这件事之后得到了More?。无论我在那个提示下键入什么,都会给我fatal: ambiguous argument 'HEADwhateverItypedIn': unknown revision or path not in the working tree.。
- @Daawsomep听起来像是在使用一个外壳,它将^视为一个特殊的字符。您可以引用引用"HEAD^",也可以使用未引用的可选语法HEAD~1。
- @Gareth需要注意的是,这在Windows8.1的常规命令提示符中(不包括git bash/shell)。
- 为我工作,但不得不逃避角色
- 在窗户上,我不得不使用git reset"HEAD^"。
- 该死!我没有读评论,读了"HEAD^ refers to the (first) parent commit of your current commit, which in your case is the commit before the temporary one."之后,我读了git reset parent commit,失去了我所有的修改。幸运的是他们很多。
- 如果不起作用,请参阅stackoverflow.com/questions/14203952/git-reset-asks-more
- @他们不知道你说的迷路是什么意思?这不会释放你的任何变化吗?你可以回到你重置的提交?(30多天后,如果没有分支指向它或它的任何子级,则可以删除它)
- 不知道可以用amend添加/删除文件
- @kostix fwiw链接已更改为git-scm.com/book/en/v2/git-tools-reset-demystalized
- 如果您和我一样,忘记获取提交消息的副本,那么提交实际上仍然存在,您可以执行git show 来查看和复制您令人敬畏的提交消息。(在我的例子中,将提交从一个分支转移到另一个分支。)
- 好几年了,我一直在想这个!伟大的!
- 如果您习惯于通过Visual Studio与Git一起工作,而不是分段进行更改,请注意,git commit --amend只会拾取分段的更改。
有两种处理方法。哪个更容易取决于你的情况
重置
如果你想摆脱的承诺是最后一个承诺,而你没有做任何额外的工作,你可以简单地使用git-reset。
在您当前的头之前将您的分支恢复到提交状态。但是,它实际上不会更改工作树中的文件。结果,提交中的更改显示为已修改-类似于"uncommit"命令。事实上,我有一个别名可以这样做。
1
| git config --global alias.uncommit 'reset HEAD^' |
号
然后,您可以在将来使用git uncommit来备份一个提交。
压扁
挤压提交意味着将两个或多个提交合并为一个提交。我经常这样做。在您的案例中,您已经提交了一个完成一半的特性,然后您将完成它,并使用适当的、永久的提交消息再次提交。
我之所以这么说是因为我想澄清一下,这可能是任何数量的承诺。运行git log并找到您想要摆脱的承诺,复制它的sha1并用它代替。Git会把你带到交互式钢筋网模式。它将显示您当前状态和您取代所做的所有承诺。因此,如果在10之前提交,它将显示所有10个提交。
在每一次提交之前,它都会有一个单词pick。找到你想要摆脱的承诺,把它从pick改为fixup或squash。使用fixup只需放弃提交消息并将更改合并到列表中的直接前一个。squash关键字执行相同的操作,但允许您编辑新组合提交的提交消息。
请注意,当您退出编辑器时,提交将按照它们在列表中显示的顺序重新提交。因此,如果您进行了一次临时提交,然后在同一个分支上做了其他工作,并在以后的提交中完成了该特性,那么使用REBASE将允许您对提交进行重新排序并挤压它们。
警告:
重新平衡修改历史记录-不要对已经与其他开发人员共享的任何提交执行此操作。
藏匿
将来,为了避免这个问题,考虑使用git stash临时存储未提交的工作。
1
| git stash save 'some message' |
。
这将把您当前的更改存储在您的隐藏列表中。上面是stash命令的最明确版本,允许注释来描述您要存储的内容。您也可以简单地运行git stash,但不会存储任何消息。
你可以浏览你的藏品清单…
这将向您显示您的所有藏品、它们所使用的分支、消息和每行的开头,以及该藏品的标识符,它看起来像这样的stash@{#},其中是它在藏品阵列中的位置。
要恢复一个stash(可以在任何分支上执行,不管stash最初是在哪里创建的),只需运行…
1
| git stash apply stash@{#} |
。
再一次,藏匿点的排列中有一个位置。如果你想要恢复的藏匿处在0的位置,也就是说,如果是最近的藏匿处。然后你可以在不指定stash位置的情况下运行命令,git会假设你指的是最后一个:git stash apply。
例如,如果我发现自己在处理错误的分支,我可以运行以下命令序列。
1 2 3
| git stash
git checkout <correct_branch>
git stash apply |
。
在您的例子中,您移动了更多的分支,但同样的想法仍然适用。
希望这有帮助。
- git config --global alias.uncommit reset HEAD^只是别名取消提交重置。相反,是git config --global alias.uncommit 'reset HEAD^'
- 请注意,如果在Windows命令提示中使用,则必须使用^^而不是^。
我想你在找这个
埃多克斯1〔3〕
它将撤消最近的提交,同时将该提交中所做的更改保留到临时状态。
- 谢谢。这对我很有用。在Windows上调用git reset HEAD^只会提示"更多?"-不管什么意思
- @tyron ^是dos中的转义符。与新行配对时,它将作为前面命令的延续提示。键入git reset HEAD^^应该可以在Windows上使用。
- @好的,谢谢你的信息
是的,您可以删除提交而不删除更改:Git重置@~
- 这是我真正想要的,这将是我认为可以接受的答案,非常感谢!
- 有趣的,简洁的语法,我以前没见过也没用过。这与git reset --soft或git reset --keep有什么不同?
对于使用zsh的用户,必须使用以下内容:
江户十一〔四〕号
解释如下:https://github.com/robbyrussell/oh-my-zsh/issues/449
如果URL失效,重要的部分是:
Escape the ^ in your command
You can alternatively can use HEAD~ so that you don't have to escape it each time.
号
- 我永远记不起这个命令,只能用谷歌搜索这个并找到我自己的答案哈哈哈
- git reset HEAD^正在zsh为我工作,可能已经修好了。
- @Benkolymansley你在运行什么版本的zsh?
- 我用的是zsh 5.3 (x86_64-apple-darwin18.0)。
在我的情况下,我已经推进回购。哎哟!
通过执行以下操作,可以在保留本地文件中的更改的同时还原特定的提交:
这样我就能够保持我所需要的更改,并且取消了一个已经被推动的承诺。
- 在我的例子中,我需要恢复一些我已经推到远程存储库的东西。更糟糕!最好的办法是先到git revert bad-commit-sha,再到git revert -n revert-commit-just-created-sha,然后从那里修理。你让我走了一半。谢谢!
- 这似乎正好相反,不是吗?它创建与所选提交中所做更改的还原相对应的新更改。如果您要提交这些新的更改,您将撤消实际上想要保留的工作。
使用Git2.9(精确地说是2.9.2.windows.1)git reset HEAD^提示输入更多信息;不确定这里需要什么输入。请参阅下面的屏幕截图
。
找到了其他解决方案git reset HEAD~#numberOfCommits,我们可以选择通过保持更改不变来选择要重置的本地提交数。因此,我们有机会放弃所有本地提交以及有限数量的本地提交。
请参阅下面显示git reset HEAD~1正在运行的屏幕截图:氧化镁
氧化镁
- 您可能需要转义^字符-尝试git reset"head^"或git reset head^
- 此外,Git重置头^^作为一个单独的^被视为一个新行。
还有一种方法。
在临时提交的顶部添加提交,然后执行以下操作:
要将两个提交合并为一个提交(命令将用显式指令打开文本文件,编辑它)。
- 技术上是正确的,但远不如简单地做git reset HEAD^那样优雅。Git Rebase在这里有很大的错误空间。
你要找的不是git reset HEAD^ --soft就是git reset HEAD^ --mixed。
如文档中所述,重置命令有三种模式:
埃多克斯1〔5〕
松开git commit。更改仍然存在于工作树(项目文件夹)+索引(--cached)中。
埃多克斯1〔6〕
撤销git commit+git add。工作树中仍存在更改
埃多克斯1〔12〕
就像你从未对代码库做过这些更改一样。更改从工作树中消失。