mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-21 14:39:10 +00:00
Add git_object_short_id API to get short id string
This finds a short id string that will unambiguously select the given object, starting with the core.abbrev length (usually 7) and growing until it is no longer ambiguous.
This commit is contained in:
parent
f5753999e4
commit
13f7ecd7b9
@ -10,6 +10,7 @@
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
#include "buffer.h"
|
||||
|
||||
/**
|
||||
* @file git2/object.h
|
||||
@ -103,6 +104,15 @@ GIT_EXTERN(int) git_object_lookup_bypath(
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_object_id(const git_object *obj);
|
||||
|
||||
/**
|
||||
* Get a short abbreviated OID string for the object
|
||||
*
|
||||
* @param out Buffer to write string into
|
||||
* @param obj The object to get an ID for
|
||||
* @return 0 on success, <0 for error
|
||||
*/
|
||||
GIT_EXTERN(int) git_object_short_id(git_buf *out, const git_object *obj);
|
||||
|
||||
/**
|
||||
* Get the object type of an object
|
||||
*
|
||||
|
43
src/object.c
43
src/object.c
@ -397,3 +397,46 @@ cleanup:
|
||||
git_tree_free(tree);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_object_short_id(git_buf *out, const git_object *obj)
|
||||
{
|
||||
git_repository *repo;
|
||||
int len = GIT_ABBREV_DEFAULT, error;
|
||||
git_oid id = {{0}};
|
||||
git_odb *odb;
|
||||
|
||||
assert(out && obj);
|
||||
|
||||
git_buf_sanitize(out);
|
||||
repo = git_object_owner(obj);
|
||||
|
||||
if ((error = git_repository__cvar(&len, repo, GIT_CVAR_ABBREV)) < 0)
|
||||
return error;
|
||||
|
||||
if ((error = git_repository_odb(&odb, repo)) < 0)
|
||||
return error;
|
||||
|
||||
while (len < GIT_OID_HEXSZ) {
|
||||
/* set up short oid */
|
||||
memcpy(&id.id, &obj->cached.oid.id, (len + 1) / 2);
|
||||
if (len & 1)
|
||||
id.id[len / 2] &= 0xf0;
|
||||
|
||||
error = git_odb_exists_prefix(NULL, odb, &id, len);
|
||||
if (error != GIT_EAMBIGUOUS)
|
||||
break;
|
||||
|
||||
giterr_clear();
|
||||
len++;
|
||||
}
|
||||
|
||||
if (!error && !(error = git_buf_grow(out, len + 1))) {
|
||||
git_oid_tostr(out->ptr, len + 1, &id);
|
||||
out->size = len;
|
||||
}
|
||||
|
||||
git_odb_free(odb);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
44
tests/object/shortid.c
Normal file
44
tests/object/shortid.c
Normal file
@ -0,0 +1,44 @@
|
||||
#include "clar_libgit2.h"
|
||||
|
||||
git_repository *_repo;
|
||||
|
||||
void test_object_shortid__initialize(void)
|
||||
{
|
||||
cl_git_pass(git_repository_open(&_repo, cl_fixture("duplicate.git")));
|
||||
}
|
||||
|
||||
void test_object_shortid__cleanup(void)
|
||||
{
|
||||
git_repository_free(_repo);
|
||||
_repo = NULL;
|
||||
}
|
||||
|
||||
void test_object_shortid__select(void)
|
||||
{
|
||||
git_oid full;
|
||||
git_object *obj;
|
||||
git_buf shorty = {0};
|
||||
|
||||
git_oid_fromstr(&full, "ce013625030ba8dba906f756967f9e9ca394464a");
|
||||
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
|
||||
cl_git_pass(git_object_short_id(&shorty, obj));
|
||||
cl_assert_equal_i(7, shorty.size);
|
||||
cl_assert_equal_s("ce01362", shorty.ptr);
|
||||
git_object_free(obj);
|
||||
|
||||
git_oid_fromstr(&full, "dea509d097ce692e167dfc6a48a7a280cc5e877e");
|
||||
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
|
||||
cl_git_pass(git_object_short_id(&shorty, obj));
|
||||
cl_assert_equal_i(9, shorty.size);
|
||||
cl_assert_equal_s("dea509d09", shorty.ptr);
|
||||
git_object_free(obj);
|
||||
|
||||
git_oid_fromstr(&full, "dea509d0b3cb8ee0650f6ca210bc83f4678851ba");
|
||||
cl_git_pass(git_object_lookup(&obj, _repo, &full, GIT_OBJ_ANY));
|
||||
cl_git_pass(git_object_short_id(&shorty, obj));
|
||||
cl_assert_equal_i(9, shorty.size);
|
||||
cl_assert_equal_s("dea509d0b", shorty.ptr);
|
||||
git_object_free(obj);
|
||||
|
||||
git_buf_free(&shorty);
|
||||
}
|
Loading…
Reference in New Issue
Block a user