Commit Diff


commit - 2a19e2e21a876bbc4ae1999ca08ce4c8f2002158
commit + 4bff57b4b66990d6829cb83645d1f1d478ae0cea
blob - ebe6d90a67b21639861c1b8348207f3e18f13847
blob + d9209e2ae1dd1c1aa01e368bc0016cf86830a9e7
--- got/got.1
+++ got/got.1
@@ -348,13 +348,16 @@ file of the local repository, as created by
 By default, any branches configured in
 .Xr got.conf 5
 for the
-.Ar remote-repository ,
-and the branch resolved via the remote repository's HEAD reference,
+.Ar remote-repository
 will be fetched.
 If
 .Cm got fetch
 is invoked in a work tree then this work tree's current branch will be
 fetched, too, provided it is present on the server.
+If no branches to fetch can be found in
+.Xr got.conf 5
+or via a work tree, or said branches are not found on the server, a branch
+resolved via the remote repository's HEAD reference will be fetched.
 This default behaviour can be overridden with the
 .Fl a
 and
blob - d7765cba2443709b2f200d7c2a3ebca4eb013084
blob + 1ef76ea95b69bf7e45b91f9053a232d241269e7d
--- got/got.c
+++ got/got.c
@@ -1544,7 +1544,7 @@ cmd_clone(int argc, char *argv[])
 	struct got_fetch_progress_arg fpa;
 	char *git_url = NULL;
 	int verbosity = 0, fetch_all_branches = 0, mirror_references = 0;
-	int bflag = 0, list_refs_only = 0;
+	int list_refs_only = 0;
 	int *pack_fds = NULL;
 
 	TAILQ_INIT(&refs);
@@ -1562,7 +1562,6 @@ cmd_clone(int argc, char *argv[])
 			    optarg, NULL);
 			if (error)
 				return error;
-			bflag = 1;
 			break;
 		case 'l':
 			list_refs_only = 1;
@@ -1718,7 +1717,7 @@ cmd_clone(int argc, char *argv[])
 	error = got_fetch_pack(&pack_hash, &refs, &symrefs,
 	    GOT_FETCH_DEFAULT_REMOTE_NAME, mirror_references,
 	    fetch_all_branches, &wanted_branches, &wanted_refs,
-	    list_refs_only, verbosity, fetchfd, repo, NULL, bflag,
+	    list_refs_only, verbosity, fetchfd, repo, NULL, 0,
 	    fetch_progress, &fpa);
 	if (error)
 		goto done;
blob - 990487533727da2e638cbb3271a6802b6af4a80b
blob + 2a22df95ff37a15b31f41c7c01f263af824ddc15
--- libexec/got-fetch-pack/got-fetch-pack.c
+++ libexec/got-fetch-pack/got-fetch-pack.c
@@ -342,12 +342,13 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1,
 	int is_firstpkt = 1, nref = 0, refsz = 16;
 	int i, n, nwant = 0, nhave = 0, acked = 0;
 	off_t packsz = 0, last_reported_packsz = 0;
-	char *id_str = NULL, *refname = NULL;
+	char *id_str = NULL, *default_id_str = NULL, *refname = NULL;
 	char *server_capabilities = NULL, *my_capabilities = NULL;
 	const char *default_branch = NULL;
 	struct got_pathlist_head symrefs;
 	struct got_pathlist_entry *pe;
 	int sent_my_capabilites = 0, have_sidebands = 0;
+	int found_branch = 0;
 	SHA1_CTX sha1_ctx;
 	uint8_t sha1_buf[SHA1_DIGEST_LENGTH];
 	size_t sha1_buf_len = 0;
@@ -438,17 +439,13 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1,
 			}
 			continue;
 		}
