status: better advices when splitting a commit (during rebase -i)
Add new informative help messages at the output of 'git status' when the user is splitting a commit. The code figures this state by comparing the contents of the following files in the .git/ directory: - HEAD - ORIG_HEAD - rebase-merge/amend - rebase-merge/orig-head Signed-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr> Signed-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr> Signed-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr> Signed-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr> Signed-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr> Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Lucien Kong committed
Jun 10, 2012 at 13:17 UTC
2d1ccebae41541946ddd7e32f291f3c8983feea9
2 files changed
+329
t/t7512-status-help.sh
+277
@@ -196,6 +196,283 @@ test_expect_success 'status when rebasing -i in edit mode' '
196
'
197
198
199
+test_expect_success 'status when splitting a commit' '
200
+ git reset --hard master &&
201
+ git checkout -b split_commit &&
202
+ test_commit one_split main.txt one &&
203
+ test_commit two_split main.txt two &&
204
+ test_commit three_split main.txt three &&
205
+ test_commit four_split main.txt four &&
206
+ FAKE_LINES="1 edit 2 3" &&
207
+ export FAKE_LINES &&
208
+ test_when_finished "git rebase --abort" &&
209
+ git rebase -i HEAD~3 &&
210
+ git reset HEAD^ &&
211
+ cat >expected <<-\EOF &&
212
+ # Not currently on any branch.
213
+ # You are currently splitting a commit during a rebase.
214
+ # (Once your working directory is clean, run "git rebase --continue")
215
+ #
216
+ # Changes not staged for commit:
217
+ # (use "git add <file>..." to update what will be committed)
218
+ # (use "git checkout -- <file>..." to discard changes in working directory)
219
+ #
220
+ # modified: main.txt
221
+ #
222
+ no changes added to commit (use "git add" and/or "git commit -a")
223
+ EOF
224
+ git status --untracked-files=no >actual &&
225
+ test_i18ncmp expected actual
226
+'
227
+
228
+
229
+test_expect_success 'status after editing the last commit with --amend during a rebase -i' '
230
+ git reset --hard master &&
231
+ git checkout -b amend_last &&
232
+ test_commit one_amend main.txt one &&
233
+ test_commit two_amend main.txt two &&
234
+ test_commit three_amend main.txt three &&
235
+ test_commit four_amend main.txt four &&
236
+ FAKE_LINES="1 2 edit 3" &&
237
+ export FAKE_LINES &&
238
+ test_when_finished "git rebase --abort" &&
239
+ git rebase -i HEAD~3 &&
240
+ git commit --amend -m "foo" &&
241
+ cat >expected <<-\EOF &&
242
+ # Not currently on any branch.
243
+ # You are currently editing a commit during a rebase.
244
+ # (use "git commit --amend" to amend the current commit)
245
+ # (use "git rebase --continue" once you are satisfied with your changes)
246
+ #
247
+ nothing to commit (use -u to show untracked files)
248
+ EOF
249
+ git status --untracked-files=no >actual &&
250
+ test_i18ncmp expected actual
251
+'
252
+
253
+
254
+test_expect_success 'prepare for several edits' '
255
+ git reset --hard master &&
256
+ git checkout -b several_edits &&
257
+ test_commit one_edits main.txt one &&
258
+ test_commit two_edits main.txt two &&
259
+ test_commit three_edits main.txt three &&
260
+ test_commit four_edits main.txt four
261
+'
262
+
263
+
264
+test_expect_success 'status: (continue first edit) second edit' '
265
+ FAKE_LINES="edit 1 edit 2 3" &&
266
+ export FAKE_LINES &&
267
+ test_when_finished "git rebase --abort" &&
268
+ git rebase -i HEAD~3 &&
269
+ git rebase --continue &&
270
+ cat >expected <<-\EOF &&
271
+ # Not currently on any branch.
272
+ # You are currently editing a commit during a rebase.
273
+ # (use "git commit --amend" to amend the current commit)
274
+ # (use "git rebase --continue" once you are satisfied with your changes)
275
+ #
276
+ nothing to commit (use -u to show untracked files)
277
+ EOF
278
+ git status --untracked-files=no >actual &&
279
+ test_i18ncmp expected actual
280
+'
281
+
282
+
283
+test_expect_success 'status: (continue first edit) second edit and split' '
284
+ git reset --hard several_edits &&
285
+ FAKE_LINES="edit 1 edit 2 3" &&
286
+ export FAKE_LINES &&
287
+ test_when_finished "git rebase --abort" &&
288
+ git rebase -i HEAD~3 &&
289
+ git rebase --continue &&
290
+ git reset HEAD^ &&
291
+ cat >expected <<-\EOF &&
292
+ # Not currently on any branch.
293
+ # You are currently splitting a commit during a rebase.
294
+ # (Once your working directory is clean, run "git rebase --continue")
295
+ #
296
+ # Changes not staged for commit:
297
+ # (use "git add <file>..." to update what will be committed)
298
+ # (use "git checkout -- <file>..." to discard changes in working directory)
299
+ #
300
+ # modified: main.txt
301
+ #
302
+ no changes added to commit (use "git add" and/or "git commit -a")
303
+ EOF
304
+ git status --untracked-files=no >actual &&
305
+ test_i18ncmp expected actual
306
+'
307
+
308
+
309
+test_expect_success 'status: (continue first edit) second edit and amend' '
310
+ git reset --hard several_edits &&
311
+ FAKE_LINES="edit 1 edit 2 3" &&
312
+ export FAKE_LINES &&
313
+ test_when_finished "git rebase --abort" &&
314
+ git rebase -i HEAD~3 &&
315
+ git rebase --continue &&
316
+ git commit --amend -m "foo" &&
317
+ cat >expected <<-\EOF &&
318
+ # Not currently on any branch.
319
+ # You are currently editing a commit during a rebase.
320
+ # (use "git commit --amend" to amend the current commit)
321
+ # (use "git rebase --continue" once you are satisfied with your changes)
322
+ #
323
+ nothing to commit (use -u to show untracked files)
324
+ EOF
325
+ git status --untracked-files=no >actual &&
326
+ test_i18ncmp expected actual
327
+'
328
+
329
+
330
+test_expect_success 'status: (amend first edit) second edit' '
331
+ git reset --hard several_edits &&
332
+ FAKE_LINES="edit 1 edit 2 3" &&
333
+ export FAKE_LINES &&
334
+ test_when_finished "git rebase --abort" &&
335
+ git rebase -i HEAD~3 &&
336
+ git commit --amend -m "a" &&
337
+ git rebase --continue &&
338
+ cat >expected <<-\EOF &&
339
+ # Not currently on any branch.
340
+ # You are currently editing a commit during a rebase.
341
+ # (use "git commit --amend" to amend the current commit)
342
+ # (use "git rebase --continue" once you are satisfied with your changes)
343
+ #
344
+ nothing to commit (use -u to show untracked files)
345
+ EOF
346
+ git status --untracked-files=no >actual &&
347
+ test_i18ncmp expected actual
348
+'
349
+
350
+
351
+test_expect_success 'status: (amend first edit) second edit and split' '
352
+ git reset --hard several_edits &&
353
+ FAKE_LINES="edit 1 edit 2 3" &&
354
+ export FAKE_LINES &&
355
+ test_when_finished "git rebase --abort" &&
356
+ git rebase -i HEAD~3 &&
357
+ git commit --amend -m "b" &&
358
+ git rebase --continue &&
359
+ git reset HEAD^ &&
360
+ cat >expected <<-\EOF &&
361
+ # Not currently on any branch.
362
+ # You are currently splitting a commit during a rebase.
363
+ # (Once your working directory is clean, run "git rebase --continue")
364
+ #
365
+ # Changes not staged for commit:
366
+ # (use "git add <file>..." to update what will be committed)
367
+ # (use "git checkout -- <file>..." to discard changes in working directory)
368
+ #
369
+ # modified: main.txt
370
+ #
371
+ no changes added to commit (use "git add" and/or "git commit -a")
372
+ EOF
373
+ git status --untracked-files=no >actual &&
374
+ test_i18ncmp expected actual
375
+'
376
+
377
+
378
+test_expect_success 'status: (amend first edit) second edit and amend' '
379
+ git reset --hard several_edits &&
380
+ FAKE_LINES="edit 1 edit 2 3" &&
381
+ export FAKE_LINES &&
382
+ test_when_finished "git rebase --abort" &&
383
+ git rebase -i HEAD~3 &&
384
+ git commit --amend -m "c" &&
385
+ git rebase --continue &&
386
+ git commit --amend -m "d" &&
387
+ cat >expected <<-\EOF &&
388
+ # Not currently on any branch.
389
+ # You are currently editing a commit during a rebase.
390
+ # (use "git commit --amend" to amend the current commit)
391
+ # (use "git rebase --continue" once you are satisfied with your changes)
392
+ #
393
+ nothing to commit (use -u to show untracked files)
394
+ EOF
395
+ git status --untracked-files=no >actual &&
396
+ test_i18ncmp expected actual
397
+'
398
+
399
+
400
+test_expect_success 'status: (split first edit) second edit' '
401
+ git reset --hard several_edits &&
402
+ FAKE_LINES="edit 1 edit 2 3" &&
403
+ export FAKE_LINES &&
404
+ test_when_finished "git rebase --abort" &&
405
+ git rebase -i HEAD~3 &&
406
+ git reset HEAD^ &&
407
+ git add main.txt &&
408
+ git commit -m "e" &&
409
+ git rebase --continue &&
410
+ cat >expected <<-\EOF &&
411
+ # Not currently on any branch.
412
+ # You are currently editing a commit during a rebase.
413
+ # (use "git commit --amend" to amend the current commit)
414
+ # (use "git rebase --continue" once you are satisfied with your changes)
415
+ #
416
+ nothing to commit (use -u to show untracked files)
417
+ EOF
418
+ git status --untracked-files=no >actual &&
419
+ test_i18ncmp expected actual
420
+'
421
+
422
+
423
+test_expect_success 'status: (split first edit) second edit and split' '
424
+ git reset --hard several_edits &&
425
+ FAKE_LINES="edit 1 edit 2 3" &&
426
+ export FAKE_LINES &&
427
+ test_when_finished "git rebase --abort" &&
428
+ git rebase -i HEAD~3 &&
429
+ git reset HEAD^ &&
430
+ git add main.txt &&
431
+ git commit --amend -m "f" &&
432
+ git rebase --continue &&
433
+ git reset HEAD^ &&
434
+ cat >expected <<-\EOF &&
435
+ # Not currently on any branch.
436
+ # You are currently splitting a commit during a rebase.
437
+ # (Once your working directory is clean, run "git rebase --continue")
438
+ #
439
+ # Changes not staged for commit:
440
+ # (use "git add <file>..." to update what will be committed)
441
+ # (use "git checkout -- <file>..." to discard changes in working directory)
442
+ #
443
+ # modified: main.txt
444
+ #
445
+ no changes added to commit (use "git add" and/or "git commit -a")
446
+ EOF
447
+ git status --untracked-files=no >actual &&
448
+ test_i18ncmp expected actual
449
+'
450
+
451
+
452
+test_expect_success 'status: (split first edit) second edit and amend' '
453
+ git reset --hard several_edits &&
454
+ FAKE_LINES="edit 1 edit 2 3" &&
455
+ export FAKE_LINES &&
456
+ test_when_finished "git rebase --abort" &&
457
+ git rebase -i HEAD~3 &&
458
+ git reset HEAD^ &&
459
+ git add main.txt &&
460
+ git commit --amend -m "g" &&
461
+ git rebase --continue &&
462
+ git commit --amend -m "h" &&
463
+ cat >expected <<-\EOF &&
464
+ # Not currently on any branch.
465
+ # You are currently editing a commit during a rebase.
466
+ # (use "git commit --amend" to amend the current commit)
467
+ # (use "git rebase --continue" once you are satisfied with your changes)
468
+ #
469
+ nothing to commit (use -u to show untracked files)
470
+ EOF
471
+ git status --untracked-files=no >actual &&
472
+ test_i18ncmp expected actual
473
+'
474
+
475
+
476
test_expect_success 'prepare am_session' '
477
git reset --hard master &&
478
git checkout -b am_session &&
wt-status.c
+52
@@ -12,6 +12,7 @@
12
#include "refs.h"
13
#include "submodule.h"
14
#include "column.h"
15
+#include "strbuf.h"
16
17
static char default_wt_status_colors[][COLOR_MAXLEN] = {
18
GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
@@ -817,6 +818,52 @@ static void show_am_in_progress(struct wt_status *s,
818
wt_status_print_trailer(s);
819
}
820
821
+static char *read_line_from_git_path(const char *filename)
822
+{
823
+ struct strbuf buf = STRBUF_INIT;
824
+ FILE *fp = fopen(git_path("%s", filename), "r");
825
+ if (!fp) {
826
+ strbuf_release(&buf);
827
+ return NULL;
828
+ }
829
+ strbuf_getline(&buf, fp, '\n');
830
+ if (!fclose(fp)) {
831
+ return strbuf_detach(&buf, NULL);
832
+ } else {
833
+ strbuf_release(&buf);
834
+ return NULL;
835
+ }
836
+}
837
+
838
+static int split_commit_in_progress(struct wt_status *s)
839
+{
840
+ int split_in_progress = 0;
841
+ char *head = read_line_from_git_path("HEAD");
842
+ char *orig_head = read_line_from_git_path("ORIG_HEAD");
843
+ char *rebase_amend = read_line_from_git_path("rebase-merge/amend");
844
+ char *rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");
845
+
846
+ if (!head || !orig_head || !rebase_amend || !rebase_orig_head ||
847
+ !s->branch || strcmp(s->branch, "HEAD"))
848
+ return split_in_progress;
849
+
850
+ if (!strcmp(rebase_amend, rebase_orig_head)) {
851
+ if (strcmp(head, rebase_amend))
852
+ split_in_progress = 1;
853
+ } else if (strcmp(orig_head, rebase_orig_head)) {
854
+ split_in_progress = 1;
855
+ }
856
+
857
+ if (!s->amend && !s->nowarn && !s->workdir_dirty)
858
+ split_in_progress = 0;
859
+
860
+ free(head);
861
+ free(orig_head);
862
+ free(rebase_amend);
863
+ free(rebase_orig_head);
864
+ return split_in_progress;
865
+}
866
+
867
static void show_rebase_in_progress(struct wt_status *s,
868
struct wt_status_state *state,
869
const char *color)
@@ -838,6 +885,11 @@ static void show_rebase_in_progress(struct wt_status *s,
885
if (advice_status_hints)
886
status_printf_ln(s, color,
887
_(" (all conflicts fixed: run \"git rebase --continue\")"));
888
+ } else if (split_commit_in_progress(s)) {
889
+ status_printf_ln(s, color, _("You are currently splitting a commit during a rebase."));
890
+ if (advice_status_hints)
891
+ status_printf_ln(s, color,
892
+ _(" (Once your working directory is clean, run \"git rebase --continue\")"));
893
} else {
894
status_printf_ln(s, color, _("You are currently editing a commit during a rebase."));
895
if (advice_status_hints && !s->amend) {