got stage: implicitly unstage when staging the reverse of the staged diff otherwise we end up with a staged empty edit for that file. ok stsp@
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
diff --git a/lib/worktree.c b/lib/worktree.c
index c8e98cc..0fefe75 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -8088,6 +8088,17 @@ stage_path(void *arg, unsigned char status,
err = (*a->status_cb)(a->status_arg, GOT_STATUS_NO_CHANGE,
get_staged_status(ie), relpath, blob_id,
new_staged_blob_id, NULL, dirfd, de_name);
+ if (err)
+ break;
+ /*
+ * When staging the reverse of the staged diff,
+ * implicitly unstage the file.
+ */
+ if (memcmp(ie->staged_blob_sha1, ie->blob_sha1,
+ sizeof(ie->blob_sha1)) == 0) {
+ got_fileindex_entry_stage_set(ie,
+ GOT_FILEIDX_STAGE_NONE);
+ }
break;
case GOT_STATUS_DELETE:
if (staged_status == GOT_STATUS_DELETE)
diff --git a/regress/cmdline/stage.sh b/regress/cmdline/stage.sh
index 701e5bd..de1799d 100755
--- a/regress/cmdline/stage.sh
+++ b/regress/cmdline/stage.sh
@@ -2154,6 +2154,59 @@ test_stage_patch_removed_twice() {
test_done "$testroot" "$ret"
}
+test_stage_patch_reversed() {
+ local testroot=`test_init stage_patch_reversed`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo 'ALPHA' > $testroot/wt/alpha
+ (cd $testroot/wt && got stage alpha > $testroot/stdout)
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo ' M alpha' > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo 'alpha' > $testroot/wt/alpha
+ (cd $testroot/wt && got stage alpha > $testroot/stdout)
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo ' M alpha' > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/wt && got status > $testroot/stdout)
+ cmp -s /dev/null $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u /dev/null $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+}
+
test_stage_patch_quit() {
local testroot=`test_init stage_patch_quit`
@@ -2987,6 +3040,7 @@ run_test test_stage_patch_added
run_test test_stage_patch_added_twice
run_test test_stage_patch_removed
run_test test_stage_patch_removed_twice
+run_test test_stage_patch_reversed
run_test test_stage_patch_quit
run_test test_stage_patch_incomplete_script
run_test test_stage_symlink