如何撤消“git commit --amend”完成而不是“git commit”

发布于 2024-08-06 00:40:09 字数 146 浏览 11 评论 0原文

我不小心修改了之前的提交。提交应该是单独的,以保留我对特定文件所做的更改的历史记录。

有没有办法撤消最后一次提交?如果我执行诸如 git reset --hard HEAD^ 之类的操作,则第一次提交也会被撤消。

(我还没有推送到任何远程目录)

I accidentally amended my previous commit. The commit should have been separate to keep history of the changes I made to a particular file.

Is there a way to undo that last commit? If I do something like git reset --hard HEAD^, the first commit also is undone.

(I have not yet pushed to any remote directories)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

沉鱼一梦 2024-08-13 00:40:09

您需要做的是创建一个新提交,其详细信息与当前 HEAD 提交相同,但父级为 HEAD 的先前版本。 git reset --soft 将移动分支指针,以便下一次提交发生在与当前分支头现在所在位置不同的提交之上。

# Move the current head so that it's pointing at the old commit
# Leave the index intact for redoing the commit.
# HEAD@{1} gives you "the commit that HEAD pointed at before 
# it was moved to where it currently points at". Note that this is
# different from HEAD~1, which gives you "the commit that is the
# parent node of the commit that HEAD is currently pointing to."
git reset --soft HEAD@{1}

# commit the current tree using the commit details of the previous
# HEAD commit. (Note that HEAD@{1} is pointing somewhere different from the
# previous command. It's now pointing at the erroneously amended commit.)
# The -C option takes the given commit and reuses the log message and
# authorship information.
git commit -C HEAD@{1}

What you need to do is to create a new commit with the same details as the current HEAD commit, but with the parent as the previous version of HEAD. git reset --soft will move the branch pointer so that the next commit happens on top of a different commit from where the current branch head is now.

# Move the current head so that it's pointing at the old commit
# Leave the index intact for redoing the commit.
# HEAD@{1} gives you "the commit that HEAD pointed at before 
# it was moved to where it currently points at". Note that this is
# different from HEAD~1, which gives you "the commit that is the
# parent node of the commit that HEAD is currently pointing to."
git reset --soft HEAD@{1}

# commit the current tree using the commit details of the previous
# HEAD commit. (Note that HEAD@{1} is pointing somewhere different from the
# previous command. It's now pointing at the erroneously amended commit.)
# The -C option takes the given commit and reuses the log message and
# authorship information.
git commit -C HEAD@{1}
糖果控 2024-08-13 00:40:09

使用 HEAD@{1} 的这些答案都不适合我,所以这是我的解决方案:

git reflog

d0c9f22 HEAD@{0}: commit (amend): [Feature] - ABC Commit Description 
c296452 HEAD@{1}: commit: [Feature] - ABC Commit Description 

git reset --soft c296452

您的暂存环境现在将包含您意外与 c296452 提交合并的所有更改。

None of these answers with the use of HEAD@{1} worked out for me, so here's my solution:

git reflog

d0c9f22 HEAD@{0}: commit (amend): [Feature] - ABC Commit Description 
c296452 HEAD@{1}: commit: [Feature] - ABC Commit Description 

git reset --soft c296452

Your staging environment will now contain all of the changes that you accidentally merged with the c296452 commit.

沐歌 2024-08-13 00:40:09

使用 ref-log

git branch fixing-things HEAD@{1}
git reset --soft fixing-things

然后您应该拥有以前的所有内容修改工作副本中的更改,并可以将它们提交到新的提交中。

要查看以前的头提交的完整列表,请输入 git reflog

如果您正在寻找单个命令来实现此目的并且不害怕低级命令,您可能会发现我的其他答案很有帮助管道命令。

Use the ref-log:

git branch fixing-things HEAD@{1}
git reset --soft fixing-things

You should then have all your previously amended changes in your working copy and can commit them to a new commit.

