Commit Diff


commit - 101257039ae01276572124264470185d2b9baaf0
commit + cd634f2d6d87577ed25d69f9b9a9d07c990a4223
blob - 8443d267c1f9a1e49d05b5258a78b6f9e247ae00
blob + 27fee027d191881e30323c0d8436d8803ffe5eca
--- got/got.1
+++ got/got.1
@@ -822,6 +822,12 @@ Changes created on top of staged changes are indicated
 .It MM Ta file was modified after earlier changes have been staged
 .It MA Ta file was modified after having been staged for addition
 .El
+.Pp
+If the work tree contains the results of an interrupted
+.Cm got rebase ,
+.Cm got histedit, or
+.Cm got merge
+operation then display a message which shows the branches involved.
 .Pp
 The options for
 .Cm got status
blob - 9ca2cf86ca1bf61c712330d9933d9bf241a80846
blob + f64718c7a221e24d8bd87dc9cda7479193609c10
--- got/got.c
+++ got/got.c
@@ -6419,6 +6419,56 @@ print_status(void *arg, unsigned char status, unsigned
 	}
 print:
 	printf("%c%c %s\n", status, staged_status, path);
+	return NULL;
+}
+
+static const struct got_error *
+show_operation_in_progress(struct got_worktree *worktree,
+    struct got_repository *repo)
+{
+	const struct got_error *err;
+	char *new_base_branch_name = NULL;
+	char *branch_name = NULL;
+	int rebase_in_progress, histedit_in_progress, merge_in_progress;
+
+	err = got_worktree_rebase_in_progress(&rebase_in_progress, worktree);
+	if (err)
+		return err;
+	if (rebase_in_progress) {
+		err = got_worktree_rebase_info(&new_base_branch_name,
+		    &branch_name, worktree, repo);
+		if (err)
+			return err;
+		printf("Work tree is rebasing %s onto %s\n",
+		    branch_name, new_base_branch_name);
+	}
+
+	err = got_worktree_histedit_in_progress(&histedit_in_progress,
+	    worktree);
+	if (err)
+		return err;
+	if (histedit_in_progress) {
+		err = got_worktree_histedit_info(&branch_name, worktree, repo);
+		if (err)
+			return err;
+		printf("Work tree is editing the history of %s\n", branch_name);
+	}
+
+	err = got_worktree_merge_in_progress(&merge_in_progress,
+	    worktree, repo);
+	if (err)
+		return err;
+	if (merge_in_progress) {
+		err = got_worktree_merge_info(&branch_name, worktree,
+		    repo);
+		if (err)
+			return err;
+		printf("Work tree is merging %s into %s\n", branch_name,
+		    got_worktree_get_head_ref_name(worktree));
+	}
+
+	free(new_base_branch_name);
+	free(branch_name);
 	return NULL;
 }
 
@@ -6521,6 +6571,10 @@ cmd_status(int argc, char *argv[])
 
 	error = got_worktree_status(worktree, &paths, repo, no_ignores,
 	    print_status, &st, check_cancelled, NULL);
