mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 04:34:15 +00:00

This is a significant reorganization of the diff code to break it into a set of more clearly distinct files and to document the new organization. Hopefully this will make the diff code easier to understand and to extend. This adds a new `git_diff_driver` object that looks of diff driver information from the attributes and the config so that things like function content in diff headers can be provided. The full driver spec is not implemented in the commit - this is focused on the reorganization of the code and putting the driver hooks in place. This also removes a few #includes from src/repository.h that were overbroad, but as a result required extra #includes in a variety of places since including src/repository.h no longer results in pulling in the whole world.
187 lines
5.7 KiB
C
187 lines
5.7 KiB
C
#include "clar_libgit2.h"
|
|
|
|
#include "fileops.h"
|
|
#include "git2/reflog.h"
|
|
#include "reflog.h"
|
|
|
|
|
|
static const char *new_ref = "refs/heads/test-reflog";
|
|
static const char *current_master_tip = "a65fedf39aefe402d3bb6e24df4d4f5fe4547750";
|
|
#define commit_msg "commit: bla bla"
|
|
|
|
static git_repository *g_repo;
|
|
|
|
|
|
// helpers
|
|
static void assert_signature(git_signature *expected, git_signature *actual)
|
|
{
|
|
cl_assert(actual);
|
|
cl_assert_equal_s(expected->name, actual->name);
|
|
cl_assert_equal_s(expected->email, actual->email);
|
|
cl_assert(expected->when.offset == actual->when.offset);
|
|
cl_assert(expected->when.time == actual->when.time);
|
|
}
|
|
|
|
|
|
// Fixture setup and teardown
|
|
void test_refs_reflog_reflog__initialize(void)
|
|
{
|
|
g_repo = cl_git_sandbox_init("testrepo.git");
|
|
}
|
|
|
|
void test_refs_reflog_reflog__cleanup(void)
|
|
{
|
|
cl_git_sandbox_cleanup();
|
|
}
|
|
|
|
void test_refs_reflog_reflog__append_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;
|
|
const git_reflog_entry *entry;
|
|
|
|
/* Create a new branch pointing at the HEAD */
|
|
git_oid_fromstr(&oid, current_master_tip);
|
|
cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &oid, 0));
|
|
|
|
cl_git_pass(git_signature_now(&committer, "foo", "foo@bar"));
|
|
|
|
cl_git_pass(git_reflog_read(&reflog, ref));
|
|
|
|
cl_git_fail(git_reflog_append(reflog, &oid, committer, "no inner\nnewline"));
|
|
cl_git_pass(git_reflog_append(reflog, &oid, committer, NULL));
|
|
cl_git_pass(git_reflog_append(reflog, &oid, committer, commit_msg "\n"));
|
|
cl_git_pass(git_reflog_write(reflog));
|
|
git_reflog_free(reflog);
|
|
|
|
/* Reopen a new instance of the repository */
|
|
cl_git_pass(git_repository_open(&repo2, "testrepo.git"));
|
|
|
|
/* Lookup the previously 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_equal_i(2, (int)git_reflog_entrycount(reflog));
|
|
|
|
entry = git_reflog_entry_byindex(reflog, 1);
|
|
assert_signature(committer, entry->committer);
|
|
cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0);
|
|
cl_assert(git_oid_cmp(&oid, &entry->oid_cur) == 0);
|
|
cl_assert(entry->msg == NULL);
|
|
|
|
entry = git_reflog_entry_byindex(reflog, 0);
|
|
assert_signature(committer, entry->committer);
|
|
cl_assert(git_oid_cmp(&oid, &entry->oid_old) == 0);
|
|
cl_assert(git_oid_cmp(&oid, &entry->oid_cur) == 0);
|
|
cl_assert_equal_s(commit_msg, entry->msg);
|
|
|
|
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_reflog__renaming_the_reference_moves_the_reflog(void)
|
|
{
|
|
git_reference *master, *new_master;
|
|
git_buf master_log_path = GIT_BUF_INIT, moved_log_path = GIT_BUF_INIT;
|
|
|
|
git_buf_joinpath(&master_log_path, git_repository_path(g_repo), GIT_REFLOG_DIR);
|
|
git_buf_puts(&moved_log_path, git_buf_cstr(&master_log_path));
|
|
git_buf_joinpath(&master_log_path, git_buf_cstr(&master_log_path), "refs/heads/master");
|
|
git_buf_joinpath(&moved_log_path, git_buf_cstr(&moved_log_path), "refs/moved");
|
|
|
|
cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&master_log_path)));
|
|
cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&moved_log_path)));
|
|
|
|
cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master"));
|
|
cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0));
|
|
git_reference_free(master);
|
|
|
|
cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&master_log_path)));
|
|
cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&moved_log_path)));
|
|
|
|
git_reference_free(new_master);
|
|
git_buf_free(&moved_log_path);
|
|
git_buf_free(&master_log_path);
|
|
}
|
|
|
|
static void assert_has_reflog(bool expected_result, const char *name)
|
|
{
|
|
git_reference *ref;
|
|
|
|
cl_git_pass(git_reference_lookup(&ref, g_repo, name));
|
|
|
|
cl_assert_equal_i(expected_result, git_reference_has_log(ref));
|
|
|
|
git_reference_free(ref);
|
|
}
|
|
|
|
void test_refs_reflog_reflog__reference_has_reflog(void)
|
|
{
|
|
assert_has_reflog(true, "HEAD");
|
|
assert_has_reflog(true, "refs/heads/master");
|
|
assert_has_reflog(false, "refs/heads/subtrees");
|
|
}
|
|
|
|
void test_refs_reflog_reflog__reading_the_reflog_from_a_reference_with_no_log_returns_an_empty_one(void)
|
|
{
|
|
git_reference *subtrees;
|
|
git_reflog *reflog;
|
|
git_buf subtrees_log_path = GIT_BUF_INIT;
|
|
|
|
cl_git_pass(git_reference_lookup(&subtrees, g_repo, "refs/heads/subtrees"));
|
|
|
|
git_buf_join_n(&subtrees_log_path, '/', 3, git_repository_path(g_repo), GIT_REFLOG_DIR, git_reference_name(subtrees));
|
|
cl_assert_equal_i(false, git_path_isfile(git_buf_cstr(&subtrees_log_path)));
|
|
|
|
cl_git_pass(git_reflog_read(&reflog, subtrees));
|
|
|
|
cl_assert_equal_i(0, (int)git_reflog_entrycount(reflog));
|
|
|
|
git_reflog_free(reflog);
|
|
git_reference_free(subtrees);
|
|
git_buf_free(&subtrees_log_path);
|
|
}
|
|
|
|
void test_refs_reflog_reflog__cannot_write_a_moved_reflog(void)
|
|
{
|
|
git_reference *master, *new_master;
|
|
git_buf master_log_path = GIT_BUF_INIT, moved_log_path = GIT_BUF_INIT;
|
|
git_reflog *reflog;
|
|
|
|
cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master"));
|
|
cl_git_pass(git_reflog_read(&reflog, master));
|
|
|
|
cl_git_pass(git_reflog_write(reflog));
|
|
|
|
cl_git_pass(git_reference_rename(&new_master, master, "refs/moved", 0));
|
|
git_reference_free(master);
|
|
|
|
cl_git_fail(git_reflog_write(reflog));
|
|
|
|
git_reflog_free(reflog);
|
|
git_reference_free(new_master);
|
|
git_buf_free(&moved_log_path);
|
|
git_buf_free(&master_log_path);
|
|
}
|
|
|
|
void test_refs_reflog_reflog__renaming_with_an_invalid_name_returns_EINVALIDSPEC(void)
|
|
{
|
|
git_reference *master;
|
|
|
|
cl_git_pass(git_reference_lookup(&master, g_repo, "refs/heads/master"));
|
|
|
|
cl_assert_equal_i(GIT_EINVALIDSPEC,
|
|
git_reflog_rename(master, "refs/heads/Inv@{id"));
|
|
|
|
git_reference_free(master);
|
|
}
|