Skip to content

Commit b895547

Browse files
committed
refs: replace reimplementation of reference resolver
The refs code currently has a second implementation that resolves references in order to find any final symbolic reference pointing to a nonexistent target branch. As we've just extended `git_refdb_resolve` to also return such references, let's use that one instead in order to reduce code duplication.
1 parent cf7dd05 commit b895547

File tree

1 file changed

+18
-49
lines changed

1 file changed

+18
-49
lines changed

src/refs.c

Lines changed: 18 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727

2828
bool git_reference__enable_symbolic_ref_target_validation = true;
2929

30-
#define DEFAULT_NESTING_LEVEL 5
31-
#define MAX_NESTING_LEVEL 10
32-
3330
enum {
3431
GIT_PACKREF_HAS_PEEL = 1,
3532
GIT_PACKREF_WAS_LOOSE = 2
@@ -1131,40 +1128,6 @@ int git_reference_cmp(
11311128
return git_oid__cmp(&ref1->target.oid, &ref2->target.oid);
11321129
}
11331130

1134-
/**
1135-
* Get the end of a chain of references. If the final one is not
1136-
* found, we return the reference just before that.
1137-
*/
1138-
static int get_terminal(git_reference **out, git_repository *repo, const char *ref_name, int nesting)
1139-
{
1140-
git_reference *ref;
1141-
int error = 0;
1142-
1143-
if (nesting > MAX_NESTING_LEVEL) {
1144-
git_error_set(GIT_ERROR_REFERENCE, "reference chain too deep (%d)", nesting);
1145-
return GIT_ENOTFOUND;
1146-
}
1147-
1148-
/* set to NULL to let the caller know that they're at the end of the chain */
1149-
if ((error = git_reference_lookup(&ref, repo, ref_name)) < 0) {
1150-
*out = NULL;
1151-
return error;
1152-
}
1153-
1154-
if (git_reference_type(ref) == GIT_REFERENCE_DIRECT) {
1155-
*out = ref;
1156-
error = 0;
1157-
} else {
1158-
error = get_terminal(out, repo, git_reference_symbolic_target(ref), nesting + 1);
1159-
if (error == GIT_ENOTFOUND && !*out)
1160-
*out = ref;
1161-
else
1162-
git_reference_free(ref);
1163-
}
1164-
1165-
return error;
1166-
}
1167-
11681131
/*
11691132
* Starting with the reference given by `ref_name`, follows symbolic
11701133
* references until a direct reference is found and updated the OID
@@ -1179,31 +1142,37 @@ int git_reference__update_terminal(
11791142
{
11801143
git_reference *ref = NULL, *ref2 = NULL;
11811144
git_signature *who = NULL;
1145+
git_refdb *refdb = NULL;
11821146
const git_signature *to_use;
11831147
int error = 0;
11841148

11851149
if (!sig && (error = git_reference__log_signature(&who, repo)) < 0)
1186-
return error;
1150+
goto out;
11871151

11881152
to_use = sig ? sig : who;
1189-
error = get_terminal(&ref, repo, ref_name, 0);
11901153

1191-
/* found a dangling symref */
1192-
if (error == GIT_ENOTFOUND && ref) {
1193-
assert(git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC);
1194-
git_error_clear();
1154+
if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0)
1155+
goto out;
1156+
1157+
if ((error = git_refdb_resolve(&ref, refdb, ref_name, -1)) < 0) {
1158+
if (error == GIT_ENOTFOUND) {
1159+
git_error_clear();
1160+
error = reference__create(&ref2, repo, ref_name, oid, NULL, 0, to_use,
1161+
log_message, NULL, NULL);
1162+
}
1163+
goto out;
1164+
}
1165+
1166+
/* In case the resolved reference is symbolic, then it's a dangling symref. */
1167+
if (git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC) {
11951168
error = reference__create(&ref2, repo, ref->target.symbolic, oid, NULL, 0, to_use,
11961169
log_message, NULL, NULL);
1197-
} else if (error == GIT_ENOTFOUND) {
1198-
git_error_clear();
1199-
error = reference__create(&ref2, repo, ref_name, oid, NULL, 0, to_use,
1200-
log_message, NULL, NULL);
1201-
} else if (error == 0) {
1202-
assert(git_reference_type(ref) == GIT_REFERENCE_DIRECT);
1170+
} else {
12031171
error = reference__create(&ref2, repo, ref->name, oid, NULL, 1, to_use,
12041172
log_message, &ref->target.oid, NULL);
12051173
}
12061174

1175+
out:
12071176
git_reference_free(ref2);
12081177
git_reference_free(ref);
12091178
git_signature_free(who);

0 commit comments

Comments
 (0)