Commit 00a48934 by Ben Straub

t10-refs.c ported.

parent dde61de6
......@@ -11,7 +11,7 @@ void test_refs_crashes__double_free(void)
cl_git_pass(git_reference_lookup(&ref2, repo, REFNAME));
cl_git_pass(git_reference_delete(ref));
/* reference is gone from disk, so reloading it will fail */
cl_must_fail(git_reference_reload(ref2));
cl_git_fail(git_reference_reload(ref2));
git_repository_free(repo);
}
#include "clar_libgit2.h"
#include "repository.h"
#include "git2/reflog.h"
#include "reflog.h"
static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
static const char *current_head_target = "refs/heads/master";
static git_repository *g_repo;
void test_ref_create__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_ref_create__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_ref_create__symbolic(void)
{
// create a new symbolic reference
git_reference *new_reference, *looked_up_ref, *resolved_ref;
git_repository *repo2;
git_oid id;
git_buf ref_path = GIT_BUF_INIT;
const char *new_head_tracker = "another-head-tracker";
git_oid_fromstr(&id, current_master_tip);
/* Retrieve the physical path to the symbolic ref for further cleaning */
cl_git_pass(git_buf_joinpath(&ref_path, g_repo->path_repository, new_head_tracker));
git_buf_free(&ref_path);
/* Create and write the new symbolic reference */
cl_git_pass(git_reference_create_symbolic(&new_reference, g_repo, new_head_tracker, current_head_target, 0));
/* Ensure the reference can be looked-up... */
cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker));
cl_assert(git_reference_type(looked_up_ref) & GIT_REF_SYMBOLIC);
cl_assert(git_reference_is_packed(looked_up_ref) == 0);
cl_assert(strcmp(looked_up_ref->name, new_head_tracker) == 0);
/* ...peeled.. */
cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref));
cl_assert(git_reference_type(resolved_ref) == GIT_REF_OID);
/* ...and that it points to the current master tip */
cl_assert(git_oid_cmp(&id, git_reference_oid(resolved_ref)) == 0);
git_reference_free(looked_up_ref);
git_reference_free(resolved_ref);
/* Similar test with a fresh new repository */
cl_git_pass(git_repository_open(&repo2, "testrepo"));
cl_git_pass(git_reference_lookup(&looked_up_ref, repo2, new_head_tracker));
cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref));
cl_assert(git_oid_cmp(&id, git_reference_oid(resolved_ref)) == 0);
git_repository_free(repo2);
git_reference_free(new_reference);
git_reference_free(looked_up_ref);
git_reference_free(resolved_ref);
}
void test_ref_create__deep_symbolic(void)
{
// create a deep symbolic reference
git_reference *new_reference, *looked_up_ref, *resolved_ref;
git_oid id;
git_buf ref_path = GIT_BUF_INIT;
const char *new_head_tracker = "deep/rooted/tracker";
git_oid_fromstr(&id, current_master_tip);
cl_git_pass(git_buf_joinpath(&ref_path, g_repo->path_repository, new_head_tracker));
cl_git_pass(git_reference_create_symbolic(&new_reference, g_repo, new_head_tracker, current_head_target, 0));
cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker));
cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref));
cl_assert(git_oid_cmp(&id, git_reference_oid(resolved_ref)) == 0);
git_reference_free(new_reference);
git_reference_free(looked_up_ref);
git_reference_free(resolved_ref);
git_buf_free(&ref_path);
}
void test_ref_create__oid(void)
{
// create a new OID reference
git_reference *new_reference, *looked_up_ref;
git_repository *repo2;
git_oid id;
git_buf ref_path = GIT_BUF_INIT;
const char *new_head = "refs/heads/new-head";
git_oid_fromstr(&id, current_master_tip);
/* Retrieve the physical path to the symbolic ref for further cleaning */
cl_git_pass(git_buf_joinpath(&ref_path, g_repo->path_repository, new_head));
/* Create and write the new object id reference */
cl_git_pass(git_reference_create_oid(&new_reference, g_repo, new_head, &id, 0));
/* Ensure the reference can be looked-up... */
cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head));
cl_assert(git_reference_type(looked_up_ref) & GIT_REF_OID);
cl_assert(git_reference_is_packed(looked_up_ref) == 0);
cl_assert(strcmp(looked_up_ref->name, new_head) == 0);
/* ...and that it points to the current master tip */
cl_assert(git_oid_cmp(&id, git_reference_oid(looked_up_ref)) == 0);
git_reference_free(looked_up_ref);
/* Similar test with a fresh new repository */
cl_git_pass(git_repository_open(&repo2, "testrepo"));
cl_git_pass(git_reference_lookup(&looked_up_ref, repo2, new_head));
cl_assert(git_oid_cmp(&id, git_reference_oid(looked_up_ref)) == 0);
git_repository_free(repo2);
git_reference_free(new_reference);
git_reference_free(looked_up_ref);
git_buf_free(&ref_path);
}
void test_ref_create__oid_unknown(void)
{
// Can not create a new OID reference which targets at an unknown id
git_reference *new_reference, *looked_up_ref;
git_oid id;
const char *new_head = "refs/heads/new-head";
git_oid_fromstr(&id, "deadbeef3f795b2b4353bcce3a527ad0a4f7f644");
/* Create and write the new object id reference */
cl_git_fail(git_reference_create_oid(&new_reference, g_repo, new_head, &id, 0));
/* Ensure the reference can't be looked-up... */
cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, new_head));
}
#include "clar_libgit2.h"
#include "repository.h"
#include "git2/reflog.h"
#include "reflog.h"
static const char *packed_test_head_name = "refs/heads/packed-test";
static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
static git_repository *g_repo;
void test_refs_delete__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_refs_delete__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_refs_delete__packed_loose(void)
{
// deleting a ref which is both packed and loose should remove both tracks in the filesystem
git_reference *looked_up_ref, *another_looked_up_ref;
git_buf temp_path = GIT_BUF_INIT;
/* Ensure the loose reference exists on the file system */
cl_git_pass(git_buf_joinpath(&temp_path, g_repo->path_repository, packed_test_head_name));
cl_git_pass(git_path_exists(temp_path.ptr));
/* Lookup the reference */
cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, packed_test_head_name));
/* Ensure it's the loose version that has been found */
cl_assert(git_reference_is_packed(looked_up_ref) == 0);
/* Now that the reference is deleted... */
cl_git_pass(git_reference_delete(looked_up_ref));
/* Looking up the reference once again should not retrieve it */
cl_git_fail(git_reference_lookup(&another_looked_up_ref, g_repo, packed_test_head_name));
/* Ensure the loose reference doesn't exist any longer on the file system */
cl_git_pass(!git_path_exists(temp_path.ptr));
git_reference_free(another_looked_up_ref);
git_buf_free(&temp_path);
}
void test_refs_delete__packed_only(void)
{
// can delete a just packed reference
git_reference *ref;
git_oid id;
const char *new_ref = "refs/heads/new_ref";
git_oid_fromstr(&id, current_master_tip);
/* Create and write the new object id reference */
cl_git_pass(git_reference_create_oid(&ref, g_repo, new_ref, &id, 0));
git_reference_free(ref);
/* Lookup the reference */
cl_git_pass(git_reference_lookup(&ref, g_repo, new_ref));
/* Ensure it's a loose reference */
cl_assert(git_reference_is_packed(ref) == 0);
/* Pack all existing references */
cl_git_pass(git_reference_packall(g_repo));
/* Reload the reference from disk */
cl_git_pass(git_reference_reload(ref));
/* Ensure it's a packed reference */
cl_assert(git_reference_is_packed(ref) == 1);
/* This should pass */
cl_git_pass(git_reference_delete(ref));
}
#include "clar_libgit2.h"
#include "repository.h"
#include "git2/reflog.h"
#include "reflog.h"
static git_repository *g_repo;
void test_refs_list__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_refs_list__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_refs_list__all(void)
{
// try to list all the references in our test repo
git_strarray ref_list;
cl_git_pass(git_reference_listall(&ref_list, g_repo, GIT_REF_LISTALL));
/*{
unsigned short i;
for (i = 0; i < ref_list.count; ++i)
printf("# %s\n", ref_list.strings[i]);
}*/
/* We have exactly 9 refs in total if we include the packed ones:
* there is a reference that exists both in the packfile and as
* loose, but we only list it once */
cl_assert(ref_list.count == 9);
git_strarray_free(&ref_list);
}
void test_refs_list__symbolic_only(void)
{
// try to list only the symbolic references
git_strarray ref_list;
cl_git_pass(git_reference_listall(&ref_list, g_repo, GIT_REF_SYMBOLIC));
cl_assert(ref_list.count == 0); /* no symrefs in the test repo */
git_strarray_free(&ref_list);
}
#include "clar_libgit2.h"
#include "repository.h"
#include "git2/reflog.h"
#include "reflog.h"
// Helpers
static int ensure_refname_normalized(int is_oid_ref, const char *input_refname, const char *expected_refname)
{
int error = GIT_SUCCESS;
char buffer_out[GIT_REFNAME_MAX];
if (is_oid_ref)
error = git_reference__normalize_name_oid(buffer_out, sizeof(buffer_out), input_refname);
else
error = git_reference__normalize_name(buffer_out, sizeof(buffer_out), input_refname);
if (error < GIT_SUCCESS)
return error;
if (expected_refname == NULL)
return error;
if (strcmp(buffer_out, expected_refname))
error = GIT_ERROR;
return error;
}
#define OID_REF 1
#define SYM_REF 0
void test_refs_normalize__direct(void)
{
// normalize a direct (OID) reference name
cl_git_fail(ensure_refname_normalized(OID_REF, "a", NULL));
cl_git_fail(ensure_refname_normalized(OID_REF, "", NULL));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads/a/", NULL));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads/a.", NULL));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads/a.lock", NULL));
cl_git_pass(ensure_refname_normalized(OID_REF, "refs/dummy/a", NULL));
cl_git_pass(ensure_refname_normalized(OID_REF, "refs/stash", NULL));
cl_git_pass(ensure_refname_normalized(OID_REF, "refs/tags/a", "refs/tags/a"));
cl_git_pass(ensure_refname_normalized(OID_REF, "refs/heads/a/b", "refs/heads/a/b"));
cl_git_pass(ensure_refname_normalized(OID_REF, "refs/heads/a./b", "refs/heads/a./b"));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads/foo?bar", NULL));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads\foo", NULL));
cl_git_pass(ensure_refname_normalized(OID_REF, "refs/heads/v@ation", "refs/heads/v@ation"));
cl_git_pass(ensure_refname_normalized(OID_REF, "refs///heads///a", "refs/heads/a"));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads/.a/b", NULL));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads/foo/../bar", NULL));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads/foo..bar", NULL));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads/./foo", NULL));
cl_git_fail(ensure_refname_normalized(OID_REF, "refs/heads/v@{ation", NULL));
}
void test_refs_normalize__symbolic(void)
{
// normalize a symbolic reference name
cl_git_pass(ensure_refname_normalized(SYM_REF, "a", "a"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "a/b", "a/b"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs///heads///a", "refs/heads/a"));
cl_git_fail(ensure_refname_normalized(SYM_REF, "", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "heads\foo", NULL));
}
/* Ported from JGit, BSD licence.
* See https://github.com/spearce/JGit/commit/e4bf8f6957bbb29362575d641d1e77a02d906739 */
void test_refs_normalize__jgit_suite(void)
{
// tests borrowed from JGit
/* EmptyString */
cl_git_fail(ensure_refname_normalized(SYM_REF, "", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "/", NULL));
/* MustHaveTwoComponents */
cl_git_fail(ensure_refname_normalized(OID_REF, "master", NULL));
cl_git_pass(ensure_refname_normalized(SYM_REF, "heads/master", "heads/master"));
/* ValidHead */
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/master", "refs/heads/master"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/pu", "refs/heads/pu"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/z", "refs/heads/z"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/FoO", "refs/heads/FoO"));
/* ValidTag */
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/tags/v1.0", "refs/tags/v1.0"));
/* NoLockSuffix */
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master.lock", NULL));
/* NoDirectorySuffix */
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master/", NULL));
/* NoSpace */
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/i haz space", NULL));
/* NoAsciiControlCharacters */
{
char c;
char buffer[GIT_REFNAME_MAX];
for (c = '\1'; c < ' '; c++) {
strncpy(buffer, "refs/heads/mast", 15);
strncpy(buffer + 15, (const char *)&c, 1);
strncpy(buffer + 16, "er", 2);
buffer[18 - 1] = '\0';
cl_git_fail(ensure_refname_normalized(SYM_REF, buffer, NULL));
}
}
/* NoBareDot */
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/.", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/..", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/./master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/../master", NULL));
/* NoLeadingOrTrailingDot */
cl_git_fail(ensure_refname_normalized(SYM_REF, ".", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/.bar", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/..bar", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/bar.", NULL));
/* ContainsDot */
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/m.a.s.t.e.r", "refs/heads/m.a.s.t.e.r"));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master..pu", NULL));
/* NoMagicRefCharacters */
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master^", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/^master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "^refs/heads/master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master~", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/~master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "~refs/heads/master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master:", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/:master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, ":refs/heads/master", NULL));
/* ShellGlob */
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master?", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/?master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "?refs/heads/master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master[", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/[master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "[refs/heads/master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master*", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/*master", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "*refs/heads/master", NULL));
/* ValidSpecialCharacters */
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/!", "refs/heads/!"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/\"", "refs/heads/\""));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/#", "refs/heads/#"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/$", "refs/heads/$"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/%", "refs/heads/%"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/&", "refs/heads/&"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/'", "refs/heads/'"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/(", "refs/heads/("));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/)", "refs/heads/)"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/+", "refs/heads/+"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/,", "refs/heads/,"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/-", "refs/heads/-"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/;", "refs/heads/;"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/<", "refs/heads/<"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/=", "refs/heads/="));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/>", "refs/heads/>"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/@", "refs/heads/@"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/]", "refs/heads/]"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/_", "refs/heads/_"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/`", "refs/heads/`"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/{", "refs/heads/{"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/|", "refs/heads/|"));
cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/}", "refs/heads/}"));
// This is valid on UNIX, but not on Windows
// hence we make in invalid due to non-portability
//
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/\\", NULL));
/* UnicodeNames */
/*
* Currently this fails.
* cl_git_pass(ensure_refname_normalized(SYM_REF, "refs/heads/\u00e5ngstr\u00f6m", "refs/heads/\u00e5ngstr\u00f6m"));
*/
/* RefLogQueryIsValidRef */
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master@{1}", NULL));
cl_git_fail(ensure_refname_normalized(SYM_REF, "refs/heads/master@{1.hour.ago}", NULL));
}
#include "clar_libgit2.h"
#include "repository.h"
#include "git2/reflog.h"
#include "reflog.h"
static const char *ref_name = "refs/heads/other";
static const char *ref_master_name = "refs/heads/master";
static const char *ref_branch_name = "refs/heads/branch";
static const char *ref_test_name = "refs/heads/test";
static git_repository *g_repo;
void test_ref_overwrite__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_ref_overwrite__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_ref_overwrite__symbolic(void)
{
// Overwrite an existing symbolic reference
git_reference *ref, *branch_ref;
/* The target needds to exist and we need to check the name has changed */
cl_git_pass(git_reference_create_symbolic(&branch_ref, g_repo, ref_branch_name, ref_master_name, 0));
cl_git_pass(git_reference_create_symbolic(&ref, g_repo, ref_name, ref_branch_name, 0));
git_reference_free(ref);
/* Ensure it points to the right place*/
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
cl_assert(git_reference_type(ref) & GIT_REF_SYMBOLIC);
cl_assert(!strcmp(git_reference_target(ref), ref_branch_name));
git_reference_free(ref);
/* Ensure we can't create it unless we force it to */
cl_git_fail(git_reference_create_symbolic(&ref, g_repo, ref_name, ref_master_name, 0));
cl_git_pass(git_reference_create_symbolic(&ref, g_repo, ref_name, ref_master_name, 1));
git_reference_free(ref);
/* Ensure it points to the right place */
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
cl_assert(git_reference_type(ref) & GIT_REF_SYMBOLIC);
cl_assert(!strcmp(git_reference_target(ref), ref_master_name));
git_reference_free(ref);
git_reference_free(branch_ref);
}
void test_ref_overwrite__object_id(void)
{
// Overwrite an existing object id reference
git_reference *ref;
git_oid id;
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
cl_assert(git_reference_type(ref) & GIT_REF_OID);
git_oid_cpy(&id, git_reference_oid(ref));
git_reference_free(ref);
/* Create it */
cl_git_pass(git_reference_create_oid(&ref, g_repo, ref_name, &id, 0));
git_reference_free(ref);
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_test_name));
cl_assert(git_reference_type(ref) & GIT_REF_OID);
git_oid_cpy(&id, git_reference_oid(ref));
git_reference_free(ref);
/* Ensure we can't overwrite unless we force it */
cl_git_fail(git_reference_create_oid(&ref, g_repo, ref_name, &id, 0));
cl_git_pass(git_reference_create_oid(&ref, g_repo, ref_name, &id, 1));
git_reference_free(ref);
/* Ensure it has been overwritten */
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
cl_assert(!git_oid_cmp(&id, git_reference_oid(ref)));
git_reference_free(ref);
}
void test_ref_overwrite__object_id_with_symbolic(void)
{
// Overwrite an existing object id reference with a symbolic one
git_reference *ref;
git_oid id;
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
cl_assert(git_reference_type(ref) & GIT_REF_OID);
git_oid_cpy(&id, git_reference_oid(ref));
git_reference_free(ref);
cl_git_pass(git_reference_create_oid(&ref, g_repo, ref_name, &id, 0));
git_reference_free(ref);
cl_git_fail(git_reference_create_symbolic(&ref, g_repo, ref_name, ref_master_name, 0));
cl_git_pass(git_reference_create_symbolic(&ref, g_repo, ref_name, ref_master_name, 1));
git_reference_free(ref);
/* Ensure it points to the right place */
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
cl_assert(git_reference_type(ref) & GIT_REF_SYMBOLIC);
cl_assert(!strcmp(git_reference_target(ref), ref_master_name));
git_reference_free(ref);
}
void test_ref_overwrite__symbolic_with_object_id(void)
{
// Overwrite an existing symbolic reference with an object id one
git_reference *ref;
git_oid id;
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
cl_assert(git_reference_type(ref) & GIT_REF_OID);
git_oid_cpy(&id, git_reference_oid(ref));
git_reference_free(ref);
/* Create the symbolic ref */
cl_git_pass(git_reference_create_symbolic(&ref, g_repo, ref_name, ref_master_name, 0));
git_reference_free(ref);
/* It shouldn't overwrite unless we tell it to */
cl_git_fail(git_reference_create_oid(&ref, g_repo, ref_name, &id, 0));
cl_git_pass(git_reference_create_oid(&ref, g_repo, ref_name, &id, 1));
git_reference_free(ref);
/* Ensure it points to the right place */
cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name));
cl_assert(git_reference_type(ref) & GIT_REF_OID);
cl_assert(!git_oid_cmp(git_reference_oid(ref), &id));
git_reference_free(ref);
}
#include "clar_libgit2.h"
#include "repository.h"
#include "git2/reflog.h"
#include "reflog.h"
static const char *loose_tag_ref_name = "refs/tags/e90810b";
static git_repository *g_repo;
void test_ref_pack__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_ref_pack__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_ref_pack__empty(void)
{
// create a packfile for an empty folder
git_buf temp_path = GIT_BUF_INIT;
cl_git_pass(git_buf_join_n(&temp_path, '/', 3, g_repo->path_repository, GIT_REFS_HEADS_DIR, "empty_dir"));
cl_git_pass(git_futils_mkdir_r(temp_path.ptr, NULL, GIT_REFS_DIR_MODE));
git_buf_free(&temp_path);
cl_git_pass(git_reference_packall(g_repo));
}
void test_ref_pack__loose(void)
{
// create a packfile from all the loose rn a repo
git_reference *reference;
git_buf temp_path = GIT_BUF_INIT;
/* Ensure a known loose ref can be looked up */
cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name));
cl_assert(git_reference_is_packed(reference) == 0);
cl_assert(strcmp(reference->name, loose_tag_ref_name) == 0);
git_reference_free(reference);
/*
* We are now trying to pack also a loose reference
* called `points_to_blob`, to make sure we can properly
* pack weak tags
*/
cl_git_pass(git_reference_packall(g_repo));
/* Ensure the packed-refs file exists */
cl_git_pass(git_buf_joinpath(&temp_path, g_repo->path_repository, GIT_PACKEDREFS_FILE));
cl_git_pass(git_path_exists(temp_path.ptr));
/* Ensure the known ref can still be looked up but is now packed */
cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name));
cl_assert(git_reference_is_packed(reference));
cl_assert(strcmp(reference->name, loose_tag_ref_name) == 0);
/* Ensure the known ref has been removed from the loose folder structure */
cl_git_pass(git_buf_joinpath(&temp_path, g_repo->path_repository, loose_tag_ref_name));
cl_git_pass(!git_path_exists(temp_path.ptr));
git_reference_free(reference);
git_buf_free(&temp_path);
}
#include "clar_libgit2.h"
#include "repository.h"
#include "git2/reflog.h"
#include "reflog.h"
static const char *loose_tag_ref_name = "refs/tags/e90810b";
static const char *non_existing_tag_ref_name = "refs/tags/i-do-not-exist";
static const char *head_tracker_sym_ref_name = "head-tracker";
static const char *current_head_target = "refs/heads/master";
static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
static const char *packed_head_name = "refs/heads/packed";
static const char *packed_test_head_name = "refs/heads/packed-test";
static git_repository *g_repo;
void test_ref_read__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_ref_read__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_ref_read__loose_tag(void)
{
// lookup a loose tag reference
git_reference *reference;
git_object *object;
git_buf ref_name_from_tag_name = GIT_BUF_INIT;
cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name));
cl_assert(git_reference_type(reference) & GIT_REF_OID);
cl_assert(git_reference_is_packed(reference) == 0);
cl_assert(strcmp(reference->name, loose_tag_ref_name) == 0);
cl_git_pass(git_object_lookup(&object, g_repo, git_reference_oid(reference), GIT_OBJ_ANY));
cl_assert(object != NULL);
cl_assert(git_object_type(object) == GIT_OBJ_TAG);
/* Ensure the name of the tag matches the name of the reference */
cl_git_pass(git_buf_joinpath(&ref_name_from_tag_name, GIT_REFS_TAGS_DIR, git_tag_name((git_tag *)object)));
cl_assert(strcmp(ref_name_from_tag_name.ptr, loose_tag_ref_name) == 0);
git_buf_free(&ref_name_from_tag_name);
git_object_free(object);
git_reference_free(reference);
}
void test_ref_read__nonexisting_tag(void)
{
// lookup a loose tag reference that doesn't exist
git_reference *reference;
cl_git_fail(git_reference_lookup(&reference, g_repo, non_existing_tag_ref_name));
git_reference_free(reference);
}
void test_ref_read__symbolic(void)
{
// lookup a symbolic reference
git_reference *reference, *resolved_ref;
git_object *object;
git_oid id;
cl_git_pass(git_reference_lookup(&reference, g_repo, GIT_HEAD_FILE));
cl_assert(git_reference_type(reference) & GIT_REF_SYMBOLIC);
cl_assert(git_reference_is_packed(reference) == 0);
cl_assert(strcmp(reference->name, GIT_HEAD_FILE) == 0);
cl_git_pass(git_reference_resolve(&resolved_ref, reference));
cl_assert(git_reference_type(resolved_ref) == GIT_REF_OID);
cl_git_pass(git_object_lookup(&object, g_repo, git_reference_oid(resolved_ref), GIT_OBJ_ANY));
cl_assert(object != NULL);
cl_assert(git_object_type(object) == GIT_OBJ_COMMIT);
git_oid_fromstr(&id, current_master_tip);
cl_assert(git_oid_cmp(&id, git_object_id(object)) == 0);
git_object_free(object);
git_reference_free(reference);
git_reference_free(resolved_ref);
}
void test_ref_read__nested_symbolic(void)
{
// lookup a nested symbolic reference
git_reference *reference, *resolved_ref;
git_object *object;
git_oid id;
cl_git_pass(git_reference_lookup(&reference, g_repo, head_tracker_sym_ref_name));
cl_assert(git_reference_type(reference) & GIT_REF_SYMBOLIC);
cl_assert(git_reference_is_packed(reference) == 0);
cl_assert(strcmp(reference->name, head_tracker_sym_ref_name) == 0);
cl_git_pass(git_reference_resolve(&resolved_ref, reference));
cl_assert(git_reference_type(resolved_ref) == GIT_REF_OID);
cl_git_pass(git_object_lookup(&object, g_repo, git_reference_oid(resolved_ref), GIT_OBJ_ANY));
cl_assert(object != NULL);
cl_assert(git_object_type(object) == GIT_OBJ_COMMIT);
git_oid_fromstr(&id, current_master_tip);
cl_assert(git_oid_cmp(&id, git_object_id(object)) == 0);
git_object_free(object);
git_reference_free(reference);
git_reference_free(resolved_ref);
}
void test_ref_read__head_then_master(void)
{
// lookup the HEAD and resolve the master branch
git_reference *reference, *resolved_ref, *comp_base_ref;
cl_git_pass(git_reference_lookup(&reference, g_repo, head_tracker_sym_ref_name));
cl_git_pass(git_reference_resolve(&comp_base_ref, reference));
git_reference_free(reference);
cl_git_pass(git_reference_lookup(&reference, g_repo, GIT_HEAD_FILE));
cl_git_pass(git_reference_resolve(&resolved_ref, reference));
cl_git_pass(git_oid_cmp(git_reference_oid(comp_base_ref), git_reference_oid(resolved_ref)));
git_reference_free(reference);
git_reference_free(resolved_ref);
cl_git_pass(git_reference_lookup(&reference, g_repo, current_head_target));
cl_git_pass(git_reference_resolve(&resolved_ref, reference));
cl_git_pass(git_oid_cmp(git_reference_oid(comp_base_ref), git_reference_oid(resolved_ref)));
git_reference_free(reference);
git_reference_free(resolved_ref);
git_reference_free(comp_base_ref);
}
void test_ref_read__master_then_head(void)
{
// lookup the master branch and then the HEAD
git_reference *reference, *master_ref, *resolved_ref;
cl_git_pass(git_reference_lookup(&master_ref, g_repo, current_head_target));
cl_git_pass(git_reference_lookup(&reference, g_repo, GIT_HEAD_FILE));
cl_git_pass(git_reference_resolve(&resolved_ref, reference));
cl_git_pass(git_oid_cmp(git_reference_oid(master_ref), git_reference_oid(resolved_ref)));
git_reference_free(reference);
git_reference_free(resolved_ref);
git_reference_free(master_ref);
}
void test_ref_read__packed(void)
{
// lookup a packed reference
git_reference *reference;
git_object *object;
cl_git_pass(git_reference_lookup(&reference, g_repo, packed_head_name));
cl_assert(git_reference_type(reference) & GIT_REF_OID);
cl_assert(git_reference_is_packed(reference));
cl_assert(strcmp(reference->name, packed_head_name) == 0);
cl_git_pass(git_object_lookup(&object, g_repo, git_reference_oid(reference), GIT_OBJ_ANY));
cl_assert(object != NULL);
cl_assert(git_object_type(object) == GIT_OBJ_COMMIT);
git_object_free(object);
git_reference_free(reference);
}
void test_ref_read__loose_first(void)
{
// assure that a loose reference is looked up before a packed reference
git_reference *reference;
cl_git_pass(git_reference_lookup(&reference, g_repo, packed_head_name));
git_reference_free(reference);
cl_git_pass(git_reference_lookup(&reference, g_repo, packed_test_head_name));
cl_assert(git_reference_type(reference) & GIT_REF_OID);
cl_assert(git_reference_is_packed(reference) == 0);
cl_assert(strcmp(reference->name, packed_test_head_name) == 0);
git_reference_free(reference);
}
#include "clar_libgit2.h"
#include "repository.h"
#include "git2/reflog.h"
#include "reflog.h"
static const char *new_ref = "refs/heads/test-reflog";
static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
static const char *commit_msg = "commit: bla bla";
static git_repository *g_repo;
// helpers
static int assert_signature(git_signature *expected, git_signature *actual)
{
if (actual == NULL)
return GIT_ERROR;
if (strcmp(expected->name, actual->name) != 0)
return GIT_ERROR;
if (strcmp(expected->email, actual->email) != 0)
return GIT_ERROR;
if (expected->when.offset != actual->when.offset)
return GIT_ERROR;
if (expected->when.time != actual->when.time)
return GIT_ERROR;
return GIT_SUCCESS;
}
// Fixture setup and teardown
void test_refs_reflog__initialize(void)
{
g_repo = cl_git_sandbox_init("testrepo");
}
void test_refs_reflog__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_refs_reflog__write_then_read(void)
{
// write a reflog for a given reference and ensure it can be read back
git_repository *repo2;
git_reference *ref, *lookedup_ref;
git_oid oid;
git_signature *committer;
git_reflog *reflog;
git_reflog_entry *entry;
char oid_str[GIT_OID_HEXSZ+1];
/* Create a new branch pointing at the HEAD */
git_oid_fromstr(&oid, current_master_tip);
cl_git_pass(git_reference_create_oid(&ref, g_repo, new_ref, &oid, 0));
git_reference_free(ref);
cl_git_pass(git_reference_lookup(&ref, g_repo, new_ref));
cl_git_pass(git_signature_now(&committer, "foo", "foo@bar"));
cl_git_pass(git_reflog_write(ref, NULL, committer, NULL));
cl_git_fail(git_reflog_write(ref, NULL, committer, "no ancestor NULL for an existing reflog"));
cl_git_fail(git_reflog_write(ref, NULL, committer, "no\nnewline"));
cl_git_pass(git_reflog_write(ref, &oid, committer, commit_msg));
/* Reopen a new instance of the repository */
cl_git_pass(git_repository_open(&repo2, "testrepo"));
/* Lookup the preivously created branch */
cl_git_pass(git_reference_lookup(&lookedup_ref, repo2, new_ref));
/* Read and parse the reflog for this branch */
cl_git_pass(git_reflog_read(&reflog, lookedup_ref));
cl_assert(reflog->entries.length == 2);
entry = (git_reflog_entry *)git_vector_get(&reflog->entries, 0);
cl_git_pass(assert_signature(committer, entry->committer));
git_oid_tostr(oid_str, GIT_OID_HEXSZ+1, &entry->oid_old);
cl_assert(strcmp("0000000000000000000000000000000000000000", oid_str) == 0);
git_oid_tostr(oid_str, GIT_OID_HEXSZ+1, &entry->oid_cur);
cl_assert(strcmp(current_master_tip, oid_str) == 0);
cl_assert(entry->msg == NULL);
entry = (git_reflog_entry *)git_vector_get(&reflog->entries, 1);
cl_git_pass(assert_signature(committer, entry->committer));
git_oid_tostr(oid_str, GIT_OID_HEXSZ+1, &entry->oid_old);
cl_assert(strcmp(current_master_tip, oid_str) == 0);
git_oid_tostr(oid_str, GIT_OID_HEXSZ+1, &entry->oid_cur);
cl_assert(strcmp(current_master_tip, oid_str) == 0);
cl_assert(strcmp(commit_msg, entry->msg) == 0);
git_signature_free(committer);
git_reflog_free(reflog);
git_repository_free(repo2);
git_reference_free(ref);
git_reference_free(lookedup_ref);
}
void test_refs_reflog__dont_write_bad(void)
{
// avoid writing an obviously wrong reflog
git_reference *ref;
git_oid oid;
git_signature *committer;
/* Create a new branch pointing at the HEAD */
git_oid_fromstr(&oid, current_master_tip);
cl_git_pass(git_reference_create_oid(&ref, g_repo, new_ref, &oid, 0));
git_reference_free(ref);
cl_git_pass(git_reference_lookup(&ref, g_repo, new_ref));
cl_git_pass(git_signature_now(&committer, "foo", "foo@bar"));
/* Write the reflog for the new branch */
cl_git_pass(git_reflog_write(ref, NULL, committer, NULL));
/* Try to update the reflog with wrong information:
* It's no new reference, so the ancestor OID cannot
* be NULL. */
cl_git_fail(git_reflog_write(ref, NULL, committer, NULL));
git_signature_free(committer);
git_reference_free(ref);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment