"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Mark Jamsek <mark@jamsek.com>
Subject:
special case 'got fetch -b <branch>' + regress
To:
Game of Trees <gameoftrees@openbsd.org>
Date:
Mon, 13 Feb 2023 02:23:01 +1100

Download raw body.

Thread
As discussed with stsp on irc, the following diff special cases
'got fetch -b' to _only_ fetch the specified branch, unlike the
remaining fetch cases (e.g., with{,out} branches set in got.conf and
with{,out} implicit work tree branch) where we fallback to the remote
HEAD branch if the branches in got.conf or the work tree are either not
set or do not exist on the remote.

Regress has also been expanded to cover the new -b behaviour and also
makes a start on complete coverage of fetch honouring the dynamics
between branches set (or not set) in got.conf, and whether they exist on
the server, and ditto for whether fetch is invoked in a work tree.

At present, we cover 'got fetch' from:

  - repo: got.conf branch that exists on remote (fetches got.conf only)
  - repo: -b branch that exists on remote (fetches -b only)
  - repo: -b branch that doesn't exist on remote (fetches none)
  - repo: got.conf branch that doesn't exist (fallback to remote HEAD)
  - wt: got.conf that doesn't exist, wt that does exist (fetches wt only)
  - wt: got.conf and wt branches that both exist (fetches conf and wt)
  - wt: -b branch that does exist on the remote (fetches -b only)
  - wt: -b branch that doesn't exist on the remote (fetches none)

As a related change, I'll follow up (tomorrow) with a diff that improves
the output when requesting a branch with 'got fetch -b' that does not
exist. Currently, we report:

  got-fetch-pack: could not find any branches to fetch
  got: could not find any branches to fetch

PS. For the sake of review, the changes not in regress are the same as
the diff sent on irc yesterday

diffstat refs/heads/main refs/heads/fetch
 M  got/got.c                                |    3+  2-
 M  include/got_fetch.h                      |    1+  1-
 M  lib/fetch.c                              |    2+  2-
 M  lib/got_lib_privsep.h                    |    2+  1-
 M  lib/privsep.c                            |    2+  1-
 M  libexec/got-fetch-pack/got-fetch-pack.c  |    3+  3-
 M  regress/cmdline/fetch.sh                 |  393+  0-

7 files changed, 406 insertions(+), 10 deletions(-)

diff refs/heads/main refs/heads/fetch
commit - 2c4740ad12b787db8704cb160abc4f1e5e73d911
commit + 85a31c5eadcc5d5cbdbd34228cc42efc85eb9962
blob - 127b86675c2322fd21f0849b2a7f9df339621c75
blob + 2c1701bd7583e22c83fc62c3bfca5fb2a5492585
--- got/got.c
+++ got/got.c
@@ -1716,7 +1716,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,
+	    list_refs_only, verbosity, fetchfd, repo, NULL, 0,
 	    fetch_progress, &fpa);
 	if (error)
 		goto done;
@@ -2546,10 +2546,11 @@ cmd_fetch(int argc, char *argv[])
 	fpa.create_configs = 0;
 	fpa.configs_created = 0;
 	memset(&fpa.config_info, 0, sizeof(fpa.config_info));
+
 	error = got_fetch_pack(&pack_hash, &refs, &symrefs, remote->name,
 	    remote->mirror_references, fetch_all_branches, &wanted_branches,
 	    &wanted_refs, list_refs_only, verbosity, fetchfd, repo,
-	    worktree_branch, fetch_progress, &fpa);
+	    worktree_branch, have_bflag, fetch_progress, &fpa);
 	if (error)
 		goto done;
 
