Commit 3a728fb5 by nulltoken Committed by Carlos Martín Nieto

object: introduce git_describe_object()

parent 4cc71bb7
......@@ -19,6 +19,7 @@
#include "git2/commit.h"
#include "git2/common.h"
#include "git2/config.h"
#include "git2/describe.h"
#include "git2/diff.h"
#include "git2/errors.h"
#include "git2/filter.h"
......
......@@ -83,6 +83,8 @@ GIT_BEGIN_DECL
*/
#define GIT_OID_HEX_ZERO "0000000000000000000000000000000000000000"
#define FLAG_BITS 27
/**
* Return the version of the libgit2 library
* being currently used.
......
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_git_describe_h__
#define INCLUDE_git_describe_h__
#include "common.h"
#include "types.h"
#include "buffer.h"
/**
* @file git2/describe.h
* @brief Git describing routines
* @defgroup git_describe Git describing routines
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
typedef enum {
GIT_DESCRIBE_DEFAULT,
GIT_DESCRIBE_TAGS,
GIT_DESCRIBE_ALL,
} git_describe_strategy_t;
/**
* Describe options structure
*
* Zero out for defaults. Initialize with `GIT_DESCRIBE_OPTIONS_INIT` macro to
* correctly set the `version` field. E.g.
*
* git_describe_opts opts = GIT_DESCRIBE_OPTIONS_INIT;
*/
typedef struct git_describe_opts {
unsigned int version;
unsigned int max_candidates_tags; /** default: 10 */
unsigned int abbreviated_size;
unsigned int describe_strategy; /** default: GIT_DESCRIBE_DEFAULT */
const char *pattern;
int always_use_long_format;
int only_follow_first_parent;
int show_commit_oid_as_fallback;
} git_describe_opts;
#define GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS 10
#define GIT_DESCRIBE_DEFAULT_ABBREVIATED_SIZE 7
#define GIT_DESCRIBE_OPTIONS_VERSION 1
#define GIT_DESCRIBE_OPTIONS_INIT { \
GIT_DESCRIBE_OPTIONS_VERSION, \
GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS, \
GIT_DESCRIBE_DEFAULT_ABBREVIATED_SIZE}
GIT_EXTERN(int) git_describe_object(
git_buf *out,
git_object *committish,
git_describe_opts *opts);
/** @} */
GIT_END_DECL
#endif
......@@ -87,6 +87,7 @@ typedef enum {
GITERR_REVERT,
GITERR_CALLBACK,
GITERR_CHERRYPICK,
GITERR_DESCRIBE,
} git_error_t;
/**
......
......@@ -25,7 +25,7 @@ typedef struct git_commit_list_node {
uninteresting:1,
topo_delay:1,
parsed:1,
flags : 4;
flags : FLAG_BITS;
unsigned short in_degree;
unsigned short out_degree;
......
This diff is collapsed. Click to expand it.
......@@ -45,4 +45,7 @@ GIT_INLINE(khint_t) git_oidmap_hash(const git_oid *oid)
} } while (0)
#define git_oidmap_foreach_value kh_foreach_value
#define git_oidmap_size(h) kh_size(h)
#endif
#include "clar_libgit2.h"
#include "describe_helpers.h"
void test_describe_describe__can_describe_against_a_bare_repo(void)
{
git_repository *repo;
git_describe_opts opts = GIT_DESCRIBE_OPTIONS_INIT;
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
assert_describe("hard_tag", "HEAD", repo, &opts, false);
opts.show_commit_oid_as_fallback = 1;
assert_describe("be3563a", "HEAD^", repo, &opts, true);
git_repository_free(repo);
}
static int delete_cb(git_reference *ref, void *payload)
{
GIT_UNUSED(payload);
cl_git_pass(git_reference_delete(ref));
git_reference_free(ref);
return 0;
}
void test_describe_describe__cannot_describe_against_a_repo_with_no_ref(void)
{
git_repository *repo;
git_describe_opts opts = GIT_DESCRIBE_OPTIONS_INIT;
git_buf buf = GIT_BUF_INIT;
git_object *object;
repo = cl_git_sandbox_init("testrepo.git");
cl_git_pass(git_revparse_single(&object, repo, "HEAD"));
cl_git_pass(git_reference_foreach(repo, delete_cb, NULL));
cl_git_fail(git_describe_object(&buf, object, &opts));
git_object_free(object);
git_buf_free(&buf);
cl_git_sandbox_cleanup();
}
#include "describe_helpers.h"
void assert_describe(
const char *expected_output,
const char *revparse_spec,
git_repository *repo,
git_describe_opts *opts,
bool is_prefix_match)
{
git_object *object;
git_buf label;
cl_git_pass(git_revparse_single(&object, repo, revparse_spec));
cl_git_pass(git_describe_object(&label, object, opts));
if (is_prefix_match)
cl_assert_equal_i(0, git__prefixcmp(git_buf_cstr(&label), expected_output));
else
cl_assert_equal_s(expected_output, label);
git_object_free(object);
git_buf_free(&label);
}
#include "clar_libgit2.h"
#include "buffer.h"
extern void assert_describe(
const char *expected_output,
const char *revparse_spec,
git_repository *repo,
git_describe_opts *opts,
bool is_prefix_match);
#include "clar_libgit2.h"
#include "describe_helpers.h"
#include "repository.h"
// Ported from https://github.com/git/git/blob/adfc1857bdb090786fd9d22c1acec39371c76048/t/t6120-describe.sh
static git_repository *repo;
void test_describe_t6120__initialize(void)
{
repo = cl_git_sandbox_init("describe");
}
void test_describe_t6120__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_describe_t6120__default(void)
{
git_describe_opts opts = GIT_DESCRIBE_OPTIONS_INIT;
assert_describe("A-", "HEAD", repo, &opts, true);
assert_describe("A-", "HEAD^", repo, &opts, true);
assert_describe("R-", "HEAD^^", repo, &opts, true);
assert_describe("A-", "HEAD^^2", repo, &opts, true);
assert_describe("B", "HEAD^^2^", repo, &opts, false);
assert_describe("R-", "HEAD^^^", repo, &opts, true);
}
void test_describe_t6120__tags(void)
{
git_describe_opts opts = GIT_DESCRIBE_OPTIONS_INIT;
opts.describe_strategy = GIT_DESCRIBE_TAGS;
assert_describe("c-", "HEAD", repo, &opts, true);
assert_describe("c-", "HEAD^", repo, &opts, true);
assert_describe("e-", "HEAD^^", repo, &opts, true);
assert_describe("c-", "HEAD^^2", repo, &opts, true);
assert_describe("B", "HEAD^^2^", repo, &opts, false);
assert_describe("e", "HEAD^^^", repo, &opts, false);
}
void test_describe_t6120__all(void)
{
git_describe_opts opts = GIT_DESCRIBE_OPTIONS_INIT;
opts.describe_strategy = GIT_DESCRIBE_ALL;
assert_describe("heads/master", "HEAD", repo, &opts, false);
assert_describe("tags/c-", "HEAD^", repo, &opts, true);
assert_describe("tags/e", "HEAD^^^", repo, &opts, false);
}
void test_describe_t6120__longformat(void)
{
git_describe_opts opts = GIT_DESCRIBE_OPTIONS_INIT;
opts.always_use_long_format = 1;
assert_describe("B-0-", "HEAD^^2^", repo, &opts, true);
assert_describe("A-3-", "HEAD^^2", repo, &opts, true);
}
void test_describe_t6120__firstparent(void)
{
git_describe_opts opts = GIT_DESCRIBE_OPTIONS_INIT;
opts.describe_strategy = GIT_DESCRIBE_TAGS;
assert_describe("c-7-", "HEAD", repo, &opts, true);
opts.only_follow_first_parent = 1;
assert_describe("e-3-", "HEAD", repo, &opts, true);
}
static void commit_and_tag(
git_time_t *time,
const char *commit_msg,
const char *tag_name)
{
git_index *index;
git_oid commit_id;
git_reference *ref;
cl_git_pass(git_repository_index__weakptr(&index, repo));
cl_git_append2file("describe/file", "\n");
git_index_add_bypath(index, "describe/file");
git_index_write(index);
*time += 10;
cl_repo_commit_from_index(&commit_id, repo, NULL, *time, commit_msg);
if (tag_name == NULL)
return;
cl_git_pass(git_reference_create(&ref, repo, tag_name, &commit_id, 0, NULL, NULL));
git_reference_free(ref);
}
void test_describe_t6120__pattern(void)
{
git_describe_opts opts = GIT_DESCRIBE_OPTIONS_INIT;
git_oid tag_id;
git_object *head;
git_signature *tagger;
git_time_t time;
/* set-up matching pattern tests */
cl_git_pass(git_revparse_single(&head, repo, "HEAD"));
time = 1380553019;
cl_git_pass(git_signature_new(&tagger, "tagger", "tagger@libgit2.org", time, 0));
cl_git_pass(git_tag_create(&tag_id, repo, "test-annotated", head, tagger, "test-annotated", 0));
git_signature_free(tagger);
git_object_free(head);
commit_and_tag(&time, "one more", "refs/tags/test1-lightweight");
commit_and_tag(&time, "yet another", "refs/tags/test2-lightweight");
commit_and_tag(&time, "even more", NULL);
/* Exercize */
opts.pattern = "test-*";
assert_describe("test-annotated-", "HEAD", repo, &opts, true);
opts.describe_strategy = GIT_DESCRIBE_TAGS;
opts.pattern = "test1-*";
assert_describe("test1-lightweight-", "HEAD", repo, &opts, true);
opts.pattern = "test2-*";
assert_describe("test2-lightweight-", "HEAD", repo, &opts, true);
opts.always_use_long_format = 1;
assert_describe("test2-lightweight-", "HEAD^", repo, &opts, true);
}
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