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

mik*_*son 581 git git-commit

我刚刚对错误的分支做了很好的提交.如何撤消我的主分支中的最后一次提交,然后进行相同的更改并将它们放入我的升级分支?

Bla*_*way 899

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

git reset --soft HEAD^
Run Code Online (Sandbox Code Playgroud)

这将恢复提交,但将提交的更改放回到索引中.假设分支相对于彼此是最新的,git将允许你进入另一个分支,然后你可以简单地提交:

git checkout branch
git commit
Run Code Online (Sandbox Code Playgroud)

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

  • 如果你得到更多?在你的Windows命令行中,使用引号来包围HEAD ^,如下所示:git reset --soft"HEAD ^" (46认同)
  • zsh用户:你可能会发现你需要像这样逃避^:`git reset --soft HEAD\^` (16认同)
  • 请注意,软重置会使您的更改暂存并准备提交.当我的IDE没有显示文件在软复位后返回修改状态时让我有点困惑. (8认同)
  • 完美修复,实际上有几个提交所以HEAD ^^和bam都是肉汁 (8认同)
  • 谢谢.这节省了我两次.如果分支有所不同,在重置之后和结账之前,您可能必须先存储您的更改,然后才能签出另一个分支.结账后重新申请藏匿处 (8认同)
  • 只是不要忘记^伙计们.这非常重要.没有它,好吧,上帝是善良的! (3认同)
  • 我在复位后尝试切换分支时遇到了另一个问题:Git说:"你对以下文件的本地更改将被checkout覆盖......"所以我不得不藏匿,切换分支然后弹出. (2认同)

fot*_*nus 123

关于这个话题迟了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
Run Code Online (Sandbox Code Playgroud)

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

  • 这绝对是正确的答案. (3认同)
  • 这应该是公认的答案.简单,明显,直接,无论提交次数多少,只使用基本的Git功能.我用TortoiseGit做了这些步骤.谢谢!:) (3认同)
  • 本例中的重置没有恢复我的更改,必须在 reflog 中找到它们,然后将它们合并到我的新分支中。为什么?不知道。 (2认同)
  • @GringoSuave,你可能像我一样,使用了 `git checkout -b my_feature` 并且你的 HEAD 现在位于 my_feature 分支。我通过返回 master 来纠正这个问题,并实际上执行了“gitbranch my_feature”,它从手册页中将创建一个新分支,但不会切换到它,而是保留在工作树中。当没有指定此命令的起点时,它会创建 my_feature 分支到当前 HEAD(这是您提交的分支) - 这是默认值。 (2认同)

Mic*_*zek 109

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

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

git reset --hard HEAD^
Run Code Online (Sandbox Code Playgroud)

将该提交拉入另一个分支:

git checkout other-branch
git cherry-pick COMMIT-HASH
Run Code Online (Sandbox Code Playgroud)

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

另请注意,这git reset --hard取消您可能拥有的任何未经跟踪和修改的更改,因此如果您有更改您可能更喜欢的更改:

git reset HEAD^
git checkout .
Run Code Online (Sandbox Code Playgroud)

  • 为了获得额外的安全感,请先在正确的分支上执行cherry-pick,然后重置错误的分支. (13认同)
  • 如果你忘记先注意哈希,只需使用`git reflog show <branch>`! (12认同)
  • @Jefromi我在那里害怕了一分钟. (2认同)

Igo*_*aka 20

如果您已经推动了更改,则需要在重置HEAD后强行进行下一次推送.

git reset --hard HEAD^
git merge COMMIT_SHA1
git push --force
Run Code Online (Sandbox Code Playgroud)

警告:硬重置将撤消工作副本中任何未提交的修改,而强制重置将完全覆盖具有本地分支当前状态的远程分支的状态.

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

git reset --hard HEAD^^^^
Run Code Online (Sandbox Code Playgroud)

  • 请注意,除非绝对必要,否则您应该*强制推送到其他人正在使用的分支 - 否则他们将无法推送,直到他们变基.但是,如果您是使用git的唯一开发人员,那么这很好. (6认同)
  • 或者,除非你在其他任何人提出错误提交之前你已经足够快地意识到了. (2认同)

Ali*_*zan 15

我最近做了同样的事情,我不小心改变了主人,当我应该致力于其他分支.但我没有推动任何东西.

如果您刚刚提交错误的分支,并且之后没有更改任何内容,并且没有推送到repo,那么您可以执行以下操作:

// 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..."
Run Code Online (Sandbox Code Playgroud)

注意:在上面的例子中,我用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
Run Code Online (Sandbox Code Playgroud)

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


Lor*_*ill 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
Run Code Online (Sandbox Code Playgroud)

现在你所有的承诺都master将继续another-branch.

来自爱的来自:http://haacked.com/archive/2015/06/29/git-migrate/

  • 这似乎对我不起作用。“另一个分支”已经存在。在这种情况下,它只是破坏了我要掌握的提交,而没有将它们放在“另一个分支”中。 (2认同)

Mit*_*rus 11

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

如果对您来说,这只是 1 次提交,那么还有许多其他更简单的重置解决方案可用。对我来说,我有大约 10 个提交是我不小心在master分支上创建的,我们称之为target,我不想丢失提交历史记录。

你能做什么,以及拯救我的是使用这个答案作为参考,使用 4 步过程,即 -

  1. 创建一个新的临时党支部tempmaster
  2. 合并temp到最初用于提交的分支,即target
  3. 撤消提交 master
  4. 删除临时分支temp

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

  1. master(我不小心提交了很多更改的地方)创建了一个新分支

    git checkout -b temp
    
    Run Code Online (Sandbox Code Playgroud)

    注意:-b标志用于创建一个新分支
    只是为了验证我们是否正确,我会快速git branch确保我们在temp分支上并git log检查我们是否正确提交。

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

    git checkout target
    
    Run Code Online (Sandbox Code Playgroud)

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

    git merge temp
    
    Run Code Online (Sandbox Code Playgroud)

    如果有冲突,您可能需要处理这里的一些冲突。成功合并后,您可以推动(我愿意)或继续下一步。

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

    git checkout master
    
    Run Code Online (Sandbox Code Playgroud)

    然后使用下面的命令将其撤回以匹配远程(或特定提交,如果需要,使用适当的命令)

    git reset --hard origin/master
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    git checkout target
    
    Run Code Online (Sandbox Code Playgroud)

    然后删除这起事故的证据

    git branch -d temp
    
    Run Code Online (Sandbox Code Playgroud)

你去吧。


ars*_*ius 9

为了阐述这个答案,如果你有多次提交到例如从移动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
Run Code Online (Sandbox Code Playgroud)