reset: disallow using --keep when there are unmerged entries
The use case for --keep option is to remove previous commits unrelated to the current changes in the working tree. So in this use case we are not supposed to have unmerged entries. This is why it seems safer to just disallow using --keep when there are unmerged entries. And this patch changes the error message when --keep was disallowed and there were some unmerged entries from: error: Entry 'file1' would be overwritten by merge. Cannot merge. fatal: Could not reset index file to revision 'HEAD^'. to: fatal: Cannot do a keep reset in the middle of a merge. which is nicer. Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Christian Couder committed
Jan 19, 2010 at 05:26 UTC
812d2a3d61b1bbb1931aff2ed6d2a17e939f5bf2
4 files changed
+28
-22
Documentation/git-reset.txt
+3
-2
@@ -155,7 +155,8 @@ tree. If there could be conflicts between the changes in the commit we
155
want to remove and the changes in the working tree we want to keep,
156
the reset is disallowed. That's why it is disallowed if there are both
157
changes between the working tree and HEAD, and between HEAD and the
158
-target.
158
+target. To be safe, it is also disallowed when there are unmerged
159
+entries.
160
161
The following tables show what happens when there are unmerged
162
entries:
@@ -174,7 +175,7 @@ entries:
175
--mixed X A A
176
--hard A A A
177
--merge A A A
177
- --keep X A A
178
+ --keep (disallowed)
179
180
X means any state and U means an unmerged index.
181
builtin-reset.c
+15
-5
@@ -224,6 +224,14 @@ static void prepend_reflog_action(const char *action, char *buf, size_t size)
224
warning("Reflog action message too long: %.*s...", 50, buf);
225
}
226
227
+static void die_if_unmerged_cache(int reset_type)
228
+{
229
+ if (is_merge() || read_cache() < 0 || unmerged_cache())
230
+ die("Cannot do a %s reset in the middle of a merge.",
231
+ reset_type_names[reset_type]);
232
+
233
+}
234
+
235
int cmd_reset(int argc, const char **argv, const char *prefix)
236
{
237
int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0;
@@ -329,11 +337,13 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
337
/* Soft reset does not touch the index file nor the working tree
338
* at all, but requires them in a good order. Other resets reset
339
* the index file to the tree object we are switching to. */
332
- if (reset_type == SOFT) {
333
- if (is_merge() || read_cache() < 0 || unmerged_cache())
334
- die("Cannot do a soft reset in the middle of a merge.");
335
- } else {
336
- int err = reset_index_file(sha1, reset_type, quiet);
340
+ if (reset_type == SOFT)
341
+ die_if_unmerged_cache(reset_type);
342
+ else {
343
+ int err;
344
+ if (reset_type == KEEP)
345
+ die_if_unmerged_cache(reset_type);
346
+ err = reset_index_file(sha1, reset_type, quiet);
347
if (reset_type == KEEP)
348
err = err || reset_index_file(sha1, MIXED, quiet);
349
if (err)
t/t7110-reset-merge.sh
+9
-14
@@ -237,7 +237,7 @@ test_expect_success '"reset --keep HEAD^" fails with pending merge' '
237
git reset --hard third &&
238
test_must_fail git merge branch1 &&
239
test_must_fail git reset --keep HEAD^ 2>err.log &&
240
- grep file1 err.log | grep "overwritten by merge"
240
+ grep "middle of a merge" err.log
241
'
242
243
# The next test will test the following:
@@ -258,18 +258,15 @@ test_expect_success '"reset --merge HEAD" is ok with pending merge' '
258
#
259
# working index HEAD target working index HEAD
260
# ----------------------------------------------------
261
-# file1: X U B B --keep X B B
262
-test_expect_success '"reset --keep HEAD" is ok with pending merge' '
261
+# file1: X U B B --keep (disallowed)
262
+test_expect_success '"reset --keep HEAD" fails with pending merge' '
263
git reset --hard third &&
264
test_must_fail git merge branch1 &&
265
- cat file1 >orig_file1 &&
266
- git reset --keep HEAD &&
267
- test "$(git rev-parse HEAD)" = "$(git rev-parse third)" &&
268
- test -z "$(git diff --cached)" &&
269
- test_cmp file1 orig_file1
265
+ test_must_fail git reset --keep HEAD 2>err.log &&
266
+ grep "middle of a merge" err.log
267
'
268
272
-test_expect_success '--merge with added/deleted' '
269
+test_expect_success '--merge is ok with added/deleted merge' '
270
git reset --hard third &&
271
rm -f file2 &&
272
test_must_fail git merge branch3 &&
@@ -283,7 +280,7 @@ test_expect_success '--merge with added/deleted' '
280
git diff --exit-code --cached
281
'
282
286
-test_expect_success '--keep with added/deleted' '
283
+test_expect_success '--keep fails with added/deleted merge' '
284
git reset --hard third &&
285
rm -f file2 &&
286
test_must_fail git merge branch3 &&
@@ -291,10 +288,8 @@ test_expect_success '--keep with added/deleted' '
288
test -f file3 &&
289
git diff --exit-code file3 &&
290
git diff --exit-code branch3 file3 &&
294
- git reset --keep HEAD &&
295
- test -f file3 &&
296
- ! test -f file2 &&
297
- git diff --exit-code --cached
291
+ test_must_fail git reset --keep HEAD 2>err.log &&
292
+ grep "middle of a merge" err.log
293
'
294
295
test_done
t/t7111-reset-table.sh
+1
-1
@@ -115,7 +115,7 @@ X U B B soft XXXXX
115
X U B B mixed X B B
116
X U B B hard B B B
117
X U B B merge B B B
118
-X U B B keep X B B
118
+X U B B keep XXXXX
119
EOF
120
121
test_done