libgit2使用教程(六)分支操作

这篇一锅粥把主要的分支操作全都铺上来。
这里有一个基础概念需要复习一下,分支本质上上指的就是 reference ,在 .git/refs 中可以找到它们的信息。分支分为本地和远端,这里我们先不考虑远端分支,在之后介绍完联网操作之后再说。

所有内容:
git branch 列出所有分支
git branch <branch name> 新建分支
git branch -d <branch name> 删除分支
git branch -m <branch name> 分支改名
git checkout <branch name> 切换分支

1. git branch
主要使用 git_branch_iterator 对分支进行遍历。代码很简单,应该很好理解,就直接贴出来了:

git_branch_iterator *branch_iterator = nullptr;
git_reference *tmp_branch = nullptr;
git_branch_t branch_type;
// list branch
git_branch_iterator_new(&branch_iterator, rep, GIT_BRANCH_LOCAL);
while (GIT_ITEROVER != git_branch_next(&tmp_branch, &branch_type, branch_iterator))
{
    const char *branch_name;
    git_branch_name(&branch_name, tmp_branch);
    bool is_head = git_branch_is_head(tmp_branch);
    if (is_head)
    {
        std::cout << "*";
    }
    std::cout << "name: " << branch_name << std::endl;
}

可以看一下 git_branch_t ,它实际上就是一个超简单的枚举类型,标示出本地和远端分支:

/** Basic type of any Git branch. */
typedef enum {
    GIT_BRANCH_LOCAL = 1,
    GIT_BRANCH_REMOTE = 2,
    GIT_BRANCH_ALL = GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE,
} git_branch_t;

git_branch_is_head,就是判断这个分支是否是当前工作分支。也就是判断这个 reference 是不是 head 。

2. git branch <branch name>
流程就是:找到源分支 → 取到最后一次 commit → 基于这个 commit 创建新的分支
那么如果这个分支并没有 commit 呢?那么这肯定是一个一次都没提交过的仓库,这种情况可以用命令行做一个测试:

$ git branch dev 
fatal: Not a valid object name: 'master'.

实际上 git 并不支持这种行为。
所以新建分支的代码就是这样:

git_reference *head = nullptr;
git_reference *new_branch = nullptr;
const git_oid *commit_id = nullptr;
git_commit *last_commit = nullptr;

git_repository_head(&head, rep);
commit_id = git_reference_target(head);
git_commit_lookup(&last_commit, rep, commit_id);
git_branch_create(&new_branch, rep, "new"/* branch name */, last_commit, 0);

3. git branch -d <branch name>
很简单,先找到目标分支,然后调接口删之

git_reference *lookup_branch = nullptr;
git_branch_lookup(&lookup_branch, rep, "new"/* branch name */, GIT_BRANCH_LOCAL);
if (lookup_branch != nullptr && !git_branch_is_head(lookup_branch))
{
    git_branch_delete(lookup_branch);
}

删除分支要保证被删分支不是当前 head 分支,否则会报错

4. git branch -m <branch name>
跟删除分支差不多,先根据分支名找到要改名字的分支,然后调一个接口做改名操作

git_reference *lookup_branch = nullptr;
git_reference *renamed_branch = nullptr;

git_branch_lookup(&lookup_branch, rep, "new"/* old name */, GIT_BRANCH_LOCAL);
git_branch_move(&renamed_branch, lookup_branch, "new3"/* new name */, 0);

5. git checkout <branch name>
就是把当前工作分支(head)切换成指定的分支

git_reference *lookup_branch = nullptr;
git_branch_lookup(&lookup_branch, rep, "new"/* branch name */, GIT_BRANCH_LOCAL);
git_repository_set_head(rep, git_reference_name(lookup_branch));

git_repository_set_head 这个接口需要的名字不是简单的分支名,而是一个 reference 的全名(refs/heads/new),所以需要使用 git_reference_name 来取一下。

代码示例 sample6

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!