提交 6624e07b 编写于 作者: J Junio C Hamano

Merge branch 'sg/rebase-progress'

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
......@@ -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);
......
......@@ -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)
......
......@@ -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?
*/
......
......@@ -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;
......@@ -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);
}
......
......@@ -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))
......@@ -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);
}
......@@ -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;
......@@ -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);
......
......@@ -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
......@@ -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 &&
......@@ -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 &&
......@@ -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 &&
......@@ -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 &&
......
......@@ -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
}
......@@ -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
}
......
......@@ -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' '
......@@ -228,7 +228,7 @@ 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' '
......@@ -236,7 +236,7 @@ test_expect_success 'push --progress shows progress to non-tty' '
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' '
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册