如何修复提交到错误的Git分支?


621

我只是对错误的分支做出了非常好的承诺。如何撤消master分支中的最后一次提交,然后进行相同的更改并将其放入我的升级分支中?

Answers:


975

如果尚未推送更改,也可以进行软重置:

git reset --soft HEAD^

这将还原提交,但是将提交的更改放回索引中。假设分支之间的关系是相对最新的,git可以让您签入另一个分支,然后您可以简单地提交:

git checkout branch
git commit

缺点是您需要重新输入提交消息。


10
请注意,软重置使您的更改处于分阶段状态并可以提交。当我的IDE未显示软重置后文件未返回修改后的状态时,我感到有些困惑。
mtjhax 2012年

9
完美的解决方法,实际上有几次犯错,HEAD ^^和bam都是肉汁
pablo

8
谢谢。这救了我两次。如果分支有所不同,则在重置之后和检出之前,您可能必须先存储更改,然后才能检出另一个分支。结帐后重新套用
Kirby

17
zsh用户:您可能会发现需要像这样转义^:git reset --soft HEAD\^
Stephen Fuhry 2012年

54
如果您得到更多?在Windows命令行中,使用引号将HEAD ^括起来,如下所示:git reset --soft“ HEAD ^”
Nate Cook

140

在该主题上晚了4年,但这可能对某人有所帮助。

如果您在提交并在master上全部提交之前忘记创建一个新分支,那么无论您执行了多少次提交,以下方法都会更容易:

git stash                       # skip if all changes are committed
git branch my_feature
git reset --hard origin/master
git checkout my_feature
git stash pop                   # skip if all changes were committed

现在,您的master分支等于,origin/master并且所有新的提交均已启用my_feature。请注意,这my_feature是本地分支,而不是远程分支。


感谢您的回答。现在我正在使用egit,我想知道是否可以通过执行以下操作来完成相同的操作:1)将当前的“ master”重命名为“ my_feature”。2)从“来源/母版”重新创建本地“母版”。我不确定这些操作的幕后作风是什么,但这似乎是一个可行的解决方案
mjj1409 2014年

为什么要合并?您可以直接在上创建分支master,然后重置masterorigin/master
caesarsol

1
那是最有趣的部分:您不需要多次提交,因为origin/master您已经要重置其提交了!然而,对于尖端的信用是此页:github.com/blog/...
caesarsol

4
这应该是公认的答案。简单,明显,直截了当,无论提交多少,都只能使用基本的Git功能。我使用TortoiseGit完成了这些步骤。谢谢!:)
Ian Grainger

1
我以为这是最好的答案,但它有一个局限性。仅当您最近从远程撤出时才有用。并且假设您有一个遥控器。如果您只有本地分支“ master”和新功能修复,则唯一正确的答案是对master进行硬重置,以计入一定数量的提交。
pauljohn32 '18

111

如果您有干净的(未经修改的)工作副本

要回滚一个提交(请确保您记下下一步的提交哈希):

git reset --hard HEAD^

要将提交提交到另一个分支:

git checkout other-branch
git cherry-pick COMMIT-HASH

如果您已修改或未跟踪更改

另请注意,这git reset --hard杀死您可能拥有的所有未跟踪和已修改的更改,因此,如果有,则可能更喜欢:

git reset HEAD^
git checkout .

git rev-parse BRANCH_NAME得到的sha。
维尔特尔2010年

12
如果您忘记先记下哈希,请使用git reflog show <branch>
卡斯卡贝尔

2
@Jefromi我在那里害怕了一分钟。
伊恩·亨特

13
为了获得额外的安全感,请先在正确的分支上执行“自动挑选”操作,然后再重置错误的分支。
年龄Mooij,

1
同样,如果发生未跟踪的更改,则可以git stash在重置之前使用,git stash pop然后在恢复之后使用它,因此无需担心该--hard部分
Clemens Klein-Robbenhaar 2013年

20

如果您已经推送了更改,则需要在重置HEAD之后强制下一次推送。

git reset --hard HEAD^
git merge COMMIT_SHA1
git push --force

警告:硬重置将撤消工作副本中所有未提交的修改,而强行推送将完全用本地分支的当前状态覆盖远程分支的状态。

以防万一,在Windows(使用Windows命令行而不是Bash)上,它实际上是四个^^^^而不是一个,所以它是

git reset --hard HEAD^^^^

6
请注意,除非绝对必要,否则请勿强行推入其他人正在使用的分支,否则他们将无法推送,直到他们变基为止。但是,如果您是使用git的唯一开发人员,那很好。
布莱尔·霍洛威

2
或者,除非您在其他人未提出错误提交之前就足够快地意识到。
Michael Mior

如果您git reset --hard COMMIT_HASH git push --force
不止一次

17

最近,我做了同样的事情,当我本应致力于其他分支时,我不小心将更改提交给master。但是我什么也没推。

如果您只是提交给错误的分​​支,并且此后未做任何更改,也没有推送到存储库,则可以执行以下操作:

// rewind master to point to the commit just before your most recent commit.
// this takes all changes in your most recent commit, and turns them into unstaged changes. 
git reset HEAD~1 

// temporarily save your unstaged changes as a commit that's not attached to any branch using git stash
// all temporary commits created with git stash are put into a stack of temporary commits.
git stash

// create other-branch (if the other branch doesn't already exist)
git branch other-branch

// checkout the other branch you should have committed to.
git checkout other-branch

// take the temporary commit you created, and apply all of those changes to the new branch. 
//This also deletes the temporary commit from the stack of temp commits.
git stash pop

// add the changes you want with git add...

// re-commit your changes onto other-branch
git commit -m "some message..."

注意:在上面的示例中,我使用git reset HEAD〜1倒带1次提交。但是,如果您想回退n次提交,则可以执行git reset HEAD〜n。

