Создать новый репозиторий git из ветки другого, используя libgit2? - PullRequest
0 голосов
/ 22 мая 2018

В C ++ с использованием libgit2 я хотел бы создать новый локальный репозиторий, в котором его ветвь master основана на specific-branch из другого локального репозитория, сохраняя его историю, чтобы впоследствии я мог синхронизироваться между ними.

По сути, я пытаюсь сделать следующее, за исключением использования libgit2:

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

Так что, если бы у меня были файлы, расположенные следующим образом:

./old.git [ветви: главная, определенная ветка]

. / 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 голосов
/ 29 мая 2018

В прямом 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 и удаленным «анонимным» из памяти URL-адресом в памяти (я надеюсь, что путь также подойдет, проверьте это) с помощью git_remote_create_anonymous, затем git_remote_downloadgit_remote_fetch Refspec вы хотите от этого.

0 голосов
/ 28 июля 2018

Альтернативой (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);
}
0 голосов
/ 22 мая 2018

Похоже, вы создаете новый репозиторий, а затем добавляете в него пульт и пытаетесь использовать его для передачи себе ... Если вы действительно хотите эмулировать свои команды, вам понадобятся два репозитория:

  1. git_repository_init new.git, затем
  2. git_repository_open old, затем установите пульт дистанционного управления на it и нажмите это в новый репозиторий.

Что-то вроде:

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);
...