Skip to content

Commit

Permalink
Merge branch 'sg/rebase-progress'
Browse files Browse the repository at this point in the history
Use "Erase in Line" CSI sequence that is already used in the editor
support to clear cruft in the progress output.

* sg/rebase-progress:
  progress: use term_clear_line()
  rebase: fix garbled progress display with '-x'
  pager: add a helper function to clear the last line in the terminal
  t3404: make the 'rebase.missingCommitsCheck=ignore' test more focused
  t3404: modernize here doc style
  • Loading branch information
gitster committed Jul 9, 2019
2 parents 88176b7 + 5b12e31 commit 6624e07
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 98 deletions.
1 change: 1 addition & 0 deletions cache.h
Expand Up @@ -1735,6 +1735,7 @@ void setup_pager(void);
int pager_in_use(void);
extern int pager_use_color;
int term_columns(void);
void term_clear_line(void);
int decimal_width(uintmax_t);
int check_pager_config(const char *cmd);
void prepare_pager_args(struct child_process *, const char *pager);
Expand Down
6 changes: 3 additions & 3 deletions editor.c
Expand Up @@ -96,10 +96,10 @@ static int launch_specified_editor(const char *editor, const char *path,

if (print_waiting_for_editor && !is_terminal_dumb())
/*
* Go back to the beginning and erase the entire line to
* avoid wasting the vertical space.
* Erase the entire line to avoid wasting the
* vertical space.
*/
fputs("\r\033[K", stderr);
term_clear_line();
}

if (!buffer)
Expand Down
20 changes: 20 additions & 0 deletions pager.c
Expand Up @@ -177,6 +177,26 @@ int term_columns(void)
return term_columns_at_startup;
}

/*
* Clear the entire line, leave cursor in first column.
*/
void term_clear_line(void)
{
if (is_terminal_dumb())
/*
* Fall back to print a terminal width worth of space
* characters (hoping that the terminal is still as wide
* as it was upon the first call to term_columns()).
*/
fprintf(stderr, "\r%*s\r", term_columns(), "");
else
/*
* On non-dumb terminals use an escape sequence to clear
* the whole line, no matter how wide the terminal.
*/
fputs("\r\033[K", stderr);
}

/*
* How many columns do we need to show this number in decimal?
*/
Expand Down
28 changes: 11 additions & 17 deletions progress.c
Expand Up @@ -88,7 +88,6 @@ static void display(struct progress *progress, uint64_t n, const char *done)
const char *tp;
struct strbuf *counters_sb = &progress->counters_sb;
int show_update = 0;
int last_count_len = counters_sb->len;