To see a full list of previous head commits type git reflog.

You might find my other answer helpful if you are looking for a single command to achieve this and are not afraid of low-level plumbing commands.

单挑你×的.吻 2024-08-13 00:40:09

通过以下方式查找修改后的提交:

git log --reflog

注意:为了清晰起见,您可以添加 --patch 来查看提交正文。与 git reflog 相同。

然后将您的 HEAD 重置为之前的任何提交:

git reset SHA1 --hard

注意:用您的真实提交替换 SHA1哈希。另请注意,此命令将丢失任何未提交的更改,因此您可以先将它们存储起来。或者,使用 --soft 来保留最新更改,然后提交它们。

然后挑选您需要的其他提交:

git cherry-pick SHA1

Find your amended commits by:

git log --reflog

Note: You may add --patch to see the body of the commits for clarity. Same as git reflog.

then reset your HEAD to any previous commit at the point it was fine by:

git reset SHA1 --hard

Note: Replace SHA1 with your real commit hash. Also note that this command will lose any uncommitted changes, so you may stash them before. Alternatively, use --soft instead to retain the latest changes and then commit them.

Then cherry-pick the other commit that you need on top of it:

git cherry-pick SHA1
羞稚 2024-08-13 00:40:09

如果您已将提交推送到远程,然后错误地修改了该提交的更改,这将解决您的问题。发出 git log 来查找提交前的 SHA。 (假设远程名称为 origin)。现在使用该 SHA 发出这些命令。

git reset --soft <SHA BEFORE THE AMMEND>
#you now see all the changes in the commit and the amend undone

#save ALL the changes to the stash
git stash

git pull origin <your-branch> --ff-only
#if you issue git log you can see that you have the commit you didn't want to amend

git stash pop
#git status reveals only the changes you incorrectly amended

#now you can create your new unamended commit

If you have pushed the commit to remote and then erroneously amended changes to that commit this will fix your problem. Issue a git log to find the SHA before the commit. (this assumes remote is named origin). Now issue these command using that SHA.

git reset --soft <SHA BEFORE THE AMMEND>
#you now see all the changes in the commit and the amend undone

#save ALL the changes to the stash
git stash

git pull origin <your-branch> --ff-only
#if you issue git log you can see that you have the commit you didn't want to amend

git stash pop
#git status reveals only the changes you incorrectly amended

#now you can create your new unamended commit
早乙女 2024-08-13 00:40:09

可能值得注意的是,如果您仍在编辑器中显示提交消息,则可以删除提交消息,它将中止 git commit --amend 命令。

Possibly worth noting that if you're still in your editor with the commit message, you can delete the commit message and it will abort the git commit --amend command.

橘虞初梦 2024-08-13 00:40:09

您始终可以拆分提交,
手册

  • 使用 git rebase -i commit^ 启动交互式变基,其中 commit 是提交你想要拆分的内容。事实上,任何提交范围都可以,只要它包含该提交。
  • 使用“编辑”操作标记要拆分的提交。
  • 当涉及到编辑该提交时,执行 git reset HEAD^。效果是 HEAD 倒转 1,索引也跟着倒转。但是,工作树保持不变。
  • 现在将更改添加到您想要在第一次提交中拥有的索引。您可以使用 git add (可能是交互方式)或 git-gui (或两者)来执行此操作。
  • 使用现在合适的任何提交消息提交当前索引。
  • 重复最后两个步骤,直到工作树干净为止。
  • 使用 git rebase --continue 继续变基。

You can always split a commit,
From the manual

  • Start an interactive rebase with git rebase -i commit^, where commit is the commit you want to split. In fact, any commit range will do, as long as it contains that commit.
  • Mark the commit you want to split with the action "edit".
  • When it comes to editing that commit, execute git reset HEAD^. The effect is that the HEAD is rewound by one, and the index follows suit. However, the working tree stays the same.
  • Now add the changes to the index that you want to have in the first commit. You can use git add (possibly interactively) or git-gui (or both) to do that.
  • Commit the now-current index with whatever commit message is appropriate now.
  • Repeat the last two steps until your working tree is clean.
  • Continue the rebase with git rebase --continue.
