如何删除未推送的Git提交

如何删除未推送的Git提交

在使用Git进行版本控制时,有时我们需要删除还未推送到远程仓库的提交。以下是几种常见的情况及相应的解决方法。

保留工作进度并删除最近一个提交

如果想删除最近的一次提交,但保留所做的工作,可以使用git reset --soft命令。

1
git reset --soft HEAD~1

此命令会将HEAD指针回退一个提交,同时保留工作目录中的修改,并把这些修改保留在暂存区,方便你稍后重新提交。

删除最近提交并破坏已完成的工作

若要删除最近一次提交,并且销毁所做的工作,可以使用git reset --hard命令。

1
git reset --hard HEAD~1

此命令将HEAD指针回退一个提交,同时丢弃所有未推送的修改,工作目录和暂存区都会恢复到指定提交的状态。

使本地仓库与远程仓库同步

如果要将本地仓库与远程仓库同步,去除本地所做的所有更改,可以使用以下命令:

1
git reset --hard origin

也可以指定远程分支,将本地分支重置为远程仓库中对应分支的状态:

1
git reset --hard origin/<branch>

处理多个提交的情况

采用 git cherry-pick 复制单个提交

如果只有一个提交需要处理,使用git cherry-pick命令通常就足够了。例如,要将某个提交复制到另一个分支:

1
2
3
4
5
6
# 获取提交的SHA
git rev-parse HEAD
# 切换到目标分支
git checkout other-branch
# 复制提交到目标分支
git cherry-pick <sha-of-the-commit>

利用 git rebase --onto 处理多个提交

当在错误的分支上有多个提交时,git rebase --onto可以发挥很好的作用。假设当前分支结构如下:

1
2
3
x--x--x--x <-- master
\
-y--y--m--m <- y branch, with commits which should have been on master

可以按以下步骤操作:

1
2
3
4
5
6
7
# 标记 master 分支
git checkout master
git branch tmp
# 切换到 y 分支
git checkout y
# 将 master 分支指针移动到当前 y 分支
git branch -f master

此时分支结构变为:

1
2
3
x--x--x--x <-- tmp
\
-y--y--m--m <- y branch, master branch

然后将y分支重置到正确的位置:

1
2
3
git checkout y
# 这里假设回退2个提交,你可以根据实际情况更改
git reset --hard HEAD~2

分支结构更新为:

1
2
3
4
5
6
x--x--x--x <-- tmp
\
-y--y--m--m <- master branch
^
|
-- y branch

最后移动提交(重新应用提交,生成新的提交):

1
2
git rebase --onto tmp y master
git branch -D tmp

最终分支结构变成:

1
2
3
x--x--x--x--m'--m' <-- master
\
-y--y <- y branch

以交互方式删除提交

还可以使用git rebase -i以交互方式编辑提交历史,删除不需要的提交。

1
git rebase -i FAR_ENOUGH_BACK

在弹出的编辑器中,删除不想保留的提交对应的行,保存并退出编辑器即可。

通过硬切方式删除提交

除了git reset --hard,还可以使用以下命令硬切提交:

1
git checkout -B <branch-name> <SHA>

如果不需要切换分支,也可以直接设置分支到指定的提交:

1
git branch -f <branch-name> <SHA>

相关操作总结

  • git reset --soft会移动HEAD指针,但保留工作目录和暂存区的修改。
  • git reset --hard会移动HEAD指针,并丢弃所有未推送的修改。
  • git branch -f可以强制将分支指针移动到指定的提交。
  • git rebase用于在当前分支上重新应用提交。
  • git cherry-pick用于从不同分支复制提交。