git三个小技巧:删除指定 commit、修改历史 commit 中的作者信息、合并某文件到当前分支
三个小技巧,工作中遇到了好几次,记录一下,方便后人和自己查看。
一、删除指定 commit
假设 commit 是最后一次 commit,这个很简单,直接
1 | git reset HEAD^ |
使用 soft 模式进行 reset(默认就是这样的),就可以取消 commit ,保留修改过后的文件,非常方便。 假设 commit 是很久以前的一条 commit,就要使用一种操作,叫rebase。比如某次commit我们不小心上传了某个 world.txt文件,后来不想要这个文件了,就可以用这个操作。 例如这三次commit
1 | commit 3bfcfea5366ca96c8aa900b7568daea2963c0741 (HEAD -> master) |
分别上传了三个文件,假设我们不要这个 world.txt 了,就要退到它的前一个版本
1 | git rebase -i 7c37f2fe648b63fd079fb82c8382191649f2869f |
会出现
1 | pick 4df80ac add world.txt |
改为
1 | drop 4df80ac add world.txt |
就会永久丢弃掉这个 commit,并且后面的 commit 还在。 之后强行推送到服务器,覆盖远程分支
1 | git push --force |
但是存在一个缺点,可能被服务器丢弃掉以前每个commit的修改时间,可以认为是在这一刻依次将历史 commit 都重新 commit 了一遍。
二、修改 commit 中的作者信息
这个大家肯定都遇到过,某些 repo 里的作者信息搞错了,需要批量修改。 https://help.github.com/articles/changing-author-info/ 按照这个链接操作一下就可以了,非常简单,非常舒服。 操作成功如下
1 | ➜ MyRepo.git git:(master) ./run.sh |
之后推送到远程即可,但是注意一下,链接里覆盖远程的代码是:
1 | git push --force --tags origin 'refs/heads/*' |
这个方法是有一定风险的,可能我们只是想改某个分支的,就不要用通配符,可以用:
1 | git push --force --tags origin 'refs/heads/online' |
三、合并某文件到当前分支
emmmm,讲道理这个需求挺奇怪的,为什么要从分支 A 的某文件复制到分支 B 呢?讲个以前见过的操作,Android 发布时,会从各个 feature 中抽取出文件,汇总一下发布。所以这个需求也是有的,刚好被我碰上了,我的需求是将master里新建的.gitignore复制到dev里,而 dev 已经被我开发了很久了(别问我为什么有这么奇怪的需求),我不想合并它们,只想拿个文件过来。 这里讲个操作,叫cherry-pick,和 merge 的区别在于分支还是相互独立的,不会合并。
1 | git checkout dev |
这样就会将 aabbccdd 这个commit信息合并到dev,非常方便,当然也会生成一个额外的commit,自动的。 默认是将全部文件都复制过来,可以再多操作几下,删掉无用的文件。