拣选指令:git cherry-pick
从众多的提交中挑选出一个提交应用在当前的工作分支中。需要一个提交ID作参数,操作过程相当于将该提交导出为补丁文件,然后在当前HEAD上重放,形成无论内容还是提交说明都一致的提交。
对提交执行变基操作:git rebase
实现将指定范围的提交嫁接到另外一个提交之上。
-i 交互式界面
--continue变基遇到冲突而暂停的情况下,先完成冲突解决(添加到暂存区,不提交),然后在恢复变基操作时使用
--skip变基遇到冲突而暂停的情况下,跳过当前提交时使用
--abort变基遇到冲突而暂停的情况下,终止变基操作,回到之前的分支时使用
$ git rebase --onto <newbase> <since> <till>
首先会执行 git checkout 切换到 <till> 。 因为会切换到 <till> ,因此如果 <till> 指向的不是一个分支(如 master),则变基操作是在 detached HEAD (分离头指针)状态进行的,当变基结束后,还要像在“时间旅行一”中那样,对 master 分支执行重置以实现把变基结果记录在分支中。
将 <since>..<till> 所标识的提交范围写到一个临时文件中。 还记得前面介绍的版本范围语法, <since>..<till> 是指包括 <till> 的所有历史提交排除 <since> 以及 <since> 的历史提交后形成的版本范围。
当前分支强制重置(git reset --hard)到 <newbase> 。 相当于执行: git reset --hard <newbase> 。
从保存在临时文件中的提交列表中,一个一个将提交按照顺序重新提交到重置之后的分支上。
如果遇到提交已经在分支中包含,跳过该提交。
如果在提交过程遇到冲突,变基过程暂停。用户解决冲突后,执行 git rebase --continue 继续变基操作。或者执行 git rebase --skip 跳过此提交。或者执行 git rebase --abort 就此终止变基操作切换到变基前的分支上。
丢弃历史
由里程碑A对应的提交构造出一个根提交至少有两种方法。
第一种:使用git commit-tree命令。用A^{tree}语法访问里程碑A对应的目录树,使用git commit-tree命令直接从该目录树创建提交。
$ git cat-file -p A^{tree}
$ echo "Commit from tree of tag A." | git commit-tree A^{tree}
第二种:使用git hash-object命令。用A^0语法访问里程碑A对应的提交。将输出过滤掉以parent开头的行,并将结果保存到一个文件中。运行git hash-object命令,将文件tmpfile作为一个commit对象写入对象库。
$ git cat-file commit A^0
$ git cat-file commit A^0 | sed -e '/^parent/ d' > tmpfile
$ git hash-object -t commit -w -- tmpfile
然后就可以使用变基操作。