git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 6/7] refname_match(): Caller must declare if we're matching local or remote refs

From
Johan Herland <johan@herland.net>
Date
May 4, 2013, 23:55 UTC
Message-ID
<1367711749-8812-7-git-send-email-johan@herland.net>
In-Reply-To
<1367711749-8812-1-git-send-email-johan@herland.net>

refname_match() is used to check whether a given shorthand name matches a given full refname, but that full refname does not always belong in the local repo, rather it is sometimes taken from list of refs sent over from a remote repo.

In preparation for adding alternative ways of expanding refspecs, we need to take into account that such alternative ways may depend on local repo configuration, and it would therefore be wrong to use them when expanding refnames for a remote repo.

To resolve this, we split the ref_expand_rules list into a local and a remote variant, and teach the callers of refname_match() to pass the correct list as third argument to refname_match().

For now, the remote and local lists are identical, but this will change in a subsequent patch.

The other functions that use ref_expand_rules, all use it in a local context, so they hardcode the use of the local variant.

Signed-off-by: Johan Herland <johan@herland.net>
---
 refs.c   | 24 +++++++++++++++++-------
 refs.h   |  3 ++-
 remote.c | 15 +++++++++------
 3 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/refs.c b/refs.c
index a866489..98997c4 100644
--- a/refs.c
+++ b/refs.c
@@ -1758,7 +1758,17 @@ static char *ref_shorten_txtly(const struct ref_expand_rule *rule,
 	return xstrndup(refname + pre_len, match_len);
 }
 
