使用libgit2从另一个分支创建新的git存储库?

时间:2018-05-22 00:41:01

标签: c++ git libgit2

在使用libgit2的C ++中,我想创建一个新的本地存储库,其master分支基于来自另一个本地存储库的specific-branch,保留其历史记录,以便稍后我可以在两者之间同步

基本上,我正在尝试以下方法,除了使用libgit2:

https://stackoverflow.com/a/9529847/1019385

所以,如果我的文件安排如下:

  

./ old.git [branches:master,specific-branch]

     

./ old / * [特定分支的./old.git文件和克隆]

命令的位置如下:

git init --bare ./new.git
cd ./old
git push ./new.git +specific-branch:master

并提出类似的事项(删除错误检查以减少代码):

git_libgit2_init();
git_repository* repo = nullptr;
git_repository_init(&repo, "./new.git", true);
git_remote_create(&remote, repo, "origin", "./new.git");
git_remote_add_push(repo, "origin", "+specific-branch:master");
git_push_options optionsPush = GIT_PUSH_OPTIONS_INIT;
git_remote_push(remote, nullptr, &optionsPush);

我不确定从哪里开始,以及如何在实际执行某些操作的地方正确调用git_remote_push()。目前没有副作用,因为未引用./old.git。也就是说,./new.git已正确创建,但不包含./old.git / ./old/*的内容。

非常感谢。

基于建议采用“获取”方法的答案,我还尝试了以下方法:

git_repository* repo = nullptr;
if (git_repository_init(&repo, "./new.git", true)) {
    FATAL();
}
git_remote* remote;
git_remote_create_anonymous(&remote, repo, "./old");
char* specs[] = { _strdup("specific-branch:master"), nullptr };
git_strarray refspecs;
refspecs.count = 1;
refspecs.strings = specs;
if (git_remote_download(remote, &refspecs, NULL)) {
    FATAL();
}

这仍然无效。

3 个答案:

答案 0 :(得分:2)

在直接的git中,最灵活和最直接的方法(因为它不需要你已经拥有整个存储库,你只需要一些),例如。

git init --bare new.git; cd $_

git fetch --no-tags ~/src/git next:master    # to fetch and rename a branch
# or
git fetch ~/src/git v2.17.0; git branch master FETCH_HEAD   # full handroll

要在libgit2中执行此操作,您可以像往常一样使用git_repository_init和内存中的#34;匿名"来创建存储库。远离网址(我希望路径也可以,请检查)git_remote_create_anonymous,然后 git_remote_download git_remote_fetch你想要的refspec从那起。

答案 1 :(得分:0)

一种替代方法(IMHO,API的方式),因为您要执行的是使用自定义上游分支的“标准”克隆步骤,因此可以使用git_clone提供的自定义点(而不是使用所有较小的部分/步骤)。

所以这样的事情应该起作用(C伪代码):

int main() {
    git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
    git_repository *repo;

    opts.bare = 1;
    opts.remote_create_cb = (git_remote_create_cb)git_remote_create_with_fetchspec;
    opts.remote_create_payload = "specific-branch:master";

    return git_clone(&repo, "./old", "./new", &opts);
}

答案 2 :(得分:-1)

看起来你正在创建一个新的存储库,然后在其上添加一个遥控器并尝试使用它来推送自己...如果你想真正模仿你的命令,你需要两个存储库:

  1. git_repository_init new.git,然后
  2. git_repository_open old,然后在 it 上设置遥控器,并将 it 推送到新存储库。
  3. 有些事情:

    git_repository *old = NULL, *new = NULL;
    
    git_libgit2_init();
    git_repository_init(&new, "./new.git", true);
    git_repository_free(new);
    
    git_repository_open(&old, "./old");
    git_remote_create(&remote, old, "origin", "./new.git");
    git_remote_add_push(old, "origin", "+specific-branch:master");
    git_remote_push(remote, NULL, NULL);
    git_repository_free(old);