另外,如果您最终提交了错误的分支,并且在意识到自己提交了错误的分支之前还写了更多代码,则可以使用git stash来保存正在进行的工作:

// save the not-ready-to-commit work you're in the middle of
git stash 

// rewind n commits
git reset HEAD~n 

// stash the committed changes as a single temp commit onto the stack. 
git stash 

// create other-branch (if it doesn't already exist)
git branch other-branch

// checkout the other branch you should have committed to.
git checkout other-branch

// apply all the committed changes to the new branch
git stash pop

// add the changes you want with git add...

// re-commit your changes onto the new branch as a single commit.
git commit -m "some message..."

// pop the changes you were in the middle of and continue coding
git stash pop

注意:我使用此网站作为参考 https://www.clearvision-cm.com/blog/what-to-do-when-you-commit-to-the-wrong-git-branch/


类似的事情发生在我身上,我对master进行了一些更改,但是我应该在新分支中完成并发送PR,最后我只是git checkout -b new_branch从那里做对了,提交是完整的,只是被推送并创建了PR,没有。不必再次提交。
Nishchal Gautam

11

因此,如果您的情况是您已承诺master但打算承诺another-branch(可能尚未存在)但尚未推送,则此问题很容易解决。

// if your branch doesn't exist, then add the -b argument 
git checkout -b another-branch
git branch --force master origin/master

现在您的所有提交都master将继续another-branch

充满爱意的来源:http : //haacked.com/archive/2015/06/29/git-migrate/


似乎是最直接的方法!不知道为什么这么少的爱和奉献
keligijus 18'Aug

4
这似乎对我不起作用。another-branch已经存在。在这种情况下,它只是破坏了我要掌握的提交,而没有将它们付诸实施another-branch
吉赛尔·塞拉特

6

为了阐述这个答案,如果你有多次提交到例如从移动developnew_branch

git checkout develop # You're probably there already
git reflog # Find LAST_GOOD, FIRST_NEW, LAST_NEW hashes
git checkout new_branch
git cherry-pick FIRST_NEW^..LAST_NEW # ^.. includes FIRST_NEW
git reflog # Confirm that your commits are safely home in their new branch!
git checkout develop
git reset --hard LAST_GOOD # develop is now back where it started

1
我有3次提交要还原,这个问题似乎使我的屁股从火中扑了出来。谢谢!
holdenweb

3

如果您遇到此问题并且拥有Visual Studio,则可以执行以下操作:

右键单击您的分支,然后选择View History

在此处输入图片说明

右键单击要返回的提交。并根据需要还原或重置。

在此处输入图片说明


3

对于错误分支上的多次提交

如果对您来说,大约只有1次提交,那么还有许多其他更容易的重置解决方案可用。对我来说,我偶然进行了约10次提交,master而不是称之为branch_xyz,并且我不想丢失提交历史记录。

您可以做些什么,而让我受益的是使用此答案作为参考,使用了四个步骤,即-

  1. 从创建一个新的临时分支 master
  2. 合并到最初用于提交的分支中,即 branch_xyz
  3. 撤消提交 master
  4. 删除临时分支。

以下是上述步骤的详细信息-

  1. 从中创建一个新分支master(我不小心做了很多更改)

    git checkout -b temp_branch_xyz
    

    注意:-bflag用于创建一个新的分支
    只是为了验证我们是否正确,我将快速git branch确定我们在该temp_branch_xyz分支上,并git log快速检查提交是否正确。

  2. 将临时分支合并到最初用于提交的分支中,即branch_xyz
    首先,切换到原始分支,即branch_xyzgit fetch如果没有,则可能需要)

    git checkout branch_xyz
    

    注意:不使用-b标志
    现在,让我们将临时分支合并到当前已签出的分支中branch_xyz

    git merge temp_branch_xyz
    

    如果存在,您可能需要在这里解决一些冲突。成功合并后,您可以按(我会)或继续进行下一步。

  3. 撤消master使用此答案作为参考的意外提交,首先切换到master

    git checkout master
    

    然后完全撤消它以匹配远程(或根据需要匹配特定的提交)

    git reset --hard origin/master
    

    同样,我会在执行git log之前和之后进行一次操作,以确保预期的更改生效。

  4. 删除证据,即删除临时分支。为此,首先您需要检出已合并临时文件的分支,即branch_xyz(如果继续master执行下面的命令,则可能会得到error: The branch 'temp_branch_xyz' is not fully merged),所以让我们

    git checkout branch_xyz
    

    然后删除此事故的证明

    git branch -d temp_branch_xyz
    

妳去


1

如果您要应用更改的分支已经存在(例如,分支开发),请按照下面fotanus提供的说明进行操作,然后:

git checkout develop
git rebase develop my_feature # applies changes to correct branch
git checkout develop # 'cuz rebasing will leave you on my_feature
git merge develop my_feature # will be a fast-forward
git branch -d my_feature

显然,如果需要,可以使用tempbranch或任何其他分支名称代替my_feature

另外,如果适用,请延迟隐藏存储(应用),直到在目标分支处合并之后。


我认为第一个命令(检出开发)是不必要的... rebase将首先检出“ my_feature”。
JoelFan

您也可以忽略“ rebase”命令的“ my_feature”参数(因为您已经签出“ my_feature”)。您还可以省略“合并”的“开发”参数(因为您已经签出“开发”)
JoelFan

1

对我来说,这是通过还原我已推送的提交,然后将那个提交挑选到另一个分支来解决的。

git checkout branch_that_had_the_commit_originally
git revert COMMIT-HASH
git checkout branch_that_was_supposed_to_have_the_commit
git cherry pick COMMIT-HASH

您可以git log用来查找正确的哈希,也可以随时更改这些更改!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.