我们知道git是分布式的代码管理工具,quilt是管理补丁的,利用栈原理对pathch进行管理,前段时间同事给介绍了一个stgit的补丁管理工具,它跟quilt很类似,也是将一组patch
进行出栈入栈,然后对其中某个patch进行更改,只是它与git相结合使用,集合了git和quilt的优点,例如想更某个patch的内容,那么你只需要出栈到该patch之前,然后更改代码,quilt 更新之后,它会自动地更新与此patch相关的commit,然后生成新的patch(即将add+commit+format-patch自动完成了,而不用像先前一样,先撤销commit,然后修改,然后add,commit,再生成patch,并且先前的commit也被撤销了)。所以如果平时代码就是用git来管理的话,如果需要修改代码,修改patch的话,可以使用stgit来操作。
一、stgit的安装和初始化
stgit不能单独使用,它要与git相结合,操作一个已用git init或者git clone创建好的git仓库。
yum install git
yum install stgit
我们可以使用某个仓库: git clone ssh://git@9.152.144.***/Linux
cd Linux
stg init (在使用stgit对当前分支的commit创建stgit补丁前,先初始化stgit以便其与当前分支建立联系)
进入repository
二、stgit处理patch
stg uncommit --number n ------将前n个commit生成n个patch
stg series ------查看栈里面的patch (>表示当前栈顶, +表示在栈里, -表示已经出栈)
stg pop (--all) -------出栈一个patch
stg push (--all ) -------入栈一个patch, --all将n个patch入栈,这样stgit就可以管理这n个patch, git pop -n 2 ,入栈前两个,栈顶的patch是HEAD
stg status --------查看patch的状态,M的话代表stgit解决了所有问题,一切正常;C的话代表有冲突的文件
stg refresh --------将新的修改更新到栈顶的patch里面
eg: 如果处理3个commit, A为最新的commit
commit A
commit B
commit C
1. 生成patch(A,B,C) stg uncommi --number 3
2. 入栈 (栈顶为A) stg push --all
3. 现在想修改patch B的内容,比如修改file1,那么我们需要让patchB成为栈顶,那么stg pop ,此时patchB为栈顶
修改文件file1, 然后简单的使用stg refresh一步操作,就可以把更新放入patchB,并且commit也会跟着更新(再也不需要
add文件更新,然后commit生成commitD,与commitB合并这么麻烦了)
三、新建patch, 新建的patch会自动push到栈里,在栈顶??????
可以在任何时候新建一个patch以满足自己的需要:
stg new patch_name [ --message "new patch"] ----------可以使用message选项来提供提交信息
做一些修改
stg refresh -----------刷新patch之后,使用stg show可以看到此patch里面已经有了修改的信息
四、更改提交信息
除了在stg new的时候可以使用--message来提供提交信息为i,还可以使用:
stg edit patch_name (stg edit 有个--diff选项提供了差异文本)
stg refresh --edit ”提交信息“
五、处理冲突
一般情况下,stg对于重排两个补丁,或者修改某个补丁入栈之后,再入栈其他补丁时候,如果他们没修改同一个文件,或者即使修改了同一个文件,但是没有
修改文件的同一部分,stgit都能很好地自动合并。如果真的出现了冲突,要如何解决?
在前面的例子里,我们更新了patchB,然后我们再把patchA入栈的时候,发现patchB的修改与原来patchA的内容发生了冲突,A入栈失败。
stg status 可以看到:
? file1 .ancestor
? file1 .current
? file1 .patched
C file1
.current文件是应用patchA之前的版本, .patche文件是将patchA入栈后的文件版本, .current是拥有冲突另外部分的版本
这时,对于冲突我们可以选择:
1. stg undo --hard 撤销合并
2. 手工解决冲突
打开file1,可以看到如下冲突:
<<<<<<<< current:file1
-- xxxxxxx
=====================
--yyyyyyyyy
>>>>>>>>> patched:file1
存在冲突的区域使用了<<<<<<<、=======和>>>>>>> 以标识出哪些是已经存在的(current), 哪些内容是patchA新添加的。
根据自己需要解决冲突。
在解决完冲突之后:
git add file1 -----切记
stg status ------可以查看一下file1前面已经变为M
stg refresh -------将修改更新到patchA
五、stgit处理某个patch的拆分:
eg:想把patchB拆分为两个patch --B‘,B2, 这时就要:
1. 先stg pop到patchB作为栈顶
2. 然后修改patchB的内容为patchB’ (修改文件,然后stg refresh)
3. stg new patch_B2
stg push --patch patch_B2
修改文件以满足想要的内容
stg refresh
4. stg push (此时是入栈了patchA), 如果发生了冲突,则需要按照先前步骤四的方法来解决冲突
六、更新非栈顶的patch
1. stg refresh --patch
2. stg new一个新patch, 然后stg squash 合并到其他patch里面
七、stg repair( 一般不要在使用stg进行patch管理的时候,去使用git进行编辑,可以使用浏览功能,比如git log), 一旦不小心使用了git add 修改了commit,
那么stg 将不能对已有的patch进行管理,此时使用stg repair可以将先前的几个patch 恢复到改动之前的状态。新的改动放在stg管理栈里面,可以stg delete一个个删除新的
patch。