blob - 5703d1fbe97e2c2bfcb5c6c2095c9653f5ee5e6e
blob + 5768c9157c81ca12b00f65491c540dd712c37e6a
--- include/got_fetch.h
+++ include/got_fetch.h
@@ -46,5 +46,5 @@ const struct got_error *got_fetch_pack(struct got_obje
 const struct got_error *got_fetch_pack(struct got_object_id **,
 	struct got_pathlist_head *, struct got_pathlist_head *, const char *,
 	int, int, struct got_pathlist_head *, struct got_pathlist_head *,
-	int, int, int, struct got_repository *, const char *,
+	int, int, int, struct got_repository *, const char *, int,
 	got_fetch_progress_cb, void *);
blob - bfa126b8fabcca280af94961030dcae5aae3e6e6
blob + e37808ed2a0bf37771cbf76e39cfa92b60ad43cc
--- lib/fetch.c
+++ lib/fetch.c
@@ -105,7 +105,7 @@ got_fetch_pack(struct got_object_id **pack_hash, struc
     struct got_pathlist_head *wanted_branches,
     struct got_pathlist_head *wanted_refs, int list_refs_only, int verbosity,
     int fetchfd, struct got_repository *repo, const char *worktree_refname,
-    got_fetch_progress_cb progress_cb, void *progress_arg)
+    int no_head, got_fetch_progress_cb progress_cb, void *progress_arg)
 {
 	size_t i;
 	int imsg_fetchfds[2], imsg_idxfds[2];
@@ -261,7 +261,7 @@ got_fetch_pack(struct got_object_id **pack_hash, struc
 	}
 	err = got_privsep_send_fetch_req(&fetchibuf, nfetchfd, &have_refs,
 	    fetch_all_branches, wanted_branches, wanted_refs,
-	    list_refs_only, worktree_refname, verbosity);
+	    list_refs_only, worktree_refname, no_head, verbosity);
 	if (err != NULL)
 		goto done;
 	nfetchfd = -1;
