0

I want to clone specific tag from my repository in bitbucket. Now I am able to clone just the whole repository. What should I add to my code to clone specific tag?

I have seen this but it doesnt really helped me :

https://github.com/libgit2/git2go/issues/126


git_libgit2_init();

int num = 0;

git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;

git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;

clone_opts.checkout_opts = checkout_opts;

clone_opts.fetch_opts.callbacks.credentials = cred_acquire_cb;

git_repository *cloned_repo = NULL;

int error = git_clone(&cloned_repo, all_urls.at(num).c_str(), clone_to.at(num).c_str(), &clone_opts);

if (error != 0) {

const git_error *err = giterr_last();

cerr << "error in clone num " << num << " -> message :" << err->message << endl;

}

else cout << endl << "Clone " << num << " succesful" << "(from url : " << all_urls.at(num) << " " << "to path : " << clone_to.at(num) << ")" << endl;

git_repository_free(cloned_repo);

git_libgit2_shutdown();


Thanks for your time

Martin.M
  • 191
  • 2
  • 11

1 Answers1

0

You may need to create a local repo and sync from remote-url manually.
The way to 'clone' : git init -> add remote url -> git fetch $refspec -> git reset

By using libgit2 the sample code below:


// libgit version v1.7.0 (last release version) 

// INPUT args
string git_address = "https://github.com/<org>/<repo>.git"
string branch, tag;

// start
git_repository *repo = nullptr;
git_remote   *remote = nullptr;

// create a bare local repository
git_repository_init(&repo, "/your/local/path/", false);

// set remote url
git_remote_create(&remote, repo, "origin", git_address.c_str());

// generate refspec
// http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions
std::string refspec;  // for git fetch
std::string revspec;  // for git checkout
if (branch.size()) {
    refspec = "+refs/heads/" + branch + ":refs/remotes/origin/" + branch;
    revspec = "refs/remotes/origin/" + branch;
}
if (tag.size()) {
    refspec = "+refs/tags/" + tag + ":refs/tags/" + tag;
    revspec = "refs/tags/" + tag;
}

// construct fetch_opts and run fetch
// for libgit:v1.7.0 the GIT_FETCH_OPTIONS_INIT was
// missing some field, so we must assign then manually.
char *refspec_addr[] = {refspec.data()};
git_strarray refspecs{refspec_addr, 1};

git_fetch_options fetch_opt = GIT_FETCH_OPTIONS_INIT;
fetch_opt.proxy_opts.type  = GIT_PROXY_AUTO;
fetch_opt.depth            = 1;
fetch_opt.follow_redirects = GIT_REMOTE_REDIRECT_INITIAL;
fetch_opt.custom_headers   = git_strarray{nullptr, 0};
git_remote_fetch(remote, &refspecs, &fetch_opt, NULL);

// find revision
git_object *rev;
git_revparse_single(&rev, repo, revspec.c_str());

// git checkout $branch
// git checkout tags/$tag
git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
git_reset(repo, rev, GIT_RESET_HARD, &checkout_opts);

// finally close
git_remote_free(remote);
git_repository_free(repo);

Some explanations:

  • GIT_RESET_SOFT : only move HEAD pointer inside local-repo
  • GIT_RESET_MIXED: move HEAD pointer and sync file into staged zone
  • GIT_RESET_HARD : move HEAD pointer, sync file from local-repo to staged zone and working dir

P.S. : Http proxy is supported. (in your system/user config .gitconfig)

vrqq
  • 448
  • 3
  • 8