mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-21 14:39:10 +00:00
merge: expose multiple merge bases
We always calculate multiple merge bases, but up to now we had only exposed the "best" merge base. Introduce git_oidarray which analogously to git_strarray lets us return multiple ids.
This commit is contained in:
parent
091165c53b
commit
7db0e6ee48
@ -39,3 +39,6 @@ v0.21 + 1
|
||||
|
||||
* Add support for refspecs with the asterisk in the middle of a
|
||||
pattern.
|
||||
|
||||
* Introduce git_merge_bases() and the git_oidarray type to expose all
|
||||
merge bases between two commits.
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "common.h"
|
||||
#include "types.h"
|
||||
#include "oid.h"
|
||||
#include "oidarray.h"
|
||||
#include "checkout.h"
|
||||
#include "index.h"
|
||||
|
||||
@ -320,6 +321,21 @@ GIT_EXTERN(int) git_merge_base(
|
||||
const git_oid *one,
|
||||
const git_oid *two);
|
||||
|
||||
/**
|
||||
* Find merge bases between two commits
|
||||
*
|
||||
* @param out array in which to store the resulting ids
|
||||
* @param repo the repository where the commits exist
|
||||
* @param one one of the commits
|
||||
* @param two the other commit
|
||||
* @return 0 on success, GIT_ENOTFOUND if not found or error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_merge_bases(
|
||||
git_oidarray *out,
|
||||
git_repository *repo,
|
||||
const git_oid *one,
|
||||
const git_oid *two);
|
||||
|
||||
/**
|
||||
* Find a merge base given a list of commits
|
||||
*
|
||||
|
40
include/git2/oidarray.h
Normal file
40
include/git2/oidarray.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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_oidarray_h__
|
||||
#define INCLUDE_git_oidarray_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "oid.h"
|
||||
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/** Array of object ids */
|
||||
typedef struct git_oidarray {
|
||||
git_oid *ids;
|
||||
size_t count;
|
||||
} git_oidarray;
|
||||
|
||||
/**
|
||||
* Free the OID array
|
||||
*
|
||||
* This method must (and must only) be called on `git_oidarray`
|
||||
* objects where the array is allocated by the library. Not doing so,
|
||||
* will result in a memory leak.
|
||||
*
|
||||
* This does not free the `git_oidarray` itself, since the library will
|
||||
* never allocate that object directly itself (it is more commonly embedded
|
||||
* inside another struct or created on the stack).
|
||||
*
|
||||
* @param array git_oidarray from which to free oid data
|
||||
*/
|
||||
GIT_EXTERN(void) git_oidarray_free(git_oidarray *array);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
||||
#endif
|
||||
|
54
src/merge.c
54
src/merge.c
@ -27,6 +27,7 @@
|
||||
#include "index.h"
|
||||
#include "filebuf.h"
|
||||
#include "config.h"
|
||||
#include "oidarray.h"
|
||||
|
||||
#include "git2/types.h"
|
||||
#include "git2/repository.h"
|
||||
@ -39,6 +40,7 @@
|
||||
#include "git2/signature.h"
|
||||
#include "git2/config.h"
|
||||
#include "git2/tree.h"
|
||||
#include "git2/oidarray.h"
|
||||
#include "git2/sys/index.h"
|
||||
|
||||
#define GIT_MERGE_INDEX_ENTRY_EXISTS(X) ((X).mode != 0)
|
||||
@ -139,7 +141,7 @@ int git_merge_base_octopus(git_oid *out, git_repository *repo, size_t length, co
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_merge_base(git_oid *out, git_repository *repo, const git_oid *one, const git_oid *two)
|
||||
static int merge_bases(git_commit_list **out, git_revwalk **walk_out, git_repository *repo, const git_oid *one, const git_oid *two)
|
||||
{
|
||||
git_revwalk *walk;
|
||||
git_vector list;
|
||||
@ -173,13 +175,63 @@ int git_merge_base(git_oid *out, git_repository *repo, const git_oid *one, const
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
*out = result;
|
||||
*walk_out = walk;
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
git_revwalk_free(walk);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int git_merge_base(git_oid *out, git_repository *repo, const git_oid *one, const git_oid *two)
|
||||
{
|
||||
int error;
|
||||
git_revwalk *walk;
|
||||
git_commit_list *result;
|
||||
|
||||
if ((error = merge_bases(&result, &walk, repo, one, two)) < 0)
|
||||
return error;
|
||||
|
||||
git_oid_cpy(out, &result->item->oid);
|
||||
git_commit_list_free(&result);
|
||||
git_revwalk_free(walk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_merge_bases(git_oidarray *out, git_repository *repo, const git_oid *one, const git_oid *two)
|
||||
{
|
||||
int error;
|
||||
git_revwalk *walk;
|
||||
git_commit_list *result, *list;
|
||||
git_array_oid_t array;
|
||||
|
||||
git_array_init(array);
|
||||
|
||||
if ((error = merge_bases(&result, &walk, repo, one, two)) < 0)
|
||||
return error;
|
||||
|
||||
list = result;
|
||||
while (list) {
|
||||
git_oid *id = git_array_alloc(array);
|
||||
if (id == NULL)
|
||||
goto on_error;
|
||||
|
||||
git_oid_cpy(id, &list->item->oid);
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
git_oidarray__from_array(out, &array);
|
||||
git_commit_list_free(&result);
|
||||
git_revwalk_free(walk);
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
git_commit_list_free(&result);
|
||||
git_revwalk_free(walk);
|
||||
return -1;
|
||||
}
|
||||
|
21
src/oidarray.c
Normal file
21
src/oidarray.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "git2/oidarray.h"
|
||||
#include "oidarray.h"
|
||||
#include "array.h"
|
||||
|
||||
void git_oidarray_free(git_oidarray *arr)
|
||||
{
|
||||
git__free(arr->ids);
|
||||
}
|
||||
|
||||
void git_oidarray__from_array(git_oidarray *arr, git_array_oid_t *array)
|
||||
{
|
||||
arr->count = array->size;
|
||||
arr->ids = array->ptr;
|
||||
}
|
18
src/oidarray.h
Normal file
18
src/oidarray.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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_oidarray_h__
|
||||
#define INCLUDE_oidarray_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "git2/oidarray.h"
|
||||
#include "array.h"
|
||||
|
||||
typedef git_array_t(git_oid) git_array_oid_t;
|
||||
|
||||
extern void git_oidarray__from_array(git_oidarray *arr, git_array_oid_t *array);
|
||||
|
||||
#endif
|
@ -135,6 +135,24 @@ void test_revwalk_mergebase__prefer_youngest_merge_base(void)
|
||||
cl_assert_equal_oid(&expected, &result);
|
||||
}
|
||||
|
||||
void test_revwalk_mergebase__multiple_merge_bases(void)
|
||||
{
|
||||
git_oid one, two, expected1, expected2;
|
||||
git_oidarray result = {NULL, 0};
|
||||
|
||||
cl_git_pass(git_oid_fromstr(&one, "a4a7dce85cf63874e984719f4fdd239f5145052f "));
|
||||
cl_git_pass(git_oid_fromstr(&two, "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"));
|
||||
cl_git_pass(git_oid_fromstr(&expected1, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
|
||||
cl_git_pass(git_oid_fromstr(&expected2, "9fd738e8f7967c078dceed8190330fc8648ee56a"));
|
||||
|
||||
cl_git_pass(git_merge_bases(&result, _repo, &one, &two));
|
||||
cl_assert_equal_i(2, result.count);
|
||||
cl_assert_equal_oid(&expected1, &result.ids[0]);
|
||||
cl_assert_equal_oid(&expected2, &result.ids[1]);
|
||||
|
||||
git_oidarray_free(&result);
|
||||
}
|
||||
|
||||
void test_revwalk_mergebase__no_off_by_one_missing(void)
|
||||
{
|
||||
git_oid result, one, two;
|
||||
|
Loading…
Reference in New Issue
Block a user