在我的一个开发分支中,我对代码库做了一些更改。在我能够完成正在开发的功能之前,我必须将当前分支切换到master来演示一些功能。但仅仅使用“git checkout master”就保留了我在开发分支中所做的更改,从而破坏了master中的一些功能。因此,我所做的是在我的开发分支上提交一条提交消息“临时提交”,然后为演示签出主控。
现在,我已经完成了演示并返回到我的开发分支中,我想删除我所做的“临时提交”,同时仍然保留我所作的更改。这可能吗?
在我的一个开发分支中,我对代码库做了一些更改。在我能够完成正在开发的功能之前,我必须将当前分支切换到master来演示一些功能。但仅仅使用“git checkout master”就保留了我在开发分支中所做的更改,从而破坏了master中的一些功能。因此,我所做的是在我的开发分支上提交一条提交消息“临时提交”,然后为演示签出主控。
现在,我已经完成了演示并返回到我的开发分支中,我想删除我所做的“临时提交”,同时仍然保留我所作的更改。这可能吗?
就这么简单:
git reset HEAD^
注意:有些shell将^视为特殊字符(例如,某些Windows shell或启用了globbing的ZSH),因此在这些情况下,您可能必须引用“HEAD^”或使用HEAD~1。
不带--hard或--soft的gitreset会将您的HEAD移动到指定的提交,而不会更改任何文件。HEAD^是指当前提交的(第一个)父提交,在您的情况下是临时提交之前的提交。
请注意,另一个选项是正常运行,然后在下一个提交点运行:
git commit --amend [-m … etc]
它将改为编辑最近的提交,具有与上面相同的效果。
请注意,如果您已经将错误的提交推到了其他人可能已将其删除的位置,则这(几乎与每个git答案一样)可能会导致问题。尽量避免这种情况
还有一种方法。
在临时提交的顶部添加提交,然后执行以下操作:
git rebase -i
要将两个提交合并为一个(命令将打开带有显式指令的文本文件,请对其进行编辑)。
有两种处理方法。哪个更容易取决于你的情况。
重置
如果您要删除的提交是最后一次提交,并且您没有做任何额外的工作,您可以简单地使用git reset
git reset HEAD^
将分支返回到当前HEAD之前的提交。但是,它实际上不会更改工作树中的文件。结果,该提交中的更改显示为已修改-这就像“取消提交”命令。事实上,我有一个别名来做这件事。
git config --global alias.uncommit 'reset HEAD^'
然后,您可以在将来使用gitunmit来备份一次提交。
挤压
压缩提交意味着将两个或多个提交合并为一个。我经常这样做。在您的案例中,您提交了一个完成一半的特性,然后您将完成它并使用正确的永久提交消息再次提交。
git rebase -i <ref>
我之所以这么说,是因为我想明确这可能是任何数量的提交。运行gitlog并找到要删除的提交,复制其SHA1并使用它来代替<ref>。Git将带您进入交互式重新基础模式。它将显示当前状态与放置在<ref>位置的任何内容之间的所有提交。因此,如果<ref>是10次提交,它将显示所有10次提交。
在每次提交之前,都会有pick这个词。找到您要删除的提交,并将其从pick更改为fixup或square。使用fixup只需丢弃提交消息并将更改合并到列表中的前一个消息中。squash关键字执行相同的操作,但允许您编辑新组合提交的提交消息。
请注意,当您退出编辑器时,提交将按照列表中显示的顺序重新提交。因此,如果您进行了临时提交,然后在同一分支上执行了其他工作,并在稍后的提交中完成了该功能,那么使用rebase将允许您重新排序提交并压缩它们。
警告:
重新分配修改历史记录-不要对您已经与其他开发人员共享的任何提交执行此操作。
固定(Stashing)
将来,为了避免这个问题,可以考虑使用git stash临时存储未提交的工作。
git stash save 'some message'
这将把您当前的更改存储在存储列表的旁边。以上是stash命令的最显式版本,允许注释描述您正在隐藏的内容。您也可以简单地运行git stash,而不执行其他操作,但不会存储任何消息。
你可以浏览你的隐藏列表。。。
git stash list
这将显示您的所有存储,它们在哪些分支上执行,以及消息和每行的开头,以及该存储的标识符,看起来像这个存储@{#},其中#是它在存储阵列中的位置。
要恢复存储(可以在任何分支上执行,无论存储最初是在哪里创建的),只需运行。。。
git stash apply stash@{#}
同样,#是存储阵列中的位置。如果要恢复的存储在0位置,也就是说,如果是最近的存储。然后,您可以在不指定存储位置的情况下运行该命令,git将假设您是指最后一个:git stash apply。
因此,例如,如果我发现自己在错误的分支上工作,我可能会运行以下命令序列。
git stash
git checkout <correct_branch>
git stash apply
在您的案例中,您在分支中移动了一点,但同样的想法仍然适用。
就我而言,我已经推动回购。哎哟
您可以通过以下操作恢复特定提交,同时将更改保留在本地文件中:
git revert -n <sha>
通过这种方式,我能够保留所需的更改,并取消已经推送的提交。
使用git2.9(精确到2.9.2.windows.1)git reset HEAD^提示更多信息;不确定此处的预期输入。请参考下面的截图
找到了另一个解决方案git-resetHEAD~#numberOfCommits,我们可以使用它来选择要通过保持更改不变来重置的本地提交数。因此,我们有机会丢弃所有本地提交以及有限数量的本地提交。
请参阅下面显示git reset HEAD~1的屏幕截图:
对于使用zsh的用户,您必须使用以下选项:
git reset—软头\^
此处解释:https://github.com/robbyrussell/oh-my-zsh/issues/449
如果URL失效,重要的部分是:
转义命令中的^你也可以选择使用HEAD~,这样你就不必每次都逃避它。
您正在查找git reset HEAD^--soft或git reset-HEAD^-mixed。
如文档中所述,重置命令有三种模式:
git reset HEAD^--软
撤消git提交。更改仍然存在于工作树(项目文件夹)+索引(--cached)中
git reset HEAD^--混合
撤消gitcommit+gitadd。工作树中仍存在更改
git reset HEAD^--硬
就像你从未对代码库做过这些更改一样。更改将从工作树中删除。
2020简单方法:
git reset <commit_hash>
(您要保留的最后一次提交的提交哈希)。
如果推送提交,则可以执行以下操作:
git push -f
您将在本地保留当前未提交的更改
在某些情况下,我只想在第一次提交时撤消对特定文件的更改,以便将它们添加到第二次提交中,并有一个更干净的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"
当然,即使在使用committosplit上的编辑选项进行rebase-i时,这也能很好地工作。
首先,您可以使用以下命令查看日志-
git reflog
这将显示所有提交,然后找出要撤消的提交以及与之关联的头号,然后输入以下命令
git reset HEAD@{#NumberOfCommitYouWantToUndo}
例如git reset HEAD@{3}
git-resetHEAD@{#}显示重置后的所有未分级更改
如果您想更新提交的历史记录,或者想添加新的提交并删除以前的提交,请使用此代码
此命令将打印最后一个提交散列,例如fa386d8eaa4bde4a4a2912ef96aad6df31f4d4ccgit日志重置上次提交。注意:它不会删除任何更改并保留新的和旧的更改。仅删除最后一条提交消息数字重置629f9dfb47620a1794f5edf816762f8e30668498添加所有更改的文件git添加。提交您的邮件gitcommit-m“Your_new_commit_message_here”强制推送之前已经推送的内容,并使用相同的gitlog命令进行检查git push-f源Your_Branch_Name