Code

reset: Make reset remove the sequencer state
authorRamkumar Ramachandra <artagnon@gmail.com>
Thu, 4 Aug 2011 10:39:12 +0000 (16:09 +0530)
committerJunio C Hamano <gitster@pobox.com>
Mon, 8 Aug 2011 16:24:50 +0000 (09:24 -0700)
Years of muscle memory have trained users to use "git reset --hard" to
remove the branch state after any sort operation.  Make it also remove
the sequencer state to facilitate this established workflow:

  $ git cherry-pick foo..bar
  ... conflict encountered ...
  $ git reset --hard # Oops, I didn't mean that
  $ git cherry-pick quux..bar
  ... cherry-pick succeeded ...

Guard against accidental removal of the sequencer state by providing
one level of "undo".  In the first "reset" invocation,
".git/sequencer" is moved to ".git/sequencer-old"; it is completely
removed only in the second invocation.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
branch.c
t/t7106-reset-sequence.sh [new file with mode: 0755]

index c0c865a4b1b0fca038f32b77f2239d7987438ff5..d06aec4637ca26a473d7cb45ecc97114db656db1 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -3,6 +3,7 @@
 #include "refs.h"
 #include "remote.h"
 #include "commit.h"
+#include "sequencer.h"
 
 struct tracking {
        struct refspec spec;
@@ -228,4 +229,5 @@ void remove_branch_state(void)
        unlink(git_path("MERGE_MSG"));
        unlink(git_path("MERGE_MODE"));
        unlink(git_path("SQUASH_MSG"));
+       remove_sequencer_state(0);
 }
diff --git a/t/t7106-reset-sequence.sh b/t/t7106-reset-sequence.sh
new file mode 100755 (executable)
index 0000000..4956caa
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+test_description='Test interaction of reset --hard with sequencer
+
+  + anotherpick: rewrites foo to d
+  + picked: rewrites foo to c
+  + unrelatedpick: rewrites unrelated to reallyunrelated
+  + base: rewrites foo to b
+  + initial: writes foo as a, unrelated as unrelated
+'
+
+. ./test-lib.sh
+
+pristine_detach () {
+       git cherry-pick --reset &&
+       git checkout -f "$1^0" &&
+       git read-tree -u --reset HEAD &&
+       git clean -d -f -f -q -x
+}
+
+test_expect_success setup '
+       echo unrelated >unrelated &&
+       git add unrelated &&
+       test_commit initial foo a &&
+       test_commit base foo b &&
+       test_commit unrelatedpick unrelated reallyunrelated &&
+       test_commit picked foo c &&
+       test_commit anotherpick foo d &&
+       git config advice.detachedhead false
+
+'
+
+test_expect_success 'reset --hard cleans up sequencer state, providing one-level undo' '
+       pristine_detach initial &&
+       test_must_fail git cherry-pick base..anotherpick &&
+       test_path_is_dir .git/sequencer &&
+       git reset --hard &&
+       test_path_is_missing .git/sequencer &&
+       test_path_is_dir .git/sequencer-old &&
+       git reset --hard &&
+       test_path_is_missing .git/sequencer-old
+'
+
+test_done