+	if (error)
+		goto done;
+
+	error = show_operation_in_progress(worktree, repo);
 done:
 	if (pack_fds) {
 		const struct got_error *pack_err =
blob - e45d7096cd1e609bd13f07ec1c9dcfcaf5a6b508
blob + d2b62724acbc48c141e49a60bd36765fe2c58cad
--- include/got_worktree.h
+++ include/got_worktree.h
@@ -319,6 +319,9 @@ const struct got_error *got_worktree_rebase_continue(s
 /* Check whether a, potentially interrupted, rebase operation is in progress. */
 const struct got_error *got_worktree_rebase_in_progress(int *,
     struct got_worktree *);
+/* Return information about an in-progress rebase operation. */
+const struct got_error *got_worktree_rebase_info(char **new_base_branch_name,
+    char **branch_name, struct got_worktree *, struct got_repository *);
 
 /*
  * Merge changes from the commit currently being rebased into the work tree.
@@ -391,6 +394,10 @@ const struct got_error *got_worktree_histedit_continue
 /* Check whether a histedit operation is in progress. */
 const struct got_error *got_worktree_histedit_in_progress(int *,
     struct got_worktree *);
+/* Return information about an in-progress histedit operation. */
+const struct got_error *got_worktree_histedit_info(
+    char **branch_nane, struct got_worktree *,
+    struct got_repository *);
 
 /*
  * Merge changes from the commit currently being edited into the work tree.
@@ -507,6 +514,10 @@ const struct got_error *got_worktree_merge_complete(
 /* Check whether a merge operation is in progress. */
 const struct got_error *got_worktree_merge_in_progress(int *,
     struct got_worktree *, struct got_repository *);
+/* Return information about an in-progress merge operation. */
+const struct got_error *
+got_worktree_merge_info(char **branch_name, struct got_worktree *,
+    struct got_repository *);
 
 /*
  * Prepare for merging a branch into the work tree's current branch: lock the
blob - 6d77ee58bbd3cfb9ef5c680a11dd856c3e64dff9
blob + 1e9dcbabbf610fad4051df25fb2ef9897b3ac524
--- lib/worktree.c
+++ lib/worktree.c
@@ -7006,6 +7006,70 @@ got_worktree_rebase_in_progress(int *in_progress, stru
 	*in_progress = (strcmp(tmp_branch_name, worktree->head_ref_name) == 0);
 	free(tmp_branch_name);
 	return NULL;
+}
+
+const struct got_error *
+got_worktree_rebase_info(char **new_base_branch_name, char **branch_name,
+    struct got_worktree *worktree, struct got_repository *repo)
+{
+	const struct got_error *err;
+	char *new_base_branch_ref_name = NULL;
+	char *branch_ref_name = NULL;
+	struct got_reference *branch_ref = NULL, *branch = NULL;
+	struct got_reference *new_base_branch = NULL;
+
+	*new_base_branch_name = NULL;
+	*branch_name = NULL;
+
+	err = get_rebase_branch_symref_name(&branch_ref_name, worktree);
+	if (err)
+		goto done;
+
+	err = get_newbase_symref_name(&new_base_branch_ref_name, worktree);
+	if (err)
+		goto done;
+
+	err = got_ref_open(&branch_ref, repo, branch_ref_name, 0);
+	if (err)
+		goto done;
+
+	err = got_ref_open(&branch, repo,
+	    got_ref_get_symref_target(branch_ref), 0);
+	if (err)
+		goto done;
+
+	err = got_ref_open(&new_base_branch, repo,
+	    new_base_branch_ref_name, 0);
+	if (err)
+		goto done;
+
+	if (!got_ref_is_symbolic(new_base_branch)) {
+		err = got_error_fmt(GOT_ERR_BAD_REF_TYPE,
+		    "%s is not a symbolic reference",
+		    got_ref_get_name(branch_ref));
+		goto done;
+	}
+
+	*new_base_branch_name = strdup(got_ref_get_symref_target(
+	    new_base_branch));
+	if (*new_base_branch_name == NULL) {
+		err = got_error_from_errno("strdup");
+		goto done;
+	}
+	*branch_name = strdup(got_ref_get_name(branch));
+	if (*branch_name == NULL) {
+		err = got_error_from_errno("strdup");
+		goto done;
+	}
+done:
+	free(branch_ref_name);
+	if (branch_ref)
+		got_ref_close(branch_ref);
+	if (new_base_branch)
+		got_ref_close(new_base_branch);
+	if (branch)
+		got_ref_close(branch);
+	return err;
 }
 
 static const struct got_error *
@@ -8030,7 +8094,48 @@ done:
 			*fileindex = NULL;
 		}
 		lock_worktree(worktree, LOCK_EX);
+	}
+	return err;
+}
+
+const struct got_error *
+got_worktree_histedit_info(char **branch_name,
+    struct got_worktree *worktree, struct got_repository *repo)
+{
+	const struct got_error *err;
+	struct got_reference *branch_ref = NULL;
+	char *branch_ref_name = NULL;
+
+	*branch_name = NULL;
+
+	err = get_histedit_branch_symref_name(&branch_ref_name, worktree);
+	if (err)
+		goto done;
+
+	err = got_ref_open(&branch_ref, repo, branch_ref_name, 0);
+	if (err)
+		goto done;
+
+	if (!got_ref_is_symbolic(branch_ref)) {
+		err = got_error_fmt(GOT_ERR_BAD_REF_TYPE,
+		    "%s is not a symbolic reference",
+		    got_ref_get_name(branch_ref));
+		goto done;
+	}
+
+	*branch_name = strdup(got_ref_get_symref_target(branch_ref));
+	if (*branch_name == NULL) {
+		err = got_error_from_errno("strdup");
+		goto done;
 	}
+done:
+	free(branch_ref_name);
+	if (branch_ref)
+		got_ref_close(branch_ref);
+	if (err) {
+		free(*branch_name);
+		*branch_name = NULL;
+	}
 	return err;
 }
 
@@ -8858,6 +8963,49 @@ done:
 }
 
 const struct got_error *
+got_worktree_merge_info(char **branch_name, struct got_worktree *worktree,
+    struct got_repository *repo)
+{
+	const struct got_error *err;
+	char *branch_refname = NULL;
+	struct got_reference *branch_ref = NULL;
+
+	*branch_name = NULL;
+
+	err = get_merge_branch_ref_name(&branch_refname, worktree);
+	if (err)
+		goto done;
+
+	err = got_ref_open(&branch_ref, repo, branch_refname, 0);
+	if (err)
+		goto done;
+
+	if (!got_ref_is_symbolic(branch_ref)) {
+		err = got_error_fmt(GOT_ERR_BAD_REF_TYPE,
+		    "%s is not a symbolic reference",
+		    got_ref_get_name(branch_ref));
+		goto done;
+	}
+	*branch_name = strdup(got_ref_get_symref_target(branch_ref));
+	if (*branch_name == NULL) {
+		err = got_error_from_errno("strdup");
+		goto done;
+	}
+
+done:
+	free(branch_refname);
+	if (branch_ref)
+		got_ref_close(branch_ref);
+	if (err) {
+		if (*branch_name) {
+			free(*branch_name);
+			*branch_name = NULL;
+		}
+	}
+	return err;
+}
+
+const struct got_error *
 got_worktree_merge_abort(struct got_worktree *worktree,
     struct got_fileindex *fileindex, struct got_repository *repo,
     got_worktree_checkout_cb progress_cb, void *progress_arg)
blob - 4540f35d9804387c36072d1da2829b2c460a5171
blob + 13dd31e4feec963e558e3e0eebbcfac22c15c741
--- regress/cmdline/histedit.sh
+++ regress/cmdline/histedit.sh
@@ -1186,7 +1186,10 @@ test_histedit_path_prefix_edit() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "M  zeta"> $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+M  zeta
+Work tree is editing the history of refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
blob - dbe3024c2ef524f9153d2084c07158bbf936910e
blob + cd6a8a4afe865e1846927b4aa4b6ef571c40bee8
--- regress/cmdline/merge.sh
+++ regress/cmdline/merge.sh
@@ -713,10 +713,13 @@ test_merge_continue() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "C  alpha" > $testroot/stdout.expected
-	echo "D  beta" >> $testroot/stdout.expected
-	echo "A  epsilon/new" >> $testroot/stdout.expected
-	echo "M  gamma/delta" >> $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+C  alpha
+D  beta
+A  epsilon/new
+M  gamma/delta
+Work tree is merging refs/heads/newbranch into refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
@@ -1005,13 +1008,16 @@ test_merge_abort() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "A  added-file" > $testroot/stdout.expected
-	echo "C  alpha" >> $testroot/stdout.expected
-	echo "D  beta" >> $testroot/stdout.expected
-	echo "A  epsilon/new" >> $testroot/stdout.expected
-	echo "M  gamma/delta" >> $testroot/stdout.expected
-	echo "A  symlink" >> $testroot/stdout.expected
-	echo "?  unversioned-file" >> $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+A  added-file
+C  alpha
+D  beta
+A  epsilon/new
+M  gamma/delta
+A  symlink
+?  unversioned-file
+Work tree is merging refs/heads/newbranch into refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
@@ -1186,7 +1192,10 @@ test_merge_in_progress() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "C  alpha" > $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+C  alpha
+Work tree is merging refs/heads/newbranch into refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
@@ -1357,7 +1366,10 @@ test_merge_missing_file() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "M  gamma/delta" > $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+M  gamma/delta
+Work tree is merging refs/heads/newbranch into refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
@@ -1433,7 +1445,10 @@ test_merge_no_op() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "C  alpha" > $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+C  alpha
+Work tree is merging refs/heads/newbranch into refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
@@ -1666,7 +1681,10 @@ test_merge_interrupt() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "M  alpha" > $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+M  alpha
+Work tree is merging refs/heads/newbranch into refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
blob - 0239e75d3e0b84aa67d95700219ecda8782265ef
blob + ee6fefa31ac2365004dd760838761c9cba5e07a1
--- regress/cmdline/rebase.sh
+++ regress/cmdline/rebase.sh
@@ -340,7 +340,10 @@ test_rebase_continue() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "C  alpha" > $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+C  alpha
+Work tree is rebasing refs/heads/newbranch onto refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
@@ -501,10 +504,13 @@ test_rebase_abort() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "A  added-file" > $testroot/stdout.expected
-	echo "C  alpha" >> $testroot/stdout.expected
-	echo "A  epsilon/new" >> $testroot/stdout.expected
-	echo "?  unversioned-file" >> $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+A  added-file
+C  alpha
+A  epsilon/new
+?  unversioned-file
+Work tree is rebasing refs/heads/newbranch onto refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
@@ -669,7 +675,10 @@ test_rebase_no_op_change() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "C  alpha" > $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+C  alpha
+Work tree is rebasing refs/heads/newbranch onto refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then
@@ -781,7 +790,10 @@ test_rebase_in_progress() {
 
 	(cd $testroot/wt && got status > $testroot/stdout)
 
-	echo "C  alpha" > $testroot/stdout.expected
+	cat > $testroot/stdout.expected <<EOF
+C  alpha
+Work tree is rebasing refs/heads/newbranch onto refs/heads/master
+EOF
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret=$?
 	if [ $ret -ne 0 ]; then