紫﹏色ふ单纯 2024-08-13 00:40:09

也许可以使用 git reflog 来获取修改前和修改后的两次提交。

然后使用 git diff before_commit_id after_commit_id > d.diff 获取修改前和修改后之间的差异。

接下来使用 git checkout before_commit_id 回到提交之前

,最后使用 git apply d.diff 来应用您所做的真正更改。

这解决了我的问题。

Maybe can use git reflog to get two commit before amend and after amend.

Then use git diff before_commit_id after_commit_id > d.diff to get diff between before amend and after amend.

Next use git checkout before_commit_id to back to before commit

And last use git apply d.diff to apply the real change you did.

That solves my problem.

淡淡の花香 2024-08-13 00:40:09

您可以执行以下操作来撤消您的 git commit —amend

  1. git reset --soft HEAD^
  2. git checkout files_from_old_commit_on_branch
  3. git pull origin your_branch_name< /code>

======================================

现在您的更改与之前相同。这样您就完成了 git commit —amend 的撤消操作,

现在您可以执行 git push origin来推送到分支。

You can do below to undo your git commit —amend

  1. git reset --soft HEAD^
  2. git checkout files_from_old_commit_on_branch
  3. git pull origin your_branch_name

====================================

Now your changes are as per previous. So you are done with the undo for git commit —amend

Now you can do git push origin <your_branch_name>, to push to the branch.

梦在夏天 2024-08-13 00:40:09

