libgit2中的git_sysdir_find_in_dirlist()有什么作用?

时间:2019-04-03 14:49:24

标签: c git libgit2

我正在尝试将libgit2中的某些逻辑移植到Go中,但由于Go的工作原理不同,所以没有将1:1端口移植到Go中。我认为此功能会扫描目录树,但不确定。

static int git_sysdir_find_in_dirlist(
    git_buf *path,
    const char *name,
    git_sysdir_t which,
    const char *label)
{
    // allocations
    size_t len;
    const char *scan, *next = NULL;
    const git_buf *syspath;

    // check the path to make sure it exists?
    GIT_ERROR_CHECK_ERROR(git_sysdir_get(&syspath, which));
    if (!syspath || !git_buf_len(syspath))
        goto done;

    // this is the part I don't understand
    for (scan = git_buf_cstr(syspath); scan; scan = next) {
        /* find unescaped separator or end of string */
        for (next = scan; *next; ++next) {
            if (*next == GIT_PATH_LIST_SEPARATOR &&
                (next <= scan || next[-1] != '\\'))
                break;
        }

        len = (size_t)(next - scan);
        next = (*next ? next + 1 : NULL);
        if (!len)
            continue;

        GIT_ERROR_CHECK_ERROR(git_buf_set(path, scan, len));
        if (name)
            GIT_ERROR_CHECK_ERROR(git_buf_joinpath(path, path->ptr, name));

        if (git_path_exists(path->ptr))
            return 0;
    }

done:
    git_buf_dispose(path);
    git_error_set(GIT_ERROR_OS, "the %s file '%s' doesn't exist", label, name);
    return GIT_ENOTFOUND;
}

这是让我感到困惑的for循环。 for (scan = git_buf_cstr(syspath); scan; scan = next) { ... }似乎在迭代/扫描syspath,然后我在for (scan = git_buf_cstr(syspath); scan; scan = next) { ... }迷路了。

此功能专门做什么?

2 个答案:

答案 0 :(得分:0)

这不是查看目录 tree ,而是查看包含目录列表的定界字符串。例如,the top level documentation说(尽管这显然不是针对特定情况的)

  

GIT_ALTERNATE_OBJECT_DIRECTORIES
  由于Git对象具有不变性,因此旧对象可以    存档到共享的只读目录中。这个变量    指定一个“:”分隔(在Windows上为“;”分隔)的Git列表    对象目录,可用于搜索Git对象。新    对象将不会写入这些目录。

     

以“(双引号)开头的条目将被解释为    C样式的带引号的路径,删除前导和尾随双引号    并尊重反斜线转义。例如,值    “带有->的路径”:香草路径有两个路径:    具有“和”的路径香草路径

该函数显然正在扫描用字符分隔的路径列表(无论该字符是什么-可能是上述的冒号或分号),检查反斜杠前缀,以便您可以编写/a:C\:/a来允许事物查看/aC:/a

答案 1 :(得分:0)

此功能的任务是在“配置级别”中查找文件name(即~/.git//etc/git,请参阅git_sysdir_t以获取已知位置的列表) )。由于这些级别存储为一堆用静态(“只读”)/(或\)分隔的C字符串,因此我们无法在运行时进行修改,因此必须跳过循环等于一个foreach-string循环。