-
-		/* always fetch remote HEAD unless -b was specified */
-		if (!no_head && default_branch &&
-		    strcmp(refname, default_branch) == 0 &&
-		    strncmp(default_branch, "refs/heads/", 11) == 0) {
-			err = fetch_ref(ibuf, have_refs, &have[nref],
-			    &want[nref], default_branch, id_str);
-			if (err)
+		if (default_branch && default_id_str == NULL &&
+		    strcmp(refname, default_branch) == 0) {
+			default_id_str = strdup(id_str);
+			if (default_id_str == NULL) {
+				err = got_error_from_errno("strdup");
 				goto done;
-			nref++;
-			continue;
+			}
 		}
 
 		if (list_refs_only || strncmp(refname, "refs/tags/", 10) == 0) {
@@ -464,6 +461,7 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1,
 				if (err)
 					goto done;
 				nref++;
+				found_branch = 1;
 				continue;
 			}
 			TAILQ_FOREACH(pe, wanted_branches, entry) {
@@ -477,6 +475,7 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1,
 				if (err)
 					goto done;
 				nref++;
+				found_branch = 1;
 			} else if (chattygot) {
 				fprintf(stderr, "%s: ignoring %s\n",
 				    getprogname(), refname);
@@ -501,6 +500,16 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1,
 
 	if (list_refs_only)
 		goto done;
+
+	if (!found_branch && !no_head && default_branch && default_id_str &&
+	    strncmp(default_branch, "refs/heads/", 11) == 0) {
+		err = fetch_ref(ibuf, have_refs, &have[nref],
+		    &want[nref], default_branch, default_id_str);
+		if (err)
+			goto done;
+		nref++;
+		found_branch = 1;
+	}
 
 	/* Abort if we haven't found anything to fetch. */
 	if (nref == 0) {
@@ -802,6 +811,7 @@ done:
 	free(have);
 	free(want);
 	free(id_str);
+	free(default_id_str);
 	free(refname);
 	free(server_capabilities);
 	return err;
blob - 5f22ce4442d17056f561112d5ba89fe236f098a4
blob + b5089c370c1eb445b14ae243faad7fb9fefbb907
--- regress/cmdline/fetch.sh
+++ regress/cmdline/fetch.sh
@@ -211,11 +211,8 @@ test_fetch_branch() {
 	got ref -l -r $testroot/repo-clone > $testroot/stdout
 
 	echo "HEAD: refs/heads/master" > $testroot/stdout.expected
-	echo "refs/heads/foo: $commit_id3" >> $testroot/stdout.expected
 	echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
-	echo "refs/remotes/origin/HEAD: refs/remotes/origin/foo" \
-		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/foo: $commit_id3" \
+	echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \
 		>> $testroot/stdout.expected
 	echo "refs/remotes/origin/master: $commit_id2" \
 		>> $testroot/stdout.expected
@@ -1116,12 +1113,9 @@ test_fetch_update_headref() {
 	got ref -l -r $testroot/repo-clone > $testroot/stdout
 
 	echo "HEAD: refs/heads/master" > $testroot/stdout.expected
-	echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected
-	echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
-	echo "refs/remotes/origin/HEAD: refs/remotes/origin/foo" \
+	echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
+	echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \
 		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/foo: $commit_id" \
-		>> $testroot/stdout.expected
 	echo "refs/remotes/origin/master: $commit_id" \
 		>> $testroot/stdout.expected
 
@@ -1432,7 +1426,7 @@ test_fetch_delete_remote_refs() {
 }
 
 test_fetch_honor_wt_conf_bflag() {
-	local testroot=`test_init fetch_honor_wt_conf_bflag`
+	local testroot=`test_init fetch_branch`
 	local testurl=ssh://127.0.0.1/$testroot
 
 	# server will have 'boo', 'hoo', and 'master'
@@ -1502,15 +1496,11 @@ test_fetch_honor_wt_conf_bflag() {
 		return 1
 	fi
 
-	(cd $testroot/repo && git checkout -q master)
-	echo "alpha master" > $testroot/repo/alpha
-	git_commit $testroot/repo -m "alpha master"
-	local commit_id_alpha_master=`git_show_head $testroot/repo`
-
 	(cd $testroot/repo && git checkout -q boo)
-
-	# from repo: no -b used, fetch got.conf "master" and repo HEAD "boo"
-	got fetch -q -r $testroot/repo-clone > $testroot/stdout
+	# from repo: fetch got.conf branch not repo HEAD
+	# boo is the default HEAD in $testroot/repo, which is not up-to-date
+	# on the clone, but we fetch got.conf "master" which is up-to-date
+	got fetch -r $testroot/repo-clone > $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
 		echo "got fetch command failed unexpectedly" >&2
@@ -1518,19 +1508,9 @@ test_fetch_honor_wt_conf_bflag() {
 		return 1
 	fi
 
-	got ref -l -r $testroot/repo-clone > $testroot/stdout
-
-	echo "HEAD: refs/heads/master" > $testroot/stdout.expected
-	echo "refs/heads/bar: $commit_id" >> $testroot/stdout.expected
-	echo "refs/heads/boo: $commit_id2" >> $testroot/stdout.expected
-	echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected
-	echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
-	echo "refs/remotes/origin/HEAD: refs/remotes/origin/boo" \
-		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/boo: $commit_id2" \
-		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/master: $commit_id_alpha_master" \
-		>> $testroot/stdout.expected
+	echo "Connecting to \"origin\" ssh://127.0.0.1$testroot/repo" \
+	    > $testroot/stdout.expected
+	echo "Already up-to-date" >> $testroot/stdout.expected
 
 	cmp -s $testroot/stdout $testroot/stdout.expected
 	ret=$?
@@ -1563,17 +1543,14 @@ test_fetch_honor_wt_conf_bflag() {
 
 	echo "HEAD: refs/heads/master" > $testroot/stdout.expected
 	echo "refs/heads/bar: $commit_id" >> $testroot/stdout.expected
-	echo "refs/heads/boo: $commit_id2" >> $testroot/stdout.expected
 	echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected
 	echo "refs/heads/hoo: $commit_id3" >> $testroot/stdout.expected
 	echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
-	echo "refs/remotes/origin/HEAD: refs/remotes/origin/boo" \
+	echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \
 		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/boo: $commit_id2" \
-		>> $testroot/stdout.expected
 	echo "refs/remotes/origin/hoo: $commit_id3" \
 		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/master: $commit_id_alpha_master" \
+	echo "refs/remotes/origin/master: $commit_id" \
 		>> $testroot/stdout.expected
 
 	cmp -s $testroot/stdout $testroot/stdout.expected
@@ -1612,15 +1589,11 @@ test_fetch_honor_wt_conf_bflag() {
 		return 1
 	fi
 
-	# from repo: fetch got.conf branch "foo", which
-	# doesn't exist on the server, and repo HEAD "boo"
+	# from repo: fetch got.conf branch which doesn't exist, so fallback
+	# to repo HEAD "boo"
 	# change default branch in got.conf from "master" to "foo"
 	sed -i "s/master/foo/" $testroot/repo-clone/got.conf
 
-	echo "modified alpha again on boo" > $testroot/repo/alpha
-	git_commit $testroot/repo -m "modified alpha again on boo"
-	commit_id_alpha=`git_show_head $testroot/repo`
-
 	got fetch -q -r $testroot/repo-clone > $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
@@ -1649,11 +1622,11 @@ test_fetch_honor_wt_conf_bflag() {
 	echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
 	echo "refs/remotes/origin/HEAD: refs/remotes/origin/boo" \
 		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/boo: $commit_id_alpha" \
+	echo "refs/remotes/origin/boo: $commit_id2" \
 		>> $testroot/stdout.expected
 	echo "refs/remotes/origin/hoo: $commit_id3" \
 		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/master: $commit_id_alpha_master" \
+	echo "refs/remotes/origin/master: $commit_id" \
 		>> $testroot/stdout.expected
 
 	cmp -s $testroot/stdout $testroot/stdout.expected
@@ -1664,16 +1637,13 @@ test_fetch_honor_wt_conf_bflag() {
 		return 1
 	fi
 
-	# from wt: fetch got.conf "foo", which doesn't exist on the
-	# server, and implicit wt branch "boo", and repo HEAD "master"
+	# from wt: fetch got.conf "foo", which doesn't exist on the server,
+	# and implicit wt branch "boo", not repo HEAD "master"
 	echo "modified delta on boo" > $testroot/repo/gamma/delta
 	git_commit $testroot/repo -m "modified delta"
 	local commit_id4=`git_show_head $testroot/repo`
 
 	(cd $testroot/repo && git checkout -q master)
-	echo "modified zeta on master" > $testroot/repo/epsilon/zeta
-	git_commit $testroot/repo -m "modified zeta on master"
-	local commit_id_zeta=`git_show_head $testroot/repo`
 
 	got checkout -b boo $testroot/repo-clone $testroot/wt > /dev/null
 	(cd $testroot/wt && got fetch -q > $testroot/stdout)
@@ -1707,7 +1677,7 @@ test_fetch_honor_wt_conf_bflag() {
 		>> $testroot/stdout.expected
 	echo "refs/remotes/origin/hoo: $commit_id3" \
 		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/master: $commit_id_zeta" \
+	echo "refs/remotes/origin/master: $commit_id" \
 		>> $testroot/stdout.expected
 
 	cmp -s $testroot/stdout $testroot/stdout.expected
@@ -1718,7 +1688,7 @@ test_fetch_honor_wt_conf_bflag() {
 		return 1
 	fi
 
-	# from wt: fetch got.conf "master" and wt "boo", and repo HEAD "hoo"
+	# from wt: fetch got.conf "master" and wt "boo", not repo HEAD "hoo"
 	# change default branch in got.conf from "foo" to "master"
 	sed -i "s/foo/master/" $testroot/repo-clone/got.conf
 	echo "modified delta on master" > $testroot/repo/gamma/delta
@@ -1761,7 +1731,7 @@ test_fetch_honor_wt_conf_bflag() {
 		>> $testroot/stdout.expected
 	echo "refs/remotes/origin/boo: $commit_id6" \
 		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/hoo: $commit_id7" \
+	echo "refs/remotes/origin/hoo: $commit_id3" \
 		>> $testroot/stdout.expected
 	echo "refs/remotes/origin/master: $commit_id5" \
 		>> $testroot/stdout.expected
@@ -1776,10 +1746,6 @@ test_fetch_honor_wt_conf_bflag() {
 
 	# from wt: fetch -b hoo not got.conf "master" or wt "boo" or
 	# repo HEAD "boo"
-	echo "hoo delta!" > $testroot/repo/gamma/delta
-	git_commit $testroot/repo -m "hoo delta!"
-	local commit_id_delta=`git_show_head $testroot/repo`
-
 	(cd $testroot/repo && git checkout -q boo)
 	echo "modified alpha again on boo" > $testroot/repo/alpha
 	git_commit $testroot/repo -m "modified alpha again on boo"
@@ -1811,7 +1777,7 @@ test_fetch_honor_wt_conf_bflag() {
 		>> $testroot/stdout.expected
 	echo "refs/remotes/origin/boo: $commit_id6" \
 		>> $testroot/stdout.expected
-	echo "refs/remotes/origin/hoo: $commit_id_delta" \
+	echo "refs/remotes/origin/hoo: $commit_id7" \
 		>> $testroot/stdout.expected
 	echo "refs/remotes/origin/master: $commit_id5" \
 		>> $testroot/stdout.expected