Commit Diff


commit - a397e3fbad25f5da2f4a33e1d2ac8248f32aa24b
commit + f4ab0e5770b96257cb1a43cfe292daa54f2b402e
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 - 3c8cb0c12d7936fbec44d19b84f4631da483f0dc
blob + 4486b08390756e709d18c25cbfc370d75101ecc2
--- got/got.c
+++ got/got.c
@@ -6420,6 +6420,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;
 }
 
@@ -6522,6 +6572,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 - f3dd65c0798d2e84fb8a2d174be5c350115e06a1
blob + 860d8c6d46a8db026e455591d706160d86c7f3fe
--- lib/worktree.c
+++ lib/worktree.c
@@ -7009,6 +7009,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 *
@@ -8033,7 +8097,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;
 }
 
@@ -8861,6 +8966,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