-const struct ref_expand_rule ref_expand_rules[] = {
+const struct ref_expand_rule ref_expand_rules_local[] = {
+	{ ref_expand_txtly, NULL, "%.*s" },
+	{ ref_expand_txtly, ref_shorten_txtly, "refs/%.*s" },
+	{ ref_expand_txtly, ref_shorten_txtly, "refs/tags/%.*s" },
+	{ ref_expand_txtly, ref_shorten_txtly, "refs/heads/%.*s" },
+	{ ref_expand_txtly, ref_shorten_txtly, "refs/remotes/%.*s" },
+	{ ref_expand_txtly, ref_shorten_txtly, "refs/remotes/%.*s/HEAD" },
+	{ NULL, NULL, NULL }
+};
+
+const struct ref_expand_rule ref_expand_rules_remote[] = {
 	{ ref_expand_txtly, NULL, "%.*s" },
 	{ ref_expand_txtly, ref_shorten_txtly, "refs/%.*s" },
 	{ ref_expand_txtly, ref_shorten_txtly, "refs/tags/%.*s" },
@@ -1848,7 +1858,7 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
 	int refs_found = 0;
 
 	*ref = NULL;
-	for (p = ref_expand_rules; p->expand; p++) {
+	for (p = ref_expand_rules_local; p->expand; p++) {
 		char fullref[PATH_MAX];
 		unsigned char sha1_from_ref[20];
 		unsigned char *this_result;
@@ -1879,7 +1889,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
 	int logs_found = 0;
 
 	*log = NULL;
-	for (p = ref_expand_rules; p->expand; p++) {
+	for (p = ref_expand_rules_local; p->expand; p++) {
 		struct stat st;
 		unsigned char hash[20];
 		char path[PATH_MAX];
@@ -2987,11 +2997,11 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
 	int i;
 	char *short_name;
 
-	for (i = ARRAY_SIZE(ref_expand_rules) - 1; i >= 0 ; --i) {
+	for (i = ARRAY_SIZE(ref_expand_rules_local) - 1; i >= 0 ; --i) {
 		int j;
 		int rules_to_fail = i;
 		int short_name_len;
-		const struct ref_expand_rule *p = ref_expand_rules + i;
+		const struct ref_expand_rule *p = ref_expand_rules_local + i;
 
 		if (!p->shorten || !(short_name = p->shorten(p, refname)))
 			continue;
@@ -3002,14 +3012,14 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
 		 * must fail to resolve to a valid non-ambiguous ref
 		 */
 		if (strict)
-			rules_to_fail = ARRAY_SIZE(ref_expand_rules);
+			rules_to_fail = ARRAY_SIZE(ref_expand_rules_local);
 
 		/*
 		 * check if the short name resolves to a valid ref,
 		 * but use only rules prior to the matched one
 		 */
 		for (j = 0; j < rules_to_fail; j++) {
-			const struct ref_expand_rule *q = ref_expand_rules + j;
+			const struct ref_expand_rule *q = ref_expand_rules_local + j;
 			char resolved[PATH_MAX];
 
 			/* skip matched rule */
diff --git a/refs.h b/refs.h
index 245af6f..15b5ec2 100644
--- a/refs.h
+++ b/refs.h
@@ -173,7 +173,8 @@ struct ref_expand_rule {
 			 const char *refname);
 	const char *pattern;
 };
-extern const struct ref_expand_rule ref_expand_rules[];
+extern const struct ref_expand_rule ref_expand_rules_local[];
+extern const struct ref_expand_rule ref_expand_rules_remote[];
 extern int refname_match(const char *abbrev_name, const char *full_name,
 			 const struct ref_expand_rule *rules);
 
diff --git a/remote.c b/remote.c
index 5ef34c9..379577c 100644
--- a/remote.c
+++ b/remote.c
@@ -969,7 +969,8 @@ void sort_ref_list(struct ref **l, int (*cmp)(const void *, const void *))
 
 static int count_refspec_match(const char *pattern,
 			       struct ref *refs,
-			       struct ref **matched_ref)
+			       struct ref **matched_ref,
+			       int refs_from_remote)
 {
 	int patlen = strlen(pattern);
 	struct ref *matched_weak = NULL;
@@ -981,7 +982,9 @@ static int count_refspec_match(const char *pattern,
 		char *name = refs->name;
 		int namelen = strlen(name);
 
-		if (!refname_match(pattern, name, ref_expand_rules))
+		if (!refname_match(pattern, name, refs_from_remote ?
+				   ref_expand_rules_remote :
+				   ref_expand_rules_local))
 			continue;
 
 		/* A match is "weak" if it is with refs outside
@@ -1091,7 +1094,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
 		return 0;
 
 	matched_src = matched_dst = NULL;
-	switch (count_refspec_match(rs->src, src, &matched_src)) {
+	switch (count_refspec_match(rs->src, src, &matched_src, 0)) {
 	case 1:
 		copy_src = 1;
 		break;
@@ -1121,7 +1124,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
 			    matched_src->name);
 	}
 
-	switch (count_refspec_match(dst_value, dst, &matched_dst)) {
+	switch (count_refspec_match(dst_value, dst, &matched_dst, 1)) {
 	case 1:
 		break;
 	case 0:
@@ -1499,7 +1502,7 @@ int branch_merge_matches(struct branch *branch,
 {
 	if (!branch || i < 0 || i >= branch->merge_nr)
 		return 0;
-	return refname_match(branch->merge[i]->src, refname, ref_expand_rules);
+	return refname_match(branch->merge[i]->src, refname, ref_expand_rules_local);
 }
 
 static int ignore_symref_update(const char *refname)
@@ -1545,7 +1548,7 @@ static const struct ref *find_ref_by_name_abbrev(const struct ref *refs, const c
 {
 	const struct ref *ref;
 	for (ref = refs; ref; ref = ref->next) {
-		if (refname_match(name, ref->name, ref_expand_rules))
+		if (refname_match(name, ref->name, ref_expand_rules_remote))
 			return ref;
 	}
 	return NULL;
-- 
1.8.1.3.704.g33f7d4f
Previous: Junio C HamanoNext: Junio C Hamano
Message 24 of 39 in “Make "$remote/$branch" work with unconventional refspecs”
  1. 0/7 Make "$remote/$branch" work with unconventional refspecsJohan Herland, May 4, 2013
  2. 1/7 shorten_unambiguous_ref(): Allow shortening refs/remotes/origin/HEAD to originJohan Herland, May 4, 2013
  3. Bert WesargMay 5, 2013
  4. Junio C HamanoMay 6, 2013
  5. Johan HerlandMay 7, 2013
  6. 1/3 t1514: Add tests of shortening refnames in strict/loose modeJohan Herland, May 7, 2013
  7. 2/3 t1514: Demonstrate failure to correctly shorten "refs/remotes/origin/HEAD"Johan Herland, May 7, 2013
  8. 3/3 shorten_unambiguous_ref(): Fix shortening refs/remotes/origin/HEAD to originJohan Herland, May 7, 2013
  9. Junio C HamanoMay 7, 2013
  10. Junio C HamanoMay 7, 2013
  11. Johan HerlandMay 7, 2013
  12. Junio C HamanoMay 7, 2013
  13. Johan HerlandMay 7, 2013
  14. 2/7 t7900: Start testing usability of namespaced remote refsJohan Herland, May 4, 2013
  15. Junio C HamanoMay 7, 2013
  16. Johan HerlandMay 7, 2013
  17. Junio C HamanoMay 7, 2013
  18. 3/7 t7900: Demonstrate failure to expand "$remote/$branch" according to refspecsJohan Herland, May 4, 2013
  19. Junio C HamanoMay 7, 2013
  20. 4/7 refs.c: Refactor rules for expanding shorthand names into full refnamesJohan Herland, May 4, 2013
  21. Junio C HamanoMay 7, 2013
  22. 5/7 refs.c: Refactor code for shortening full refnames into shorthand namesJohan Herland, May 4, 2013
  23. Junio C HamanoMay 7, 2013
  24. 6/7 refname_match(): Caller must declare if we're matching local or remote refsJohan Herland, May 4, 2013
  25. Junio C HamanoMay 7, 2013
  26. 7/7 refs.c: Add rules for resolving refs using remote refspecsJohan Herland, May 4, 2013
  27. Junio C HamanoMay 5, 2013
  28. Johan HerlandMay 5, 2013
  29. Junio C HamanoMay 5, 2013
  30. Johan HerlandMay 5, 2013
  31. Junio C HamanoMay 5, 2013
  32. Santi BéjarMay 6, 2013
  33. Santi BéjarMay 6, 2013
  34. Junio C HamanoMay 6, 2013
  35. Santi BéjarMay 6, 2013
  36. Junio C HamanoMay 6, 2013
  37. Junio C HamanoMay 6, 2013
  38. Johan HerlandMay 6, 2013
  39. Junio C HamanoMay 7, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.