/** * We still need to fail if part of the namespace is * still in use. */ void test_refs_branches_create__name_vs_namespace_fail(void) { const char * name; struct item { const char *first; const char *first_alternate; const char *second; }; static const struct item item[] = { { "level_one/level_two", "level_one/alternate", "level_one" }, { "a/b/c/d/e", "a/b/c/d/alternate", "a/b/c/d" }, { "ss/tt/uu/vv/ww", "ss/alternate", "ss" }, { NULL, NULL, NULL }, }; const struct item *p; retrieve_known_commit(&target, repo); for (p=item; p->first; p++) { cl_git_pass(git_branch_create(&branch, repo, p->first, target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); cl_git_pass(git_branch_name(&name, branch)); cl_assert_equal_s(name, p->first); cl_git_pass(git_branch_delete(branch)); git_reference_free(branch); branch = NULL; cl_git_pass(git_branch_create(&branch, repo, p->first_alternate, target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); cl_git_pass(git_branch_name(&name, branch)); cl_assert_equal_s(name, p->first_alternate); /* we do not delete the alternate. */ git_reference_free(branch); branch = NULL; cl_git_fail(git_branch_create(&branch, repo, p->second, target, 0, NULL, NULL)); git_reference_free(branch); branch = NULL; } }
int Branch_upstream__set__(Branch *self, Reference *py_ref) { int err; const char *branch_name = NULL; CHECK_REFERENCE_INT(self); if ((PyObject *)py_ref != Py_None) { if (!PyObject_TypeCheck(py_ref, (PyTypeObject *)&ReferenceType)) { PyErr_SetObject(PyExc_TypeError, (PyObject *)py_ref); return -1; } CHECK_REFERENCE_INT(py_ref); err = git_branch_name(&branch_name, py_ref->reference); if (err < GIT_OK) { Error_set(err); return -1; } } err = git_branch_set_upstream(self->reference, branch_name); if (err < GIT_OK) { Error_set(err); return -1; } return 0; }
/** * Verify that we can create a branch with a name that matches the * namespace of a previously delete branch. * * git branch level_one/level_two * git branch -D level_one/level_two * git branch level_one * * We expect the delete to have deleted the files: * ".git/refs/heads/level_one/level_two" * ".git/logs/refs/heads/level_one/level_two" * It may or may not have deleted the (now empty) * containing directories. To match git.git behavior, * the second create needs to implicilty delete the * directories and create the new files. * "refs/heads/level_one" * "logs/refs/heads/level_one" * * We should not fail to create the branch or its * reflog because of an obsolete namespace container * directory. */ void test_refs_branches_create__name_vs_namespace(void) { const char * name; struct item { const char *first; const char *second; }; static const struct item item[] = { { "level_one/level_two", "level_one" }, { "a/b/c/d/e", "a/b/c/d" }, { "ss/tt/uu/vv/ww", "ss" }, /* And one test case that is deeper. */ { "xx1/xx2/xx3/xx4", "xx1/xx2/xx3/xx4/xx5/xx6" }, { NULL, NULL }, }; const struct item *p; retrieve_known_commit(&target, repo); for (p=item; p->first; p++) { cl_git_pass(git_branch_create(&branch, repo, p->first, target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp(git_reference_target(branch), git_commit_id(target))); cl_git_pass(git_branch_name(&name, branch)); cl_assert_equal_s(name, p->first); cl_git_pass(git_branch_delete(branch)); git_reference_free(branch); branch = NULL; cl_git_pass(git_branch_create(&branch, repo, p->second, target, 0, NULL, NULL)); git_reference_free(branch); branch = NULL; } }
/* * call-seq: * branch.upstream = branch * * Set the upstream configuration for a given local branch. * * Takes a local or remote Rugged::Branch instance or a Rugged::Reference * pointing to a branch. */ static VALUE rb_git_branch_set_upstream(VALUE self, VALUE rb_branch) { git_reference *branch, *target_branch; const char *target_branch_name; Data_Get_Struct(self, git_reference, branch); if (!NIL_P(rb_branch)) { if (!rb_obj_is_kind_of(rb_branch, rb_cRuggedReference)) rb_raise(rb_eTypeError, "Expecting a Rugged::Reference instance"); Data_Get_Struct(rb_branch, git_reference, target_branch); rugged_exception_check( git_branch_name(&target_branch_name, target_branch) ); } else { target_branch_name = NULL; } rugged_exception_check( git_branch_set_upstream(branch, target_branch_name) ); return rb_branch; }
/* * call-seq: * branch.name -> string * * Returns the name of +branch+. * * See Rugged::Reference#canonical_name if you need the fully qualified * name of the underlying reference. */ static VALUE rb_git_branch_name(VALUE self) { git_reference *branch; const char *branch_name; Data_Get_Struct(self, git_reference, branch); rugged_exception_check(git_branch_name(&branch_name, branch)); return rb_str_new_utf8(branch_name); }
PyObject* Branch_branch_name__get__(Branch *self) { int err; const char *c_name; CHECK_REFERENCE(self); err = git_branch_name(&c_name, self->reference); if (err == GIT_OK) return to_unicode(c_name, NULL, NULL); else return Error_set(err); }
void QGit::currentBranch() { git_repository *repo = nullptr; git_reference *ref = nullptr; const char *branch = nullptr; int res = 0; QGitError error; QString name; try { res = git_repository_open(&repo, m_path.absolutePath().toUtf8().constData()); if (res) { throw QGitError("git_repository_open", res); } res = git_repository_head(&ref, repo); if (res) { throw QGitError("git_repository_head", res); } res = git_branch_name(&branch, ref); if (res) { throw QGitError("git_branch_name", res); } name = branch; } catch(const QGitError &ex) { error = ex; } emit currentBranchReply(name, error); if (ref) { git_reference_free(ref); ref = nullptr; } if (repo) { git_repository_free(repo); repo = nullptr; } }
QString QGit::getBranchNameFromPath(const QString &path) { git_repository *repo = nullptr; git_reference *ref = nullptr; int result = 0; const char *branch = nullptr; QString ret; git_libgit2_init(); result = git_repository_open(&repo, path.toUtf8().constData()); if (result) { goto cleanup; } result = git_repository_head(&ref, repo); if (result) { goto cleanup; } git_branch_name(&branch, ref); ret = branch; cleanup: if (ref) { git_reference_free(ref); ref = nullptr; } if (repo) { git_repository_free(repo); repo = nullptr; } git_libgit2_shutdown(); return ret; }
/** * ggit_branch_get_name: * @branch: a #GgitBranch. * @error: a #GError for error reporting, or %NULL. * * Gets the name of the given local or remote branch. * * Returns: the name of the given local or remote branch. */ const gchar * ggit_branch_get_name (GgitBranch *branch, GError **error) { const gchar *out; gint ret; g_return_val_if_fail (GGIT_IS_BRANCH (branch), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); ret = git_branch_name (&out, _ggit_native_get (branch)); if (ret != GIT_OK) { _ggit_error_set (error, ret); return NULL; } return out; }
void test_refs_branches_create__can_create_branch_with_unicode(void) { const char *nfc = "\xC3\x85\x73\x74\x72\xC3\xB6\x6D"; const char *nfd = "\x41\xCC\x8A\x73\x74\x72\x6F\xCC\x88\x6D"; const char *emoji = "\xF0\x9F\x8D\xB7"; const char *names[] = { nfc, nfd, emoji }; const char *alt[] = { nfd, nfc, NULL }; const char *expected[] = { nfc, nfd, emoji }; unsigned int i; bool fs_decompose_unicode = git_path_does_fs_decompose_unicode(git_repository_path(repo)); retrieve_known_commit(&target, repo); if (cl_repo_get_bool(repo, "core.precomposeunicode")) expected[1] = nfc; /* test decomp. because not all Mac filesystems decompose unicode */ else if (fs_decompose_unicode) expected[0] = nfd; for (i = 0; i < ARRAY_SIZE(names); ++i) { const char *name; cl_git_pass(git_branch_create( &branch, repo, names[i], target, 0, NULL, NULL)); cl_git_pass(git_oid_cmp( git_reference_target(branch), git_commit_id(target))); cl_git_pass(git_branch_name(&name, branch)); cl_assert_equal_s(expected[i], name); assert_branch_matches_name(expected[i], names[i]); if (fs_decompose_unicode && alt[i]) assert_branch_matches_name(expected[i], alt[i]); cl_git_pass(git_branch_delete(branch)); git_reference_free(branch); branch = NULL; } }
static void checkout(git_repository *repo) { git_reference *master_ref, *remote_ref, *HEAD_ref, *tmpr; git_checkout_options co_opts; const char *remote_br_name; git_commit *remote_commit; git_object *remote_obj; char *remotebr; int rc; remotebr = NULL; xasprintf(&remotebr, "refs/remotes/%s/%s", option_origin, option_trunk); rc = git_reference_lookup(&remote_ref, repo, remotebr); if (rc) die("git_reference_lookup(%s): %d", remotebr, rc); rc = git_branch_name(&remote_br_name, remote_ref); if (rc) die("git_branch_name: %d", rc); rc = git_reference_peel(&remote_obj, remote_ref, GIT_OBJ_COMMIT); if (rc) die("git_reference_peel"); rc = git_commit_lookup(&remote_commit, repo, git_object_id(remote_obj)); if (rc) die("git_commit_lookup"); rc = git_branch_create(&master_ref, repo, "master", remote_commit, false, NULL, NULL); if (rc) die("git_branch_create: %d", rc); rc = git_reference_symbolic_create(&HEAD_ref, repo, "HEAD", "refs/heads/master", false, NULL, NULL); if (rc && rc != GIT_EEXISTS) die("git_reference_symbolic_create: %d", rc); rc = git_branch_set_upstream(master_ref, remote_br_name); if (rc) /* TODO: '' is not a valid remote name */ #if 0 die("git_branch_set_upstream: %d (%d/%s)", rc, giterr_last()->klass, giterr_last()->message); #else printf("XXXgit_branch_set_upstream: %d (%d/%s)\n", rc, giterr_last()->klass, giterr_last()->message); #endif rc = git_reference_lookup(&tmpr, repo, "refs/heads/master"); if (rc) die("%s: reference_lookup: master doesn't exist?", __func__); if (git_reference_cmp(tmpr, master_ref) != 0) die("mismatched master"); co_opts = (git_checkout_options) GIT_CHECKOUT_OPTIONS_INIT; co_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; rc = git_checkout_head(repo, &co_opts); if (rc) die("git_checkout_head"); free(remotebr); git_commit_free(remote_commit); git_object_free(remote_obj); git_reference_free(tmpr); git_reference_free(HEAD_ref); git_reference_free(master_ref); git_reference_free(remote_ref); }
std::string Branch::name() const { const char *out; Exception::git2_assert(git_branch_name(&out, data())); return std::string(out); }