Skip to content

Commit 88284df

Browse files
committed
Merge pull request libgit2#3758 from libgit2/ethomson/annotated_commit_refs
Annotated commits: differentiate between the ref names and the description
2 parents cb2dfa4 + d559237 commit 88284df

File tree

6 files changed

+127
-85
lines changed

6 files changed

+127
-85
lines changed

src/annotated_commit.c

Lines changed: 99 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -19,39 +19,102 @@
1919
#include "git2/index.h"
2020

2121
static int annotated_commit_init(
22+
git_annotated_commit **out,
23+
git_commit *commit,
24+
const char *description)
25+
{
26+
git_annotated_commit *annotated_commit;
27+
int error = 0;
28+
29+
assert(out && commit);
30+
31+
*out = NULL;
32+
33+
annotated_commit = git__calloc(1, sizeof(git_annotated_commit));
34+
GITERR_CHECK_ALLOC(annotated_commit);
35+
36+
annotated_commit->type = GIT_ANNOTATED_COMMIT_REAL;
37+
38+
if ((error = git_commit_dup(&annotated_commit->commit, commit)) < 0)
39+
goto done;
40+
41+
git_oid_fmt(annotated_commit->id_str, git_commit_id(commit));
42+
annotated_commit->id_str[GIT_OID_HEXSZ] = '\0';
43+
44+
if (!description)
45+
description = annotated_commit->id_str;
46+
47+
annotated_commit->description = git__strdup(description);
48+
GITERR_CHECK_ALLOC(annotated_commit->description);
49+
50+
done:
51+
if (!error)
52+
*out = annotated_commit;
53+
54+
return error;
55+
}
56+
57+
static int annotated_commit_init_from_id(
2258
git_annotated_commit **out,
2359
git_repository *repo,
2460
const git_oid *id,
25-
const char *ref_name,
26-
const char *remote_url)
61+
const char *description)
2762
{
28-
git_annotated_commit *annotated_commit;
2963
git_commit *commit = NULL;
3064
int error = 0;
3165

32-
assert(out && id);
66+
assert(out && repo && id);
3367

3468
*out = NULL;
3569

36-
if ((error = git_commit_lookup(&commit, repo, id)) < 0 ||
37-
(error = git_annotated_commit_from_commit(&annotated_commit,
38-
commit)) < 0)
70+
if ((error = git_commit_lookup(&commit, repo, id)) < 0)
3971
goto done;
4072

41-
if (ref_name) {
42-
annotated_commit->ref_name = git__strdup(ref_name);
43-
GITERR_CHECK_ALLOC(annotated_commit->ref_name);
44-
}
73+
error = annotated_commit_init(out, commit, description);
74+
75+
done:
76+
git_commit_free(commit);
77+
return error;
78+
}
79+
80+
int git_annotated_commit_lookup(
81+
git_annotated_commit **out,
82+
git_repository *repo,
83+
const git_oid *id)
84+
{
85+
return annotated_commit_init_from_id(out, repo, id, NULL);
86+
}
87+
88+
int git_annotated_commit_from_commit(
89+
git_annotated_commit **out,
90+
git_commit *commit)
91+
{
92+
return annotated_commit_init(out, commit, NULL);
93+
}
4594

