Skip to content

Commit e849aa8

Browse files
committed
repository: start recognizing the current state
Recognize when we're merging, reverting or doing a cherry-pick, which we need if we want to generate message templates for merging et al.
1 parent 31637cd commit e849aa8

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

include/git2/repository.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,15 @@ GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo);
302302
*/
303303
GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index);
304304

305+
typedef enum {
306+
GIT_REPOSITORY_STATE_NONE,
307+
GIT_REPOSITORY_STATE_MERGE,
308+
GIT_REPOSITORY_STATE_REVERT,
309+
GIT_REPOSITORY_STATE_CHERRY_PICK,
310+
} git_repository_state_t;
311+
312+
GIT_EXTERN(int) git_repository_state(git_repository *repo);
313+
305314
/** @} */
306315
GIT_END_DECL
307316
#endif

src/refs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#define GIT_HEAD_FILE "HEAD"
3030
#define GIT_FETCH_HEAD_FILE "FETCH_HEAD"
3131
#define GIT_MERGE_HEAD_FILE "MERGE_HEAD"
32+
#define GIT_REVERT_HEAD_FILE "REVERT_HEAD"
33+
#define GIT_CHERRY_PICK_HEAD_FILE "CHERRY_PICK_HEAD"
3234
#define GIT_REFS_HEADS_MASTER_FILE GIT_REFS_HEADS_DIR "master"
3335

3436
#define GIT_REFNAME_MAX 1024

src/repository.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,3 +1058,35 @@ int git_repository_head_tree(git_tree **tree, git_repository *repo)
10581058
*tree = (git_tree *)obj;
10591059
return 0;
10601060
}
1061+
1062+
int git_repository_state(git_repository *repo)
1063+
{
1064+
git_buf path = GIT_BUF_INIT;
1065+
1066+
if (git_buf_joinpath(&path, repo->path_repository, GIT_MERGE_HEAD_FILE) < 0)
1067+
return -1;
1068+
1069+
if (git_path_exists(git_buf_cstr(&path))) {
1070+
git_buf_free(&path);
1071+
return GIT_REPOSITORY_STATE_MERGE;
1072+
}
1073+
1074+
if (git_buf_joinpath(&path, repo->path_repository, GIT_REVERT_HEAD_FILE) < 0)
1075+
return -1;
1076+
1077+
if (git_path_exists(git_buf_cstr(&path))) {
1078+
git_buf_free(&path);
1079+
return GIT_REPOSITORY_STATE_REVERT;
1080+
}
1081+
1082+
if (git_buf_joinpath(&path, repo->path_repository, GIT_CHERRY_PICK_HEAD_FILE) < 0)
1083+
return -1;
1084+
1085+
if (git_path_exists(git_buf_cstr(&path))) {
1086+
git_buf_free(&path);
1087+
return GIT_REPOSITORY_STATE_CHERRY_PICK;
1088+
}
1089+
1090+
git_buf_free(&path);
1091+
return GIT_REPOSITORY_STATE_NONE;
1092+
}

tests-clar/repo/state.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "clar_libgit2.h"
2+
#include "buffer.h"
3+
#include "refs.h"
4+
#include "posix.h"
5+
6+
static git_repository *_repo;
7+
static git_buf _path;
8+
9+
void test_repo_state__initialize(void)
10+
{
11+
_repo = cl_git_sandbox_init("testrepo.git");
12+
}
13+
14+
void test_repo_state__cleanup(void)
15+
{
16+
cl_git_sandbox_cleanup();
17+
git_buf_free(&_path);
18+
}
19+
20+
void test_repo_state__none(void)
21+
{
22+
/* The repo should be at its default state */
23+
cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(_repo));
24+
}
25+
26+
void test_repo_state__merge(void)
27+
{
28+
29+
/* Then it should recognise that .git/MERGE_HEAD and friends mean their respective states */
30+
cl_git_pass(git_buf_joinpath(&_path, git_repository_path(_repo), GIT_MERGE_HEAD_FILE));
31+
cl_git_mkfile(git_buf_cstr(&_path), "dummy");
32+
cl_assert_equal_i(GIT_REPOSITORY_STATE_MERGE, git_repository_state(_repo));
33+
}
34+
35+
void test_repo_state__revert(void)
36+
{
37+
cl_git_pass(git_buf_joinpath(&_path, git_repository_path(_repo), GIT_REVERT_HEAD_FILE));
38+
cl_git_mkfile(git_buf_cstr(&_path), "dummy");
39+
cl_assert_equal_i(GIT_REPOSITORY_STATE_REVERT, git_repository_state(_repo));
40+
}
41+
42+
void test_repo_state__cherry_pick(void)
43+
{
44+
cl_git_pass(git_buf_joinpath(&_path, git_repository_path(_repo), GIT_CHERRY_PICK_HEAD_FILE));
45+
cl_git_mkfile(git_buf_cstr(&_path), "dummy");
46+
cl_assert_equal_i(GIT_REPOSITORY_STATE_CHERRY_PICK, git_repository_state(_repo));
47+
}

0 commit comments

Comments
 (0)