用好 Git 很难: 很容易就犯错了,然后想自己弥补犯下的错,简直太难了。查阅 Git 文档简直就像是个 “鸡生蛋 蛋生鸡” 的问题,
你得知道你要的是啥
,但问题就在于我不知道呀!
所以接下来我会分享一些我遇到过的抓狂的经历,然后用
白话
来说说我是如何解决的。
# 警告: 千万别对公共的 commit 做这种操作
这经常发生在我提交了 commit 以后立马发现,哎呀,我忘了在某个等号后面加空格了。当然,你也可以提交一个新的 commit 然后利用
rebase -i
命令来合并它们,但我觉得我的这种方式比你快 100 万倍。
警告: 你千万不要在已推送的公共分支上做这个 amend 的操作! 只能在你本地 commit 上做这种修改,否则你会把事情搞砸的!
很多人建议使用
cherry-pick
来解决这个问题,其实两者都可以,你只要选择自己喜欢的方式就行了。
git checkout name-of-the-correct-branch
# 抓取 master 分支上最新的那个 commit
git cherry-pick master
# 然后删掉 master 上的那个 commit
git checkout master
git reset HEAD~ --hard
如果对文件做了改动,但是通过 diff
命令却看不到,那很可能是你执行过 add
命令将文件改动添加到了 暂存区
了。你需要添加下面这个参数。
git diff --staged
这些文件在这里 ¯\_(ツ)_/¯ (是的,我知道这是一个 feature 而不是 bug,但它第一次发生在作为初学者的你身上时,真的很让人困惑!)
git revert [刚才记下的那个 hash 值]
# git 会自动修改文件来抵消那次 commit 的改动,并创
# 建一个新的 commit,你可以根据提示修改这个新 commit
# 的信息,或者直接保存就完事了
这样你就不需要用回溯老版本然后再复制粘贴的方式了,那样做太费事了!如果你提交的某个 commit 导致了 bug,你直接用 revert
命令来撤回那次提交就行啦。
你甚至可以恢复单个文件而不是一整个 commit!但那是另一套 git 命令咯...
git checkout [刚才记下的那个 hash 值] -- path/to/file
# 改动前的文件会保存到你的暂存区
git commit -m "这样就不需要通过复制粘贴来撤回改动啦"
我花了好长好长时间才搞明白要这么做。说真的,用 checkout --
来撤回一个文件的改动,这真是太奇葩了?! :向 Linus Torvalds 摆出抗议姿势:
cd ..
sudo rm -r fucking-git-repo-dir
git clone https://some.github.url/fucking-git-repo-dir.git
cd fucking-git-repo-dir
感谢 Eric V. 提供了这个事例,如果对 sudo
的使用有什么的质疑的话,可以去向他提出。
不过说真的,如果你的分支真的这么糟糕的话,你应该使用 "git-approved" 的方法来重置你的 repo,可以试试这么做,但要注意这些操作都是破坏性的,不可逆的!
# 获取远端库最新的状态
git fetch origin
git checkout master
git reset --hard origin/master
# 删除 untracked 的文件和目录
git clean -d --force
# 对每一个有问题的分支重复上述 checkout/reset/clean 操作