libgit2使用教程(十三)git rebase

rebase 就是将制定目标分支,或者制定 commit 所在的一条路径,直接插到当前分支或目标分支。(好像有点乱,具体的东西自己去查吧)

简单点说,这不是合并。

当然,虽然不是 merge 但是也会有冲突的可能,所以中途有解决冲突的需要,所以 rebase 操作是分阶段进行的,因此逻辑会复杂一些。

首先尝试打开现有未完成的 rebase

git_rebase* prebase = nullptr; 
git_rebase_options rebase_opt = GIT_REBASE_OPTIONS_INIT; 
error = git_rebase_open(&prebase, rep, &rebase_opt);

如果存在未完成的 rebase,可以选择继续将其完成,或者把它终止掉

git_rebase_abort(prebase);

在 git_rebase_open 返回 -3 (也就是 GIT_ENOTFOUND ) 表示当前仓库并没有其他未完成的 rebase 可以放心大胆的从头开始搞。

接下来创建一个 rebase

git_rebase* prebase = nullptr; 
git_rebase_options rebase_opt = GIT_REBASE_OPTIONS_INIT; git_reference* onto_branch = nullptr; 
git_annotated_commit* onto = nullptr; 
git_branch_lookup(&onto_branch, rep, "new", GIT_BRANCH_LOCAL); git_annotated_commit_from_ref(&onto, rep, onto_branch); 
git_rebase_init(&prebase, rep, 
   nullptr /* current branch */, 
   nullptr /* upstream */ , 
   onto    /* branch to rebase onto */, 
   &rebase_opt);

init 的第三个参数是需要被操作的分支,传空表示当前分支;第四个参数和第五个参数这俩二选一,前者表示以一个 commit 为节点把到这个节点为止的一条链合并到目标分支;后者是直接选一个分支的最新一个 commit ,将这个分支的整条链合并到目标分支。

当然,这个时候工作区不会有任何变化。到 .git 文件夹里面会看到多了一个叫做 rebase-merge 的文件夹。如果这个时候程序被终止,这个文件夹会保留,在下一次启动的时候,就可以通过 git_rebase_open 打开这个 rebase 。

接下来就是实际执行 rebase 这个操作

git_rebase_operation* operation = nullptr; 
git_rebase_next(&operation, prebase)

这里可能存在遍历,但是为什么会有多个 operation 我也还没搞太明白,不过为了避免出事,还是循环调用保险一些:

while (git_rebase_next(&operation, prebase) != GIT_ITEROVER)

接下来,不要忘记查看是否有冲突,需要将冲突解决才可以做后边的 commit 的操作:

// reslove conflicts 
git_repository_index(&index, rep); 
if (git_index_has_conflicts(index)) 
{ 
   // git checkout --theirs 
   git_checkout_options opt = GIT_CHECKOUT_OPTIONS_INIT; 
   opt.checkout_strategy |= GIT_CHECKOUT_USE_THEIRS; 
   git_checkout_index(rep, index, &opt); 
} 

// add 
git_index_update_all(index, nullptr, nullptr, nullptr); 
git_index_write(index);

在解决完冲突,并且 add 之后,就可以 commit 了。这里并不需要使用 commit 的 create 接口,rebase 部分提供了 rebase 专用的 commit 接口。

git_signature* me = nullptr; 
git_oid new_commit; 
git_signature_now(&me, "XiaochenFTX", "xiaochenftx@gmail.com"); 
git_rebase_commit(&new_commit, prebase, me, me, "UTF-8", "new rebase");

最后,做一下收尾 finish 掉这个 rebase 操作

git_rebase_finish(prebase, me);

示例代码:sample13

RSS
Follow by Email
YouTube
YouTube
Pinterest
fb-share-icon
LinkedIn
Share
VK
Weibo
WeChat
WhatsApp
Reddit
FbMessenger
Copy link
URL has been copied successfully!