Download raw body.
make got status show interrupted operations
This small UI tweak makes it easier to users to identify whether
a work tree is currently in an interrupted operation. ok?
-----------------------------------------------
make 'got status' display interrupted rebase, histedit, and merge operations
When an operation is interrupted add a trailing message to status output
which displays the operation and branches involved.
This information will be useful when diagnosing problem reports and it
helps new users with contextualizing multi-operation work tree states.
diff a854b8c994a1381e4c6f2ba45bef9c22da0ec956 96a6a00dbe4a094394ebc2d7c77082c01c9850e1
commit - a854b8c994a1381e4c6f2ba45bef9c22da0ec956
commit + 96a6a00dbe4a094394ebc2d7c77082c01c9850e1
blob - ee41732e49ededaf4c54218c0d0b9deb2c1feff9
blob + 24c38ee62b98e9ab39fdf9d2f67d3b4b3502a98c
--- got/got.1
+++ got/got.1
@@ -823,6 +823,12 @@ Changes created on top of staged changes are indicated
.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
are as follows:
blob - 5775865ce9bc5a0a9f5d8638ed832cf4ef970d67
blob + f7503f5f1f6ae825fc05d3dfc22e2c43d67b1afd
--- got/got.c
+++ got/got.c
@@ -6424,6 +6424,56 @@ print:
}
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;
+}
+
+static const struct got_error *
cmd_status(int argc, char *argv[])
{
const struct got_error *close_err, *error = 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
@@ -7011,6 +7011,70 @@ got_worktree_rebase_in_progress(int *in_progress, stru
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 *
collect_rebase_commit_msg(struct got_pathlist_head *commitable_paths,
const char *diff_path, char **logmsg, void *arg)
@@ -8037,6 +8101,47 @@ done:
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;
+}
+
static const struct got_error *
delete_histedit_refs(struct got_worktree *worktree, struct got_repository *repo)
{
@@ -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
make got status show interrupted operations