(十) 改变历史

拣选指令:git cherry-pick

从众多的提交中挑选出一个提交应用在当前的工作分支中。需要一个提交ID作参数,操作过程相当于将该提交导出为补丁文件,然后在当前HEAD上重放,形成无论内容还是提交说明都一致的提交。

对提交执行变基操作:git rebase

实现将指定范围的提交嫁接到另外一个提交之上。

-i 交互式界面

--continue变基遇到冲突而暂停的情况下,先完成冲突解决(添加到暂存区,不提交),然后在恢复变基操作时使用

--skip变基遇到冲突而暂停的情况下,跳过当前提交时使用

--abort变基遇到冲突而暂停的情况下,终止变基操作,回到之前的分支时使用

$ git rebase --onto

首先会执行 git checkout 切换到  。 因为会切换到  ,因此如果  指向的不是一个分支(如 master),则变基操作是在 detached HEAD (分离头指针)状态进行的,当变基结束后,还要像在“时间旅行一”中那样,对 master 分支执行重置以实现把变基结果记录在分支中。

将 .. 所标识的提交范围写到一个临时文件中。 还记得前面介绍的版本范围语法, .. 是指包括  的所有历史提交排除  以及  的历史提交后形成的版本范围。

当前分支强制重置(git reset --hard)到  。 相当于执行: git reset --hard  。

从保存在临时文件中的提交列表中,一个一个将提交按照顺序重新提交到重置之后的分支上。

如果遇到提交已经在分支中包含,跳过该提交。

如果在提交过程遇到冲突,变基过程暂停。用户解决冲突后,执行 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

然后就可以使用变基操作。

反转提交:git revert

重新做一次新的提交,相当于用错误的历史提交的反向提交,来修正错误的历史提交。

文章导航