fix and test interaction of rebase/histedit -c and 'got stage'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
diff --git a/include/got_error.h b/include/got_error.h
index cbf9d06..bd4cd93 100644
--- a/include/got_error.h
+++ b/include/got_error.h
@@ -119,6 +119,7 @@
#define GOT_ERR_STAGE_CONFLICT 103
#define GOT_ERR_STAGE_OUT_OF_DATE 104
#define GOT_ERR_FILE_NOT_STAGED 105
+#define GOT_ERR_STAGED_PATHS 106
static const struct got_error {
int code;
@@ -241,6 +242,8 @@ static const struct got_error {
{ GOT_ERR_STAGE_OUT_OF_DATE, "work tree must be updated before "
"changes can be staged" },
{ GOT_ERR_FILE_NOT_STAGED, "file is not staged" },
+ { GOT_ERR_STAGED_PATHS, "work tree contains files with staged "
+ "changes; these changes must be committed or unstaged first" },
};
/*
diff --git a/lib/worktree.c b/lib/worktree.c
index b1367b4..86889ab 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -3945,6 +3945,7 @@ got_worktree_rebase_continue(struct got_object_id **commit_id,
char *tmp_branch_name = NULL, *branch_ref_name = NULL;
struct got_reference *commit_ref = NULL, *branch_ref = NULL;
char *fileindex_path = NULL;
+ int have_staged_files = 0;
*commit_id = NULL;
*new_base_branch = NULL;
@@ -3960,9 +3961,18 @@ got_worktree_rebase_continue(struct got_object_id **commit_id,
if (err)
goto done;
+ err = got_fileindex_for_each_entry_safe(*fileindex, check_staged_file,
+ &have_staged_files);
+ if (err && err->code != GOT_ERR_CANCELLED)
+ goto done;
+ if (have_staged_files) {
+ err = got_error(GOT_ERR_STAGED_PATHS);
+ goto done;
+ }
+
err = get_rebase_tmp_ref_name(&tmp_branch_name, worktree);
if (err)
- return err;
+ goto done;
err = get_rebase_branch_symref_name(&branch_ref_name, worktree);
if (err)
@@ -4793,6 +4803,7 @@ got_worktree_histedit_continue(struct got_object_id **commit_id,
struct got_reference *commit_ref = NULL;
struct got_reference *base_commit_ref = NULL;
char *fileindex_path = NULL;
+ int have_staged_files = 0;
*commit_id = NULL;
*tmp_branch = NULL;
@@ -4807,9 +4818,18 @@ got_worktree_histedit_continue(struct got_object_id **commit_id,
if (err)
goto done;
+ err = got_fileindex_for_each_entry_safe(*fileindex, check_staged_file,
+ &have_staged_files);
+ if (err && err->code != GOT_ERR_CANCELLED)
+ goto done;
+ if (have_staged_files) {
+ err = got_error(GOT_ERR_STAGED_PATHS);
+ goto done;
+ }
+
err = get_histedit_tmp_ref_name(&tmp_branch_name, worktree);
if (err)
- return err;
+ goto done;
err = get_histedit_branch_symref_name(&branch_ref_name, worktree);
if (err)
diff --git a/regress/cmdline/histedit.sh b/regress/cmdline/histedit.sh
index a859ac4..5aa888a 100755
--- a/regress/cmdline/histedit.sh
+++ b/regress/cmdline/histedit.sh
@@ -525,6 +525,29 @@ function test_histedit_edit {
echo "edited modified alpha on master" > $testroot/wt/alpha
+ # test interaction of 'got stage' and histedit -c
+ (cd $testroot/wt && got stage alpha > /dev/null)
+ (cd $testroot/wt && got histedit -c > $testroot/stdout \
+ 2> $testroot/stderr)
+ ret="$?"
+ if [ "$ret" == "0" ]; then
+ echo "histedit succeeded unexpectedly" >&2
+ test_done "$testroot" "1"
+ return 1
+ fi
+ echo -n "got: work tree contains files with staged changes; " \
+ > $testroot/stderr.expected
+ echo "these changes must be committed or unstaged first" \
+ >> $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got unstage alpha > /dev/null)
(cd $testroot/wt && got histedit -c > $testroot/stdout)
local new_commit1=`git_show_parent_commit $testroot/repo`
diff --git a/regress/cmdline/rebase.sh b/regress/cmdline/rebase.sh
index 3ffba83..fb98c2f 100755
--- a/regress/cmdline/rebase.sh
+++ b/regress/cmdline/rebase.sh
@@ -244,6 +244,29 @@ function test_rebase_continue {
# resolve the conflict
echo "modified alpha on branch and master" > $testroot/wt/alpha
+ # test interaction of 'got stage' and rebase -c
+ (cd $testroot/wt && got stage alpha > /dev/null)
+ (cd $testroot/wt && got rebase -c > $testroot/stdout \
+ 2> $testroot/stderr)
+ ret="$?"
+ if [ "$ret" == "0" ]; then
+ echo "rebase succeeded unexpectedly" >&2
+ test_done "$testroot" "1"
+ return 1
+ fi
+ echo -n "got: work tree contains files with staged changes; " \
+ > $testroot/stderr.expected
+ echo "these changes must be committed or unstaged first" \
+ >> $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got unstage alpha > /dev/null)
(cd $testroot/wt && got rebase -c > $testroot/stdout)
(cd $testroot/repo && git checkout -q newbranch)