725

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

4

11 回答 11

1150

如果您还没有推送您的更改,您还可以进行软重置:

git reset --soft HEAD^

这将恢复提交,但将提交的更改放回您的索引中。假设分支相对于彼此来说是最新的,git 会让你检查另一个分支,然后你可以简单地提交:

git checkout branch
git commit -c ORIG_HEAD

-c ORIG_HEAD部分对于不再键入提交消息很有用。

于 2010-05-31T05:53:20.067 回答
188

该主题晚了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并且所有新的提交都 on my_feature。请注意,这my_feature是一个本地分支,而不是远程分支。

于 2014-02-06T14:44:33.570 回答
116

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

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

git reset --hard HEAD^

将该提交拉入不同的分支:

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

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

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

git reset HEAD^
git checkout .
于 2010-05-31T05:33:08.127 回答
22

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

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

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

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

git reset --hard HEAD^^^^
于 2010-05-31T06:11:27.620 回答
19

我最近做了同样的事情,我不小心提交了对 master 的更改,而我应该提交给 other-branch。但我什么也没推。

如果您刚刚提交到错误的分支,并且此后没有更改任何内容,并且没有推送到 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..."

注意:在上面的例子中,我使用 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/

于 2017-05-30T21:51:29.300 回答
12

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

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

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

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

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

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

    git checkout -b temp
    

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

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

    git checkout target
    

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

    git merge temp
    

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

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

    git checkout master
    

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

    git reset --hard origin/master
    

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

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

    git checkout target
    

    然后删除这个事故的证明

    git branch -d temp
    

你去吧。

于 2020-01-21T20:15:43.343 回答
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/

于 2016-04-08T13:19:46.920 回答
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
于 2018-10-18T00:48:18.360 回答
3

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

右键单击您的分支并选择View History

在此处输入图像描述

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

在此处输入图像描述

于 2017-04-04T23:39:24.037 回答
2

对我来说,这是通过恢复我推送的提交来解决的,然后选择该提交到另一个分支。

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来找到正确的哈希,并且您可以随时推送这些更改!

于 2020-04-15T19:29:26.470 回答
1

如果您想要应用更改的分支已经存在(例如分支develop),请按照以下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

此外,如果适用,请延迟存储弹出(应用),直到您在目标分支合并之后。

于 2016-08-23T22:15:55.623 回答