blob - 09e7cb7ce6e9cf826f667d69280ad2dab4b4d161
blob + b8170cb9afee37b2625c705535e43662ca7dd06c
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
@@ -404,6 +404,7 @@ struct got_imsg_fetch_request {
 
 /* Structure for GOT_IMSG_FETCH_REQUEST data. */
 struct got_imsg_fetch_request {
+	int no_head;
 	int fetch_all_branches;
 	int list_refs_only;
 	int verbosity;
@@ -700,7 +701,7 @@ const struct got_error *got_privsep_send_fetch_req(str
     int *, int *, struct imsgbuf *ibuf);
 const struct got_error *got_privsep_send_fetch_req(struct imsgbuf *, int,
     struct got_pathlist_head *, int, struct got_pathlist_head *,
-    struct got_pathlist_head *, int, const char *, int);
+    struct got_pathlist_head *, int, const char *, int, int);
 const struct got_error *got_privsep_send_fetch_outfd(struct imsgbuf *, int);
 const struct got_error *got_privsep_recv_fetch_progress(int *,
     struct got_object_id **, char **, struct got_pathlist_head *, char **,
blob - 8954b4c42e443bbd5ba01b707de2fd26e6410d19
blob + 45186fa65020450414f58d1089a1b4ee158eeff9
--- lib/privsep.c
+++ lib/privsep.c
@@ -532,7 +532,7 @@ got_privsep_send_fetch_req(struct imsgbuf *ibuf, int f
     struct got_pathlist_head *have_refs, int fetch_all_branches,
     struct got_pathlist_head *wanted_branches,
     struct got_pathlist_head *wanted_refs, int list_refs_only,
-    const char *worktree_branch, int verbosity)
+    const char *worktree_branch, int no_head, int verbosity)
 {
 	const struct got_error *err = NULL;
 	struct ibuf *wbuf;
@@ -556,6 +556,7 @@ got_privsep_send_fetch_req(struct imsgbuf *ibuf, int f
 		return got_error_from_errno("imsg_create FETCH_HAVE_REF");
 
 	memset(&fetchreq, 0, sizeof(fetchreq));
+	fetchreq.no_head = no_head;
 	fetchreq.fetch_all_branches = fetch_all_branches;
 	fetchreq.list_refs_only = list_refs_only;
 	fetchreq.verbosity = verbosity;
blob - f21581a8de91fa478a72e20f422c81a342ce59e8
blob + c8d35d7046be5e229cbdc28ec23f311320cfef70
--- libexec/got-fetch-pack/got-fetch-pack.c
+++ libexec/got-fetch-pack/got-fetch-pack.c
@@ -333,7 +333,7 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1,
     struct got_pathlist_head *have_refs, int fetch_all_branches,
     struct got_pathlist_head *wanted_branches,
     struct got_pathlist_head *wanted_refs, int list_refs_only,
-    const char *worktree_branch, struct imsgbuf *ibuf)
+    const char *worktree_branch, int no_head, struct imsgbuf *ibuf)
 {
 	const struct got_error *err = NULL;
 	char buf[GOT_PKT_MAX];
@@ -501,7 +501,7 @@ fetch_pack(int fd, int packfd, uint8_t *pack_sha1,
 	if (list_refs_only)
 		goto done;
 
-	if (!found_branch && default_branch && default_id_str &&
+	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);
@@ -1026,7 +1026,7 @@ main(int argc, char **argv)
 	err = fetch_pack(fetchfd, packfd, pack_sha1, &have_refs,
 	    fetch_req.fetch_all_branches, &wanted_branches,
 	    &wanted_refs, fetch_req.list_refs_only,
-	    worktree_branch, &ibuf);
+	    worktree_branch, fetch_req.no_head, &ibuf);
 done:
 	free(worktree_branch);
 	got_pathlist_free(&have_refs, GOT_PATHLIST_FREE_ALL);
blob - 26346effc18d13d5e986f7072e63b5d9c885450f
blob + 32900e895fc896beef177d3ad156f591d1f1ffb8
--- regress/cmdline/fetch.sh
+++ regress/cmdline/fetch.sh
@@ -1425,7 +1425,399 @@ test_fetch_delete_remote_refs() {
 	test_done "$testroot" "$ret"
 }
 
+test_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'
+	echo "modified alpha on master" > $testroot/repo/alpha
+	git_commit $testroot/repo -m "modified alpha"
+	local commit_id=`git_show_head $testroot/repo`
+
+	got branch -r $testroot/repo -c $commit_id boo
+	(cd $testroot/repo && git checkout -q boo)
+	echo "modified beta on boo" > $testroot/repo/beta
+	git_commit $testroot/repo -m "modified beta"
+	local commit_id2=`git_show_head $testroot/repo`
+
+	got branch -r $testroot/repo -c $commit_id2 hoo
+	(cd $testroot/repo && git checkout -q hoo)
+	echo "modified delta on hoo" > $testroot/repo/gamma/delta
+	git_commit $testroot/repo -m "modified delta"
+	local commit_id3=`git_show_head $testroot/repo`
+
+	(cd $testroot/repo && git checkout -q master)
+	got clone -q $testurl/repo $testroot/repo-clone
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got clone command failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# only clone will have foo and bar
+	got branch -r $testroot/repo-clone -c $commit_id foo
+	got branch -r $testroot/repo-clone -c $commit_id bar
+
+	got fetch -q -r $testroot/repo-clone > $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got fetch command failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo -n > $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		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/foo: $commit_id" >> $testroot/stdout.expected
+	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/master: $commit_id" \
+		>> $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/repo && git checkout -q boo)
+	# 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
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	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=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# from repo: fetch -b hoo not got.conf branch or repo HEAD
+	got fetch -q -r $testroot/repo-clone -b hoo > $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got fetch command failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo -n > $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		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/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/master" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/hoo: $commit_id3" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/master: $commit_id" \
+		>> $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# from repo: fetch -b foo which doesn't exist on the server but
+	# do not fallback to repo HEAD "boo" because we used the -b flag
+	got fetch -r $testroot/repo-clone -b foo > $testroot/stdout \
+	    2> $testroot/stderr
+
+	echo "Connecting to \"origin\" ssh://127.0.0.1$testroot/repo" \
+	    > $testroot/stdout.expected
+	echo "got-fetch-pack: could not find any branches to fetch" \
+	    > $testroot/stderr.expected
+	echo "got: could not find any branches to fetch" \
+	    >> $testroot/stderr.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	cmp -s $testroot/stderr $testroot/stderr.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# 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
+
+	got fetch -q -r $testroot/repo-clone > $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got fetch command failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo -n > $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		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/hoo: $commit_id3" >> $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/hoo: $commit_id3" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/master: $commit_id" \
+		>> $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# 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)
+
+	got checkout -b boo $testroot/repo-clone $testroot/wt > /dev/null
+	(cd $testroot/wt && got fetch -q > $testroot/stdout)
+
+	echo -n > $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	local wt_uuid=`(cd $testroot/wt && got info | grep 'UUID:' | \
+		cut -d ':' -f 2 | tr -d ' ')`
+
+	got ref -l -r $testroot/repo-clone > $testroot/stdout
+
+	echo "HEAD: refs/heads/master" > $testroot/stdout.expected
+	echo "refs/got/worktree/base-$wt_uuid: $commit_id2" \
+		>> $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/master" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/boo: $commit_id4" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/hoo: $commit_id3" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/master: $commit_id" \
+		>> $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# 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
+	git_commit $testroot/repo -m "modified delta on master"
+	local commit_id5=`git_show_head $testroot/repo`
+
+	(cd $testroot/repo && git checkout -q boo)
+	echo "modified alpha on boo" > $testroot/repo/alpha
+	git_commit $testroot/repo -m "modified alpha on boo"
+	local commit_id6=`git_show_head $testroot/repo`
+
+	(cd $testroot/repo && git checkout -q hoo)
+	echo "modified beta on hoo" > $testroot/repo/beta
+	git_commit $testroot/repo -m "modified beta on hoo"
+	local commit_id7=`git_show_head $testroot/repo`
+
+	(cd $testroot/wt && got fetch -q > $testroot/stdout)
+
+	echo -n > $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	got ref -l -r $testroot/repo-clone > $testroot/stdout
+
+	echo "HEAD: refs/heads/master" > $testroot/stdout.expected
+	echo "refs/got/worktree/base-$wt_uuid: $commit_id2" \
+		>> $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/hoo" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/boo: $commit_id6" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/hoo: $commit_id3" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/master: $commit_id5" \
+		>> $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# from wt: fetch -b hoo not got.conf "master" or wt "boo" or
+	# repo HEAD "boo"
+	(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"
+	local commit_id8=`git_show_head $testroot/repo`
+
+	(cd $testroot/wt && got fetch -q -b hoo > $testroot/stdout)
+
+	echo -n > $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	got ref -l -r $testroot/repo-clone > $testroot/stdout
+
+	echo "HEAD: refs/heads/master" > $testroot/stdout.expected
+	echo "refs/got/worktree/base-$wt_uuid: $commit_id2" \
+		>> $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" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/boo: $commit_id6" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/hoo: $commit_id7" \
+		>> $testroot/stdout.expected
+	echo "refs/remotes/origin/master: $commit_id5" \
+		>> $testroot/stdout.expected
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# from wt: fetch -b bar that doesn't exist on the server but
+	# do not fetch got.conf "master" or wt "boo" or repo HEAD "boo"
+	(cd $testroot/wt && got fetch -b bar > $testroot/stdout \
+	    2> $testroot/stderr)
+
+	echo "Connecting to \"origin\" ssh://127.0.0.1$testroot/repo" \
+	    > $testroot/stdout.expected
+	echo "got-fetch-pack: could not find any branches to fetch" \
+	    > $testroot/stderr.expected
+	echo "got: could not find any branches to fetch" \
+	    >> $testroot/stderr.expected
+
+	cmp -s $testroot/stderr $testroot/stderr.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+	fi
+	test_done "$testroot" "$ret"
+}
+
 test_parseargs "$@"
 run_test test_fetch_basic
 run_test test_fetch_list
@@ -1441,3 +1833,4 @@ run_test test_fetch_delete_remote_refs
 run_test test_fetch_headref_deleted_locally
 run_test test_fetch_gotconfig_remote_repo
 run_test test_fetch_delete_remote_refs
+run_test test_fetch_honor_wt_conf_bflag

-- 
Mark Jamsek <fnc.bsdbox.org|got.bsdbox.org>
GPG: F2FF 13DE 6A06 C471 CA80  E6E2 2930 DC66 86EE CF68