Skip to content

Commit

Permalink
Fixed build issue with old versions of libgit2
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Koefferlein committed Oct 28, 2023
1 parent 2e16a1e commit ba19b33
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 48 deletions.
117 changes: 69 additions & 48 deletions src/tl/tl/tlGit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,72 +153,93 @@ ref_matches (const char *name, const std::string &ref)
}
}

static void
checkout_branch (git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch)
namespace
{
git_buf remote_branch = GIT_BUF_INIT_CONST (NULL, 0);

try {
class GitBuffer
{
public:
GitBuffer ()
{
m_buf = GIT_BUF_INIT_CONST (NULL, 0);
}

git_oid oid;
~GitBuffer ()
{
#if LIBGIT2_VER_MAJOR > 0 || (LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR >= 28)
git_buf_dispose (&m_buf);
#else
git_buf_free (&m_buf);
#endif
}

// if no branch is given, use the default branch
if (! branch) {
check (git_remote_default_branch (&remote_branch, remote));
branch = remote_branch.ptr;
if (tl::verbosity () >= 10) {
tl::info << tr ("Git checkout: Using default branch for repository ") << git_remote_url (remote) << ": " << branch;
}
} else {
if (tl::verbosity () >= 10) {
tl::info << tr ("Git checkout: Checking out branch for repository ") << git_remote_url (remote) << ": " << branch;
}
}
const char *c_str () const { return m_buf.ptr; }

// resolve the branch by using ls-remote:
git_buf *get () { return &m_buf; }
const git_buf *get () const { return &m_buf; }

size_t n = 0;
const git_remote_head **ls = NULL;
check (git_remote_ls (&ls, &n, remote));
private:
git_buf m_buf;
};

if (tl::verbosity () >= 20) {
tl::info << "Git checkout: ls-remote on " << git_remote_url (remote) << ":";
}
}

bool found = false;
static void
checkout_branch (git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch)
{
GitBuffer remote_branch;
git_oid oid;

for (size_t i = 0; i < n; ++i) {
const git_remote_head *rh = ls[i];
if (tl::verbosity () >= 20) {
char oid_fmt [80];
git_oid_tostr (oid_fmt, sizeof (oid_fmt), &rh->oid);
tl::info << " " << rh->name << ": " << (const char *) oid_fmt;
}
if (ref_matches (rh->name, branch)) {
oid = rh->oid;
found = true;
}
// if no branch is given, use the default branch
if (! branch) {
check (git_remote_default_branch (remote_branch.get (), remote));
branch = remote_branch.c_str ();
if (tl::verbosity () >= 10) {
tl::info << tr ("Git checkout: Using default branch for repository ") << git_remote_url (remote) << ": " << branch;
}

if (! found) {
throw tl::Exception (tl::to_string (tr ("Git checkout - Unable to resolve reference name: ")) + branch);
} else {
if (tl::verbosity () >= 10) {
tl::info << tr ("Git checkout: Checking out branch for repository ") << git_remote_url (remote) << ": " << branch;
}
}

if (tl::verbosity () >= 10) {
// resolve the branch by using ls-remote:

size_t n = 0;
const git_remote_head **ls = NULL;
check (git_remote_ls (&ls, &n, remote));

if (tl::verbosity () >= 20) {
tl::info << "Git checkout: ls-remote on " << git_remote_url (remote) << ":";
}

bool found = false;

for (size_t i = 0; i < n; ++i) {
const git_remote_head *rh = ls[i];
if (tl::verbosity () >= 20) {
char oid_fmt [80];
git_oid_tostr (oid_fmt, sizeof (oid_fmt), &oid);
tl::info << tr ("Git checkout: resolving ") << branch << tr (" to ") << (const char *) oid_fmt;
git_oid_tostr (oid_fmt, sizeof (oid_fmt), &rh->oid);
tl::info << " " << rh->name << ": " << (const char *) oid_fmt;
}
if (ref_matches (rh->name, branch)) {
oid = rh->oid;
found = true;
}
}

check (git_repository_set_head_detached (repo, &oid));
check (git_checkout_head (repo, co_opts));
if (! found) {
throw tl::Exception (tl::to_string (tr ("Git checkout - Unable to resolve reference name: ")) + branch);
}

} catch (...) {
git_buf_dispose (&remote_branch);
throw;
if (tl::verbosity () >= 10) {
char oid_fmt [80];
git_oid_tostr (oid_fmt, sizeof (oid_fmt), &oid);
tl::info << tr ("Git checkout: resolving ") << branch << tr (" to ") << (const char *) oid_fmt;
}

git_buf_dispose (&remote_branch);
check (git_repository_set_head_detached (repo, &oid));
check (git_checkout_head (repo, co_opts));
}

void
Expand Down
3 changes: 3 additions & 0 deletions src/tl/tl/tlGit.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class TL_PUBLIC GitObject
*
* This method throws an exception if the directory structure could
* not be obtained or downloading of one file failed.
*
* "branch" is the remote ref to use. This can be a branch name, a tag name,
* a remote ref such as "refs/heads/master" or a symbolic name such as "HEAD".
*/
static bool download (const std::string &url, const std::string &target, const std::string &branch, double timeout = 60.0, tl::InputHttpStreamCallback *callback = 0);

Expand Down

0 comments on commit ba19b33

Please sign in to comment.