在Git中丢弃本地提交
在Git中丢弃本地提交
技术背景
在使用Git进行版本控制时,我们可能会有一些多余的本地提交,或者需要撤销某些提交。同时,理解HEAD和detached HEAD的概念对于掌握Git操作至关重要。HEAD是对当前分支上当前提交(最新提交)的引用,其内容存储在.git/HEAD中,包含当前提交的40字节SHA - 1值。而detached HEAD是指HEAD指向历史中的某个先前提交,而非当前分支的最新提交。
实现步骤
丢弃本地提交
- 将本地仓库状态重置到远程分支状态:
如果多余的提交仅你可见,可以使用git reset --hard origin/<branch_name>将本地仓库状态重置到远程分支的状态,会丢弃所有本地更改。例如:1
git reset --hard origin/master - 删除最近一次提交:
- 保留工作内容:使用
git reset --soft HEAD~1,此命令会丢弃提交,但保留暂存区和工作目录。 - 删除工作内容:使用
git reset --hard HEAD~1,会丢弃提交,清除暂存区,重置工作目录。
- 保留工作内容:使用
- 删除最近n次提交:
使用git reset --hard HEAD~n,其中n是要丢弃的提交次数。例如,要丢弃最近5次提交:1
git reset --hard HEAD~5 - 通过SHA - 1哈希值重置:
可以使用git reset --hard <the sha1 hash>将HEAD重置到指定的提交。先使用gitk --all查看所需提交的SHA - 1 ID,然后执行重置操作。例如:1
git reset --hard 0d1d7fc32 - 使用
git rebase -i删除或压缩提交:
对于未推送的本地提交,可以使用git rebase -i。例如,git rebase -i HEAD~2会对最后两次提交进行变基操作,在弹出的编辑器中,将想要删除的提交标记为drop。
从detached HEAD状态恢复
- 使用
git checkout:- 切换到指定提交:
git checkout <commit_id>,这会导致detached HEAD状态,之后可以创建新分支继续工作。例如:
1
2git checkout 1234567
git checkout -b new_branch 1234567- 回退指定数量的提交:
git checkout HEAD~X,X是要回退的提交数量。
- 切换到指定提交:
- 使用
git reflog:git reflog会显示所有更新HEAD的更改,通过git checkout HEAD@{...}可以回到所需的提交。例如:1
2git reflog
git checkout HEAD@{5} - 使用
git reset --hard <commit_id>:
将HEAD移动到所需的提交,但会销毁任何本地修改。如果有未提交的工作需要保留,可以先使用git stash保存修改,重置后再使用git stash pop恢复。例如:1
2
3git stash
git reset --hard 0d1d7fc32
git stash pop - 使用
git revert <sha - 1>:
该命令会“撤销”给定的提交或提交范围,会创建一个新的提交来撤销原提交的更改,原提交仍会保留在历史记录中。例如:1
git revert 1234567
其他操作
- 删除未跟踪的文件:
使用git clean -df删除未跟踪的文件(未提交的本地更改)。 - Visual Studio中的操作:
- 在VS2019及以前:在
Team Explorer窗口中,连接到目标仓库,从Branches右键单击感兴趣的分支,选择View history,在History窗口中右键单击一个提交,选择Reset -> Delete changes (--hard)。 - 在VS2022中:使用
Git菜单中的Manage Branches,点击左侧的分支,右侧显示其历史记录,右键点击Reset -> Delete Changes (--hard)。
- 在VS2019及以前:在
核心代码
丢弃本地提交
1 | |
从detached HEAD状态恢复
1 | |
其他操作
1 | |
最佳实践
- 在执行
git reset --hard操作之前,最好先备份项目或创建一个新的分支,以免丢失重要的修改。 - 使用
git reflog可以方便地找回之前的提交,在不确定操作后果时,可以先查看reflog记录。 - 在使用
git revert时,它不会删除原提交,而是创建一个新的撤销提交,适用于多人协作的场景,避免影响其他开发者的提交历史。
常见问题
git reset --hard误操作怎么办:
可以使用git reflog查看之前的HEAD状态,然后使用git reset --hard <sha - 1>恢复到误操作之前的状态。git stash pop出现合并冲突怎么办:
需要手动解决合并冲突,在解决冲突后,使用git add将解决后的文件添加到暂存区,然后使用git commit提交更改。git rebase -i操作错误如何恢复:
如果git rebase -i操作过程中出现错误,可以使用git rebase --abort取消变基操作,回到变基之前的状态。
在Git中丢弃本地提交
https://119291.xyz/posts/discard-local-commits-in-git/