几乎晚了 9 年,但没有看到这个变体提到完成同样的事情(它是其中一些的组合,类似于顶部答案(https://stackoverflow.com/a/1459264/4642530)。

搜索分支上所有分离的头

git reflog show origin/BRANCH_NAME --date =relative

然后找到 SHA1 哈希

重置为旧的 SHA1

git reset --hard SHA1

然后将其推回原处。

git push origin BRANCH_NAME

完成。

这会将您完全恢复到旧的提交

(包括之前覆盖的分离提交头的日期) 。

Almost 9 years late to this but didn't see this variation mentioned accomplishing the same thing (it's kind of a combination of a few of these, similar to to top answer (https://stackoverflow.com/a/1459264/4642530).

Search all detached heads on branch

git reflog show origin/BRANCH_NAME --date=relative

Then find the SHA1 hash

Reset to old SHA1

git reset --hard SHA1

Then push it back up.

git push origin BRANCH_NAME

Done.

This will revert you back to the old commit entirely.

(Including the date of the prior overwritten detached commit head)

澉约 2024-08-13 00:40:09
  1. 检出到上次提交的临时分支

    gitbranch temp HEAD@{1}

  2. 重置上次提交

    git reset temp

  3. 现在,您将拥有您提交以及之前提交的所有文件。检查所有文件的状态。

    git status

  4. 从 git 阶段重置您的提交文件。

    git reset myfile1.js(依此类推)

  5. 重新附加此提交

    git commit -C HEAD@{1}

  6. 添加并提交您的文件到新的提交。

  1. Checkout to temporary branch with last commit

    git branch temp HEAD@{1}

  2. Reset last commit

    git reset temp

  3. Now, you'll have all files your commit as well as previous commit. Check status of all the files.

    git status

  4. Reset your commit files from git stage.

    git reset myfile1.js (so on)

  5. Reattach this commit

    git commit -C HEAD@{1}

  6. Add and commit your files to new commit.

稀香 2024-08-13 00:40:09

简单的解决方案
解决方案有效:如果您的 HEAD 提交与远程提交同步。

  • 在本地工作区中再创建一个分支,并使其与远程分支保持同步。
  • Cherry 从分支(其中 git commit --amend)中挑选 HEAD 提交到新创建的分支上。

精心挑选的提交将仅包含您的最新更改,而不包含旧更改。
您现在可以重命名此提交。

Simple Solution
Solution Works Given: If your HEAD commit is in sync with remote commit.

  • Create one more branch in your local workspace, and keep it in sync with your remote branch.
  • Cherry pick the HEAD commit from the branch (where git commit --amend) was performed onto the newly created branch.

The cherry-picked commit will only contain your latest changes, not the old changes.
You can now just rename this commit.

顾北清歌寒 2024-08-13 00:40:09

您可以通过以下方式轻松做到这一点:

  • 软重置具有旧提交和新提交的最后一次提交。修改后的更改

git reset --soft HEAD^

  • 现在在新提交中提交分阶段更改

git commit -m "new commit msg"

现在推送更改并重新调整此提交您修改更改的最后一次提交的顶部。

这将确保新提交仅修改了更改。

This is how you can do it easily:

  • Soft reset the last commit which has old commit & amended changes

git reset --soft HEAD^

  • Now commit the staged changes in a new commit

git commit -m "new commit msg"

Now push the changes and rebase this commit on top of last commit on which you had amended your changes.

This will make sure that the new commit has only amended changes.

太阳公公是暖光 2024-08-13 00:40:09

您可以使用低级 commit-tree 命令和 reflog< /a> 使用当前的头提交树构造一个新的提交,但将原始(修改前)提交作为父提交。通过重置工作树和索引来转发分支:

git reset --soft "$(git commit-tree HEAD^{tree} -p HEAD@{1} -m 'Commit message of new commit')"

为什么会这样?让我们看一些 ASCII 绘图:

C     t:W    (HEAD@{1}) original commit with tree W
B     t:V
A     t:U

这是我们开始的地方,但是修改提交后,我们剩下:

C'    t:X    (branch; HEAD) accidentally amended commit with tree X
| C   t:W    (HEAD@{1}) original commit with tree W
|/
B     t:V
A     t:U

提交 C 不再可以从分支访问,但它仍然存在于 Git 的数据库中,并在引用日志中列出为HEAD@{1}

您想要的是使用修改后的提交树创建以下新提交:

D     t:X    (branch; HEAD) separate commit with tree X
C     t:W    original commit with tree W
B     t:V
A     t:U

并且 git commit-tree HEAD^{tree} -p HEAD@{1} 正是这样做的:它创建提交 D与树 X(与修改提交 C' 相同的树),但将父级设置为 C(修改之前的提交)。需要使用 git reset 将分支从错误的、修改后的提交移动到正确的、单独的提交。

You can use the low-level commit-tree command and the reflog to construct a new commit with your current head commit's tree, but the original (pre-amend) commit as parent. The branch is forwarded by resetting both working tree and index:

git reset --soft "$(git commit-tree HEAD^{tree} -p HEAD@{1} -m 'Commit message of new commit')"

Why does this work? Let's have a look at some ASCII drawings:

C     t:W    (HEAD@{1}) original commit with tree W
B     t:V
A     t:U

This is where we start, but after amending the commit, we are left with:

C'    t:X    (branch; HEAD) accidentally amended commit with tree X
| C   t:W    (HEAD@{1}) original commit with tree W
|/
B     t:V
A     t:U

Commit C is no longer reachable from the branch, but it still exists in Git's database and is listed in the reflog as HEAD@{1}.

What you want is to create the following new commit with the tree of the amended commit:

D     t:X    (branch; HEAD) separate commit with tree X
C     t:W    original commit with tree W
B     t:V
A     t:U

and git commit-tree HEAD^{tree} -p HEAD@{1} does exactly that: it creates commit D with tree X (same tree as of amended commit C'), but sets the parent to C (the commit before being amended). git reset is required to move the branch from the erroneous, amended commit to the correct, separate commit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文