Merge branch 'sg/rebase-progress'
authorJunio C Hamano <gitster@pobox.com>
Tue, 9 Jul 2019 22:25:45 +0000 (15:25 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 9 Jul 2019 22:25:45 +0000 (15:25 -0700)
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

1  2 
cache.h
sequencer.c
t/t3404-rebase-interactive.sh
diff --combined cache.h
index 37e0b820649b4ef22113e8618aeb861fac25b67e,5b2cd32bad89b691646fa1be58fe8a1ed12f327b..3167585cabda5f91f4c501d9b5bf924b4f5a3e12
+++ b/cache.h
@@@ -43,6 -43,30 +43,6 @@@ int git_deflate_end_gently(git_zstream 
  int git_deflate(git_zstream *, int flush);
  unsigned long git_deflate_bound(git_zstream *, unsigned long);
  
 -/* The length in bytes and in hex digits of an object name (SHA-1 value). */
 -#define GIT_SHA1_RAWSZ 20
 -#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
 -/* The block size of SHA-1. */
 -#define GIT_SHA1_BLKSZ 64
 -
 -/* The length in bytes and in hex digits of an object name (SHA-256 value). */
 -#define GIT_SHA256_RAWSZ 32
 -#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
 -/* The block size of SHA-256. */
 -#define GIT_SHA256_BLKSZ 64
 -
 -/* The length in byte and in hex digits of the largest possible hash value. */
 -#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
 -#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
 -/* The largest possible block size for any supported hash. */
 -#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
 -
 -struct object_id {
 -      unsigned char hash[GIT_MAX_RAWSZ];
 -};
 -
 -#define the_hash_algo the_repository->hash_algo
 -
  #if defined(DT_UNKNOWN) && !defined(NO_D_TYPE_IN_DIRENT)
  #define DTYPE(de)     ((de)->d_type)
  #else
@@@ -802,7 -826,7 +802,7 @@@ int match_stat_data(const struct stat_d
  int match_stat_data_racy(const struct index_state *istate,
                         const struct stat_data *sd, struct stat *st);
  
 -void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
 +void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, struct stat *st);
  
  #define REFRESH_REALLY                0x0001  /* ignore_valid */
  #define REFRESH_UNMERGED      0x0002  /* allow unmerged */
@@@ -1735,6 -1759,7 +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);
diff --combined sequencer.c
index 74a7a47d015010a82463691ddc70abce4708687a,63b09cfceb5d3d4c685bebad6dcc24fe1d72bc61..cf262701e8e7df668b2c659bfb4806f0c7e90a9e
@@@ -279,7 -279,7 +279,7 @@@ static const char *gpg_sign_opt_quoted(
  int sequencer_remove_state(struct replay_opts *opts)
  {
        struct strbuf buf = STRBUF_INIT;
 -      int i;
 +      int i, ret = 0;
  
        if (is_rebase_i(opts) &&
            strbuf_read_file(&buf, rebase_path_refs_to_delete(), 0) > 0) {
                        char *eol = strchr(p, '\n');
                        if (eol)
                                *eol = '\0';
 -                      if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0)
 +                      if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0) {
                                warning(_("could not delete '%s'"), p);
 +                              ret = -1;
 +                      }
                        if (!eol)
                                break;
                        p = eol + 1;
  
        strbuf_reset(&buf);
        strbuf_addstr(&buf, get_dir(opts));
 -      remove_dir_recursively(&buf, 0);
 +      if (remove_dir_recursively(&buf, 0))
 +              ret = error(_("could not remove '%s'"), buf.buf);
        strbuf_release(&buf);
  
 -      return 0;
 +      return ret;
  }
  
  static const char *action_name(const struct replay_opts *opts)
@@@ -770,7 -767,7 +770,7 @@@ static int parse_key_value_squoted(cha
   *    GIT_AUTHOR_DATE='$author_date'
   *
   * where $author_name, $author_email and $author_date are quoted. We are strict
 - * with our parsing, as the file was meant to be eval'd in the old
 + * with our parsing, as the file was meant to be eval'd in the now-removed
   * git-am.sh/git-rebase--interactive.sh scripts, and thus if the file differs
   * from what this function expects, it is better to bail out than to do
   * something that the user does not expect.
@@@ -2314,21 -2311,19 +2314,21 @@@ static int have_finished_the_last_pick(
        return ret;
  }
  
 -void sequencer_post_commit_cleanup(struct repository *r)
 +void sequencer_post_commit_cleanup(struct repository *r, int verbose)
  {
        struct replay_opts opts = REPLAY_OPTS_INIT;
        int need_cleanup = 0;
  
        if (file_exists(git_path_cherry_pick_head(r))) {
 -              unlink(git_path_cherry_pick_head(r));
 +              if (!unlink(git_path_cherry_pick_head(r)) && verbose)
 +                      warning(_("cancelling a cherry picking in progress"));
                opts.action = REPLAY_PICK;
                need_cleanup = 1;
        }
  
        if (file_exists(git_path_revert_head(r))) {
 -              unlink(git_path_revert_head(r));
 +              if (!unlink(git_path_revert_head(r)) && verbose)
 +                      warning(_("cancelling a revert in progress"));
                opts.action = REPLAY_REVERT;
                need_cleanup = 1;
        }
@@@ -3406,10 -3401,6 +3406,10 @@@ static int do_merge(struct repository *
                rollback_lock_file(&lock);
                ret = fast_forward_to(r, &commit->object.oid,
                                      &head_commit->object.oid, 0, opts);
 +              if (flags & TODO_EDIT_MERGE_MSG) {
 +                      run_commit_flags |= AMEND_MSG;
 +                      goto fast_forward_edit;
 +              }
                goto leave_merge;
        }
  
                 * value (a negative one would indicate that the `merge`
                 * command needs to be rescheduled).
                 */
 +      fast_forward_edit:
                ret = !!run_git_commit(r, git_path_merge_msg(r), opts,
                                       run_commit_flags);
  
@@@ -3741,8 -3731,11 +3741,11 @@@ static int pick_commits(struct reposito
                        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))
                        }
                        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);
                        }
                        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 -3962,13 +3972,13 @@@ cleanup_head_ref
                }
                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);
index 46d971b4efe647d48cb8c771b07e794065992b0b,0b8267c97cb7e2d53d157ae9114f47eeb90a15b4..461dd539ffd4803c62d54e22e8921fbefa2c0786
@@@ -75,11 -75,10 +75,10 @@@ test_expect_success 'rebase --keep-empt
        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 +236,23 @@@ test_expect_success 'exchange two commi
        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 +492,14 @@@ test_expect_success 'commit message ret
        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 +795,12 @@@ test_expect_success 'rebase -i can cop
        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 &&
@@@ -1031,7 -1026,7 +1026,7 @@@ test_expect_success 'rebase -i --root r
        test -z "$(git show -s --format=%p HEAD^)"
  '
  
 -test_expect_success 'rebase -i --root when root has untracked file confilct' '
 +test_expect_success 'rebase -i --root when root has untracked file conflict' '
        test_when_finished "reset_rebase" &&
        git checkout -b failing-root-pick A &&
        echo x >file2 &&
@@@ -1304,52 -1299,37 +1299,37 @@@ test_expect_success 'rebase -i respect
                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 &&