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

[RFD/PATCH 4/5] branch.c: Look up refspecs to validate tracking branches

From
Johan Herland <johan@herland.net>
Date
Apr 19, 2013, 06:20 UTC
Message-ID
<1366352442-501-5-git-send-email-johan@herland.net>
In-Reply-To
<1366352442-501-1-git-send-email-johan@herland.net>

The current code for validating tracking branches (e.g. the argument to the -t/--track option) hardcodes refs/heads/* and refs/remotes/* as the potential locations for tracking branches. This works well with the conventional refspecs created by "git clone" or "git remote add", but does not work if the user tweaks the refspecs to place remote-tracking branches outside refs/remotes/*.

This patch adds explicit checking of the refspecs for each remote to determine whether a candidate tracking branch is indeed a valid remote-tracking branch, even if placed outside refs/heads/* and refs/remotes/*.

This new check is added as a fallback after checking for match against refs/heads/* and refs/remotes/*, so the code will not be run in the common case.

This patch also fixes the last remaining test failure in t2024-checkout-dwim.
Signed-off-by: Johan Herland <johan@herland.net>
---
 branch.c                 | 18 +++++++++++++++++-
 t/t2024-checkout-dwim.sh |  2 +-
 2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/branch.c b/branch.c
index 6ae6a4c..c9f9dec 100644
--- a/branch.c
+++ b/branch.c
@@ -197,6 +197,21 @@ int validate_new_branchname(const char *name, struct strbuf *ref,
 	return 1;
 }
 
+static int check_tracking_branch(struct remote *remote, void *cb_data)
+{
+	char *tracking_branch = cb_data;
+	struct refspec query;
+	memset(&query, 0, sizeof(struct refspec));
+	query.dst = tracking_branch;
+	return !(remote_find_tracking(remote, &query) ||
+		 prefixcmp(query.src, "refs/heads/"));
+}
+
+static int validate_remote_tracking_branch(char *ref)
+{
+	return !for_each_remote(check_tracking_branch, ref);
+}
+
 static const char upstream_not_branch[] =
 N_("Cannot setup tracking information; starting point '%s' is not a branch.");
 static const char upstream_missing[] =
@@ -259,7 +274,8 @@ void create_branch(const char *head,
 	case 1:
 		/* Unique completion -- good, only if it is a real branch */
 		if (prefixcmp(real_ref, "refs/heads/") &&
-		    prefixcmp(real_ref, "refs/remotes/")) {
+		    prefixcmp(real_ref, "refs/remotes/") &&
+		    validate_remote_tracking_branch(real_ref)) {
 			if (explicit_tracking)
 				die(_(upstream_not_branch), start_name);
 			else
diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh
index fc6edc9..a8f0a90 100755
--- a/t/t2024-checkout-dwim.sh
+++ b/t/t2024-checkout-dwim.sh
@@ -108,7 +108,7 @@ test_expect_success 'checkout of branch from a single remote succeeds #3' '
 	test_tracking_branch spam repo_c refs/remotes/extra_dir/repo_c/extra_dir/spam
 '
 
-test_expect_failure 'checkout of branch from a single remote succeeds #4' '
+test_expect_success 'checkout of branch from a single remote succeeds #4' '
 	git checkout eggs &&
 	test_tracking_branch eggs repo_d refs/repo_d/eggs
 '
-- 
1.8.1.3.704.g33f7d4f
Previous: Johan HerlandNext: Johan Herland
Message 7 of 9 in “Improving the search for remote-tracking branches”
  1. 0/5 Improving the search for remote-tracking branchesJohan Herland, Apr 19, 2013
  2. 1/5 t2024: Add tests verifying current DWIM behavior of 'git checkout <branch>'Johan Herland, Apr 19, 2013
  3. 2/5 t2024: Show failure to use refspec when DWIMming remote branch namesJohan Herland, Apr 19, 2013
  4. 3/5 checkout: Use remote refspecs when DWIMming tracking branchesJohan Herland, Apr 19, 2013
  5. Junio C HamanoApr 19, 2013
  6. Johan HerlandApr 20, 2013
  7. 4/5 branch.c: Look up refspecs to validate tracking branchesJohan Herland, Apr 19, 2013
  8. 5/5 RFD: Disallow out-of-refspec refs within refs/remotes/* to be used as upstreamJohan Herland, Apr 19, 2013
  9. Junio C HamanoApr 19, 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.