Commit Diff


commit - c935fd512b9937ffefdd248a3a840d0530011a1e
commit + 863cc633e270c0edf587982ac9faccf7bb28f339
blob - 307cde1004e6a1fa347b52fc61a1f2576241e8a8
blob + 9c2fa4cf0f0253f379430b774f532e2e54e6ebc3
--- got/got.1
+++ got/got.1
@@ -1566,8 +1566,9 @@ reference namespace.
 If invoked in a work tree, the work tree's current branch is shown
 with one of the following annotations:
 .Bl -column YXZ description
-.It * Ta work tree's base commit matches the branch tip
-.It \(a~ Ta work tree's base commit is out-of-date
+.It * Ta work tree's base commit and the base commit of all tracked files
+matches the branch tip
+.It \(a~ Ta work tree comprises mixed commits or its base commit is out-of-date
 .El
 .It Fl n
 Do not switch and update the work tree after creating a new branch.
blob - 11de03d9dc00687d501d46094c4ba5444e8c8cb6
blob + ff960485254894c4b8c41fda56a2319bc2b89b17
--- got/got.c
+++ got/got.c
@@ -6797,23 +6797,16 @@ list_branch(struct got_repository *repo, struct got_wo
     struct got_reference *ref)
 {
 	const struct got_error *err = NULL;
-	const char *refname, *marker = "  ";
+	const char *refname;
 	char *refstr;
+	char marker = ' ';
 
 	refname = got_ref_get_name(ref);
 	if (worktree && strcmp(refname,
 	    got_worktree_get_head_ref_name(worktree)) == 0) {
-		struct got_object_id *id = NULL;
-
-		err = got_ref_resolve(&id, repo, ref);
-		if (err)
+		err = got_worktree_get_state(&marker, repo, worktree);
+		if (err != NULL)
 			return err;
-		if (got_object_id_cmp(id,
-		    got_worktree_get_base_commit_id(worktree)) == 0)
-			marker = "* ";
-		else
-			marker = "~ ";
-		free(id);
 	}
 
 	if (strncmp(refname, "refs/heads/", 11) == 0)
@@ -6827,7 +6820,7 @@ list_branch(struct got_repository *repo, struct got_wo
 	if (refstr == NULL)
 		return got_error_from_errno("got_ref_to_str");
 
-	printf("%s%s: %s\n", marker, refname, refstr);
+	printf("%c %s: %s\n", marker, refname, refstr);
 	free(refstr);
 	return NULL;
 }
blob - 71213582275291870b3a3f5941f02a76914cc1c1
blob + 4bc9143544d7cac2ae3c847fbeb41f48e55a1f0a
--- regress/cmdline/branch.sh
+++ regress/cmdline/branch.sh
@@ -524,7 +524,7 @@ test_branch_packed_ref_collision() {
 	# variants of ref/heads/zoo:
 	(cd $testroot/wt && got br -lt > $testroot/stdout)
 
-	echo "* zoo: $commit_id2" > $testroot/stdout.expected
+	echo "~ zoo: $commit_id2" > $testroot/stdout.expected
 	echo "  master: $commit_id" >> $testroot/stdout.expected
 	cmp -s $testroot/stdout $testroot/stdout.expected
 	ret=$?
@@ -586,11 +586,90 @@ test_branch_commit_keywords() {
 	got br -r "$testroot/repo" -l | grep kwbranch2 > "$testroot/stdout"
 
 	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+	fi
+
+	test_done "$testroot" "$ret"
+}
+
+test_branch_list_worktree_state() {
+	local testroot=$(test_init branch_list_worktree_state)
+	local wt="$testroot/wt"
+
+	set -- "$(git_show_head "$testroot/repo")"
+
+	got checkout "$testroot/repo" "$wt" > /dev/null
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "checkout failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd "$wt" && got br -n newbranch > /dev/null)
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "branch failed unexpectedly" >&2
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# check up-to-date marker is shown with fresh checkout
+	(cd "$wt" && got br -l > "$testroot/stdout")
+	echo "* master: $(pop_id 1 $@)" > $testroot/stdout.expected
+	echo "  newbranch: $(pop_id 1 $@)" >> $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
+
+	# check out-of-date marker is shown with mixed-commit state
+	echo "mixed-commit" > "$wt/alpha"
+	(cd "$wt" && got commit -m "mixed-commit" > "$testroot/stdout")
+	set -- "$@" "$(git_show_head "$testroot/repo")"
+
+	(cd "$wt" && got br -l > "$testroot/stdout")
+	echo "~ master: $(pop_id 2 $@)" > $testroot/stdout.expected
+	echo "  newbranch: $(pop_id 1 $@)" >> $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
 
+	# check up-to-date marker is shown after 'got update'
+	(cd "$wt" && got up > /dev/null)
+	(cd "$wt" && got br -l > "$testroot/stdout")
+	echo "* master: $(pop_id 2 $@)" > $testroot/stdout.expected
+	echo "  newbranch: $(pop_id 1 $@)" >> $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
+
+	# check out-of-date marker is shown with out-of-date base commit
+	(cd "$wt" && got up -c:head:- > /dev/null)
+	(cd "$wt" && got br -l > "$testroot/stdout")
+	echo "~ master: $(pop_id 2 $@)" > $testroot/stdout.expected
+	echo "  newbranch: $(pop_id 1 $@)" >> $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
+
 	test_done "$testroot" "$ret"
 }
 
@@ -603,3 +682,4 @@ run_test test_branch_delete_packed
 run_test test_branch_show
 run_test test_branch_packed_ref_collision
 run_test test_branch_commit_keywords
+run_test test_branch_list_worktree_state