46-
if (remote_url) {
47-
annotated_commit->remote_url = git__strdup(remote_url);
48-
GITERR_CHECK_ALLOC(annotated_commit->remote_url);
95+
int git_annotated_commit_from_revspec(
96+
git_annotated_commit **out,
97+
git_repository *repo,
98+
const char *revspec)
99+
{
100+
git_object *obj, *commit;
101+
int error;
102+
103+
assert(out && repo && revspec);
104+
105+
if ((error = git_revparse_single(&obj, repo, revspec)) < 0)
106+
return error;
107+
108+
if ((error = git_object_peel(&commit, obj, GIT_OBJ_COMMIT))) {
109+
git_object_free(obj);
110+
return error;
49111
}
50112

51-
*out = annotated_commit;
113+
error = annotated_commit_init(out, (git_commit *)commit, revspec);
114+
115+
git_object_free(obj);
116+
git_object_free(commit);
52117

53-
done:
54-
git_commit_free(commit);
55118
return error;
56119
}
57120

@@ -70,8 +133,15 @@ int git_annotated_commit_from_ref(
70133
if ((error = git_reference_resolve(&resolved, ref)) < 0)
71134
return error;
72135

73-
error = annotated_commit_init(out, repo, git_reference_target(resolved),
74-
git_reference_name(ref), NULL);
136+
error = annotated_commit_init_from_id(out,
137+
repo,
138+
git_reference_target(resolved),
139+
git_reference_name(ref));
140+
141+
if (!error) {
142+
(*out)->ref_name = git__strdup(git_reference_name(ref));
143+
GITERR_CHECK_ALLOC((*out)->ref_name);
144+
}
75145

76146
git_reference_free(resolved);
77147
return error;
@@ -97,41 +167,6 @@ int git_annotated_commit_from_head(
97167
return error;
98168
}
99169

100-
int git_annotated_commit_from_commit(
101-
git_annotated_commit **out,
102-
git_commit *commit)
103-
{
104-
git_annotated_commit *annotated_commit;
105-
106-
assert(out && commit);
107-
108-
*out = NULL;
109-
110-
annotated_commit = git__calloc(1, sizeof(git_annotated_commit));
111-
GITERR_CHECK_ALLOC(annotated_commit);
112-
113-
annotated_commit->type = GIT_ANNOTATED_COMMIT_REAL;
114-
115-
git_cached_obj_incref(commit);
116-
annotated_commit->commit = commit;
117-
118-
git_oid_fmt(annotated_commit->id_str, git_commit_id(commit));
119-
annotated_commit->id_str[GIT_OID_HEXSZ] = '\0';
120-
121-
*out = annotated_commit;
122-
return 0;
123-
}
124-
125-
int git_annotated_commit_lookup(
126-
git_annotated_commit **out,
127-
git_repository *repo,
128-
const git_oid *id)
129-
{
130-
assert(out && repo && id);
131-
132-
return annotated_commit_init(out, repo, id, NULL, NULL);
133-
}
134-
135170
int git_annotated_commit_from_fetchhead(
136171
git_annotated_commit **out,
137172
git_repository *repo,
@@ -141,33 +176,16 @@ int git_annotated_commit_from_fetchhead(
141176
{
142177
assert(repo && id && branch_name && remote_url);
143178

144-
return annotated_commit_init(out, repo, id, branch_name, remote_url);
145-
}
146-
147-
int git_annotated_commit_from_revspec(
148-
git_annotated_commit **out,
149-
git_repository *repo,
150-
const char *revspec)
151-
{
152-
git_object *obj, *commit;
153-
int error;
154-
155-
assert(out && repo && revspec);
156-
157-
if ((error = git_revparse_single(&obj, repo, revspec)) < 0)
158-
return error;
159-
160-
if ((error = git_object_peel(&commit, obj, GIT_OBJ_COMMIT))) {
161-
git_object_free(obj);
162-
return error;
163-
}
179+
if (annotated_commit_init_from_id(out, repo, id, branch_name) < 0)
180+
return -1;
164181

165-
error = annotated_commit_init(out, repo, git_object_id(commit), revspec, NULL);
182+
(*out)->ref_name = git__strdup(branch_name);
183+
GITERR_CHECK_ALLOC((*out)->ref_name);
166184

167-
git_object_free(obj);
168-
git_object_free(commit);
185+
(*out)->remote_url = git__strdup(remote_url);
186+
GITERR_CHECK_ALLOC((*out)->remote_url);
169187

170-
return error;
188+
return 0;
171189
}
172190

173191

@@ -187,8 +205,9 @@ void git_annotated_commit_free(git_annotated_commit *annotated_commit)
187205
case GIT_ANNOTATED_COMMIT_REAL:
188206
git_commit_free(annotated_commit->commit);
189207
git_tree_free(annotated_commit->tree);
190-
git__free(annotated_commit->ref_name);
191-
git__free(annotated_commit->remote_url);
208+
git__free((char *)annotated_commit->description);
209+
git__free((char *)annotated_commit->ref_name);
210+
git__free((char *)annotated_commit->remote_url);
192211
break;
193212
case GIT_ANNOTATED_COMMIT_VIRTUAL:
194213
git_index_free(annotated_commit->index);

src/annotated_commit.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ struct git_annotated_commit {
3333
git_index *index;
3434
git_array_oid_t parents;
3535

36-
char *ref_name;
37-
char *remote_url;
36+
/* how this commit was looked up */
37+
const char *description;
38+
39+
const char *ref_name;
40+
const char *remote_url;
3841

3942
char id_str[GIT_OID_HEXSZ+1];
4043
};

src/branch.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ int git_branch_create_from_annotated(
121121
const git_annotated_commit *commit,
122122
int force)
123123
{
124-
return create_branch(ref_out, repository, branch_name, commit->commit, commit->ref_name, force);
124+
return create_branch(ref_out,
125+
repository, branch_name, commit->commit, commit->description, force);
125126
}
126127

127128
int git_branch_delete(git_reference *branch)

src/repository.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2162,7 +2162,7 @@ int git_repository_set_head_detached_from_annotated(
21622162
{
21632163
assert(repo && commitish);
21642164

2165-
return detach(repo, git_annotated_commit_id(commitish), commitish->ref_name);
2165+
return detach(repo, git_annotated_commit_id(commitish), commitish->description);
21662166
}
21672167

21682168
int git_repository_detach_head(git_repository* repo)

src/reset.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,5 +195,5 @@ int git_reset_from_annotated(
195195
git_reset_t reset_type,
196196
const git_checkout_options *checkout_opts)
197197
{
198-
return reset(repo, (git_object *) commit->commit, commit->ref_name, reset_type, checkout_opts);
198+
return reset(repo, (git_object *) commit->commit, commit->description, reset_type, checkout_opts);
199199
}

tests/rebase/abort.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,25 @@ void test_rebase_abort__merge_by_id(void)
145145
git_rebase_free(rebase);
146146
}
147147

148+
void test_rebase_abort__merge_by_revspec(void)
149+
{
150+
git_rebase *rebase;
151+
git_annotated_commit *branch_head, *onto_head;
152+
153+
cl_git_pass(git_annotated_commit_from_revspec(&branch_head, repo, "b146bd7"));
154+
cl_git_pass(git_annotated_commit_from_revspec(&onto_head, repo, "efad0b1"));
155+
156+
cl_git_pass(git_rebase_init(&rebase, repo, branch_head, NULL, onto_head, NULL));
157+
cl_assert_equal_i(GIT_REPOSITORY_STATE_REBASE_MERGE, git_repository_state(repo));
158+
159+
test_abort(branch_head, onto_head);
160+
161+
git_annotated_commit_free(branch_head);
162+
git_annotated_commit_free(onto_head);
163+
164+
git_rebase_free(rebase);
165+
}
166+
148167
void test_rebase_abort__merge_by_id_immediately_after_init(void)
149168
{
150169
git_rebase *rebase;

0 commit comments

Comments
 (0)