Skip to content

Commit

Permalink
status: better advices when splitting a commit (during rebase -i)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Lucien Kong authored and Junio C Hamano committed Jun 14, 2012
1 parent 96b0ec1 commit 2d1cceb
Show file tree
Hide file tree
Showing 2 changed files with 329 additions and 0 deletions.
277 changes: 277 additions & 0 deletions t/t7512-status-help.sh
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,283 @@ test_expect_success 'status when rebasing -i in edit mode' '
'


test_expect_success 'status when splitting a commit' '
git reset --hard master &&
git checkout -b split_commit &&
test_commit one_split main.txt one &&
test_commit two_split main.txt two &&
test_commit three_split main.txt three &&
test_commit four_split main.txt four &&
FAKE_LINES="1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git reset HEAD^ &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently splitting a commit during a rebase.
# (Once your working directory is clean, run "git rebase --continue")
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: main.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'status after editing the last commit with --amend during a rebase -i' '
git reset --hard master &&
git checkout -b amend_last &&
test_commit one_amend main.txt one &&
test_commit two_amend main.txt two &&
test_commit three_amend main.txt three &&
test_commit four_amend main.txt four &&
FAKE_LINES="1 2 edit 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git commit --amend -m "foo" &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently editing a commit during a rebase.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
nothing to commit (use -u to show untracked files)
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'prepare for several edits' '
git reset --hard master &&
git checkout -b several_edits &&
test_commit one_edits main.txt one &&
test_commit two_edits main.txt two &&
test_commit three_edits main.txt three &&
test_commit four_edits main.txt four
'


test_expect_success 'status: (continue first edit) second edit' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git rebase --continue &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently editing a commit during a rebase.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
nothing to commit (use -u to show untracked files)
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'status: (continue first edit) second edit and split' '
git reset --hard several_edits &&
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git rebase --continue &&
git reset HEAD^ &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently splitting a commit during a rebase.
# (Once your working directory is clean, run "git rebase --continue")
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: main.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'status: (continue first edit) second edit and amend' '
git reset --hard several_edits &&
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git rebase --continue &&
git commit --amend -m "foo" &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently editing a commit during a rebase.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
nothing to commit (use -u to show untracked files)
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'status: (amend first edit) second edit' '
git reset --hard several_edits &&
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git commit --amend -m "a" &&
git rebase --continue &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently editing a commit during a rebase.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
nothing to commit (use -u to show untracked files)
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'status: (amend first edit) second edit and split' '
git reset --hard several_edits &&
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git commit --amend -m "b" &&
git rebase --continue &&
git reset HEAD^ &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently splitting a commit during a rebase.
# (Once your working directory is clean, run "git rebase --continue")
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: main.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'status: (amend first edit) second edit and amend' '
git reset --hard several_edits &&
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git commit --amend -m "c" &&
git rebase --continue &&
git commit --amend -m "d" &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently editing a commit during a rebase.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
nothing to commit (use -u to show untracked files)
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'status: (split first edit) second edit' '
git reset --hard several_edits &&
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git reset HEAD^ &&
git add main.txt &&
git commit -m "e" &&
git rebase --continue &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently editing a commit during a rebase.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
nothing to commit (use -u to show untracked files)
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'status: (split first edit) second edit and split' '
git reset --hard several_edits &&
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git reset HEAD^ &&
git add main.txt &&
git commit --amend -m "f" &&
git rebase --continue &&
git reset HEAD^ &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently splitting a commit during a rebase.
# (Once your working directory is clean, run "git rebase --continue")
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: main.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'status: (split first edit) second edit and amend' '
git reset --hard several_edits &&
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
git rebase -i HEAD~3 &&
git reset HEAD^ &&
git add main.txt &&
git commit --amend -m "g" &&
git rebase --continue &&
git commit --amend -m "h" &&
cat >expected <<-\EOF &&
# Not currently on any branch.
# You are currently editing a commit during a rebase.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
nothing to commit (use -u to show untracked files)
EOF
git status --untracked-files=no >actual &&
test_i18ncmp expected actual
'


test_expect_success 'prepare am_session' '
git reset --hard master &&
git checkout -b am_session &&
Expand Down
52 changes: 52 additions & 0 deletions wt-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "refs.h"
#include "submodule.h"
#include "column.h"
#include "strbuf.h"

static char default_wt_status_colors[][COLOR_MAXLEN] = {
GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
Expand Down Expand Up @@ -817,6 +818,52 @@ static void show_am_in_progress(struct wt_status *s,
wt_status_print_trailer(s);
}

static char *read_line_from_git_path(const char *filename)
{
struct strbuf buf = STRBUF_INIT;
FILE *fp = fopen(git_path("%s", filename), "r");
if (!fp) {
strbuf_release(&buf);
return NULL;
}
strbuf_getline(&buf, fp, '\n');
if (!fclose(fp)) {
return strbuf_detach(&buf, NULL);
} else {
strbuf_release(&buf);
return NULL;
}
}

static int split_commit_in_progress(struct wt_status *s)
{
int split_in_progress = 0;
char *head = read_line_from_git_path("HEAD");
char *orig_head = read_line_from_git_path("ORIG_HEAD");
char *rebase_amend = read_line_from_git_path("rebase-merge/amend");
char *rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");

if (!head || !orig_head || !rebase_amend || !rebase_orig_head ||
!s->branch || strcmp(s->branch, "HEAD"))
return split_in_progress;

if (!strcmp(rebase_amend, rebase_orig_head)) {
if (strcmp(head, rebase_amend))
split_in_progress = 1;
} else if (strcmp(orig_head, rebase_orig_head)) {
split_in_progress = 1;
}

if (!s->amend && !s->nowarn && !s->workdir_dirty)
split_in_progress = 0;

free(head);
free(orig_head);
free(rebase_amend);
free(rebase_orig_head);
return split_in_progress;
}

static void show_rebase_in_progress(struct wt_status *s,
struct wt_status_state *state,
const char *color)
Expand All @@ -838,6 +885,11 @@ static void show_rebase_in_progress(struct wt_status *s,
if (advice_status_hints)
status_printf_ln(s, color,
_(" (all conflicts fixed: run \"git rebase --continue\")"));
} else if (split_commit_in_progress(s)) {
status_printf_ln(s, color, _("You are currently splitting a commit during a rebase."));
if (advice_status_hints)
status_printf_ln(s, color,
_(" (Once your working directory is clean, run \"git rebase --continue\")"));
} else {
status_printf_ln(s, color, _("You are currently editing a commit during a rebase."));
if (advice_status_hints && !s->amend) {
Expand Down

0 comments on commit 2d1cceb

Please sign in to comment.