if (progress->delay && (!progress_update || --progress->delay))
return;
Expand Down Expand Up @@ -116,26 +115,21 @@ static void display(struct progress *progress, uint64_t n, const char *done)
if (show_update) {
if (is_foreground_fd(fileno(stderr)) || done) {
const char *eol = done ? done : "\r";
size_t clear_len = counters_sb->len < last_count_len ?
last_count_len - counters_sb->len + 1 :
0;
size_t progress_line_len = progress->title_len +
counters_sb->len + 2;
int cols = term_columns();

term_clear_line();
if (progress->split) {
fprintf(stderr, " %s%*s", counters_sb->buf,
(int) clear_len, eol);
} else if (!done && cols < progress_line_len) {
clear_len = progress->title_len + 1 < cols ?
cols - progress->title_len - 1 : 0;
fprintf(stderr, "%s:%*s\n %s%s",
progress->title, (int) clear_len, "",
counters_sb->buf, eol);
fprintf(stderr, " %s%s", counters_sb->buf,
eol);
} else if (!done &&
/* The "+ 2" accounts for the ": ". */
term_columns() < progress->title_len +
counters_sb->len + 2) {
fprintf(stderr, "%s:\n %s%s",
progress->title, counters_sb->buf, eol);
progress->split = 1;
} else {
fprintf(stderr, "%s: %s%*s", progress->title,
counters_sb->buf, (int) clear_len, eol);
fprintf(stderr, "%s: %s%s", progress->title,
counters_sb->buf, eol);
}
fflush(stderr);
}
Expand Down
17 changes: 14 additions & 3 deletions sequencer.c
Expand Up @@ -3741,8 +3741,11 @@ static int pick_commits(struct repository *r,
unlink(git_path_merge_head(the_repository));
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);

if (item->command == TODO_BREAK)
if (item->command == TODO_BREAK) {
if (!opts->verbose)
term_clear_line();
return stopped_at_head(r);
}
}
if (item->command <= TODO_SQUASH) {
if (is_rebase_i(opts))
Expand All @@ -3764,11 +3767,14 @@ static int pick_commits(struct repository *r,
}
if (item->command == TODO_EDIT) {
struct commit *commit = item->commit;
if (!res)
if (!res) {
if (!opts->verbose)
term_clear_line();
fprintf(stderr,
_("Stopped at %s... %.*s\n"),
short_commit_name(commit),
item->arg_len, arg);
}
return error_with_patch(r, commit,
arg, item->arg_len, opts, res, !res);
}
Expand Down Expand Up @@ -3806,6 +3812,8 @@ static int pick_commits(struct repository *r,
int saved = *end_of_arg;
struct stat st;

if (!opts->verbose)
term_clear_line();
*end_of_arg = '\0';
res = do_exec(r, arg);
*end_of_arg = saved;
Expand Down Expand Up @@ -3964,10 +3972,13 @@ static int pick_commits(struct repository *r,
}
apply_autostash(opts);

if (!opts->quiet)
if (!opts->quiet) {
if (!opts->verbose)
term_clear_line();
fprintf(stderr,
"Successfully rebased and updated %s.\n",
head_ref.buf);
}

strbuf_release(&buf);
strbuf_release(&head_ref);
Expand Down
120 changes: 50 additions & 70 deletions t/t3404-rebase-interactive.sh
Expand Up @@ -75,11 +75,10 @@ test_expect_success 'rebase --keep-empty' '
test_line_count = 6 actual
'

cat > expect <<EOF
error: nothing to do
EOF

test_expect_success 'rebase -i with empty HEAD' '
cat >expect <<-\EOF &&
error: nothing to do
EOF
set_fake_editor &&
test_must_fail env FAKE_LINES="1 exec_true" git rebase -i HEAD^ >actual 2>&1 &&
test_i18ncmp expect actual
Expand Down Expand Up @@ -237,25 +236,23 @@ test_expect_success 'exchange two commits' '
test G = $(git cat-file commit HEAD | sed -ne \$p)
'

cat > expect << EOF
diff --git a/file1 b/file1
index f70f10e..fd79235 100644
--- a/file1
+++ b/file1
@@ -1 +1 @@
-A
+G
EOF

cat > expect2 << EOF
<<<<<<< HEAD
D
=======
G
>>>>>>> 5d18e54... G
EOF

test_expect_success 'stop on conflicting pick' '
cat >expect <<-\EOF &&
diff --git a/file1 b/file1
index f70f10e..fd79235 100644
--- a/file1
+++ b/file1
@@ -1 +1 @@
-A
+G
EOF
cat >expect2 <<-\EOF &&
<<<<<<< HEAD
D
=======
G
>>>>>>> 5d18e54... G
EOF
git tag new-branch1 &&
set_fake_editor &&
test_must_fail git rebase -i master &&
Expand Down Expand Up @@ -495,15 +492,14 @@ test_expect_success 'commit message retained after conflict' '
git branch -D conflict-squash
'

cat > expect-squash-fixup << EOF
B
D
test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messages' '
cat >expect-squash-fixup <<-\EOF &&
B
ONCE
EOF
D
test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messages' '
ONCE
EOF
git checkout -b squash-fixup E &&
base=$(git rev-parse HEAD~4) &&
set_fake_editor &&
Expand Down Expand Up @@ -799,13 +795,12 @@ test_expect_success 'rebase -i can copy notes' '
test "a note" = "$(git notes show HEAD)"
'

cat >expect <<EOF
an earlier note
a note
EOF

test_expect_success 'rebase -i can copy notes over a fixup' '
cat >expect <<-\EOF &&
an earlier note
a note
EOF
git reset --hard n3 &&
git notes add -m"an earlier note" n2 &&
set_fake_editor &&
Expand Down Expand Up @@ -1304,52 +1299,37 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = ignore' '
actual
'

cat >expect <<EOF
Warning: some commits may have been dropped accidentally.
Dropped commits (newer to older):
- $(git rev-list --pretty=oneline --abbrev-commit -1 master)
To avoid this message, use "drop" to explicitly remove a commit.
Use 'git config rebase.missingCommitsCheck' to change the level of warnings.
The possible behaviours are: ignore, warn, error.
Rebasing (1/4)
Rebasing (2/4)
Rebasing (3/4)
Rebasing (4/4)
Successfully rebased and updated refs/heads/missing-commit.
EOF

cr_to_nl () {
tr '\015' '\012'
}

test_expect_success 'rebase -i respects rebase.missingCommitsCheck = warn' '
cat >expect <<-EOF &&
Warning: some commits may have been dropped accidentally.
Dropped commits (newer to older):
- $(git rev-list --pretty=oneline --abbrev-commit -1 master)
To avoid this message, use "drop" to explicitly remove a commit.
EOF
test_config rebase.missingCommitsCheck warn &&
rebase_setup_and_clean missing-commit &&
set_fake_editor &&
FAKE_LINES="1 2 3 4" \
git rebase -i --root 2>actual.2 &&
cr_to_nl <actual.2 >actual &&
head -n4 actual.2 >actual &&
test_i18ncmp expect actual &&
test D = $(git cat-file commit HEAD | sed -ne \$p)
'

cat >expect <<EOF
Warning: some commits may have been dropped accidentally.
Dropped commits (newer to older):
- $(git rev-list --pretty=oneline --abbrev-commit -1 master)
- $(git rev-list --pretty=oneline --abbrev-commit -1 master~2)
To avoid this message, use "drop" to explicitly remove a commit.
Use 'git config rebase.missingCommitsCheck' to change the level of warnings.
The possible behaviours are: ignore, warn, error.
You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'.
Or you can abort the rebase with 'git rebase --abort'.
EOF

test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' '
cat >expect <<-EOF &&
Warning: some commits may have been dropped accidentally.
Dropped commits (newer to older):
- $(git rev-list --pretty=oneline --abbrev-commit -1 master)
- $(git rev-list --pretty=oneline --abbrev-commit -1 master~2)
To avoid this message, use "drop" to explicitly remove a commit.
Use '\''git config rebase.missingCommitsCheck'\'' to change the level of warnings.
The possible behaviours are: ignore, warn, error.
You can fix this with '\''git rebase --edit-todo'\'' and then run '\''git rebase --continue'\''.
Or you can abort the rebase with '\''git rebase --abort'\''.
EOF
test_config rebase.missingCommitsCheck error &&
rebase_setup_and_clean missing-commit &&
set_fake_editor &&
Expand Down
4 changes: 2 additions & 2 deletions t/t3420-rebase-autostash.sh
Expand Up @@ -49,7 +49,7 @@ create_expected_success_interactive () {
$(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual)
HEAD is now at $(git rev-parse --short feature-branch) third commit
Rebasing (1/2)QRebasing (2/2)QApplied autostash.
Successfully rebased and updated refs/heads/rebased-feature-branch.
Q QSuccessfully rebased and updated refs/heads/rebased-feature-branch.
EOF
}

Expand All @@ -73,7 +73,7 @@ create_expected_failure_interactive () {
Rebasing (1/2)QRebasing (2/2)QApplying autostash resulted in conflicts.
Your changes are safe in the stash.
You can run "git stash pop" or "git stash drop" at any time.
Successfully rebased and updated refs/heads/rebased-feature-branch.
Q QSuccessfully rebased and updated refs/heads/rebased-feature-branch.
EOF
}

Expand Down
6 changes: 3 additions & 3 deletions t/t5541-http-push-smart.sh
Expand Up @@ -213,7 +213,7 @@ test_expect_success TTY 'push shows progress when stderr is a tty' '
cd "$ROOT_PATH"/test_repo_clone &&
test_commit noisy &&
test_terminal git push >output 2>&1 &&
test_i18ngrep "^Writing objects" output
test_i18ngrep "Writing objects" output
'

test_expect_success TTY 'push --quiet silences status and progress' '
Expand All @@ -228,15 +228,15 @@ test_expect_success TTY 'push --no-progress silences progress but not status' '
test_commit no-progress &&
test_terminal git push --no-progress >output 2>&1 &&
test_i18ngrep "^To http" output &&
test_i18ngrep ! "^Writing objects" output
test_i18ngrep ! "Writing objects" output
'

test_expect_success 'push --progress shows progress to non-tty' '
cd "$ROOT_PATH"/test_repo_clone &&
test_commit progress &&
git push --progress >output 2>&1 &&
test_i18ngrep "^To http" output &&
test_i18ngrep "^Writing objects" output
test_i18ngrep "Writing objects" output
'

test_expect_success 'http push gives sane defaults to reflog' '
Expand Down

0 comments on commit 6624e07

Please sign in to comment.