Merge branch 'gb/rebase-signoff'
authorJunio C Hamano <gitster@pobox.com>
Wed, 26 Apr 2017 06:39:01 +0000 (15:39 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 26 Apr 2017 06:39:02 +0000 (15:39 +0900)
"git rebase" learns "--signoff" option.

* gb/rebase-signoff:
rebase: pass --[no-]signoff option to git am
builtin/am: fold am_signoff() into am_append_signoff()
builtin/am: honor --signoff also when --rebasing

1  2 
Documentation/git-rebase.txt
builtin/am.c
git-rebase.sh
index 67d48e68831561303c4f39f46bf105371ed0d916,76ee47218f2e365a1b0001a64c23d16a2c31ae04..53f4e144444ae7b30ce2634c0f364400927b27d2
@@@ -12,7 -12,7 +12,7 @@@ SYNOPSI
        [<upstream> [<branch>]]
  'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
        --root [<branch>]
 -'git rebase' --continue | --skip | --abort | --edit-todo
 +'git rebase' --continue | --skip | --abort | --quit | --edit-todo
  
  DESCRIPTION
  -----------
@@@ -252,11 -252,6 +252,11 @@@ leave out at most one of A and B, in wh
        will be reset to where it was when the rebase operation was
        started.
  
 +--quit::
 +      Abort the rebase operation but HEAD is not reset back to the
 +      original branch. The index and working tree are also left
 +      unchanged as a result.
 +
  --keep-empty::
        Keep the commits that do not change anything from its
        parents in the result.
@@@ -370,6 -365,11 +370,11 @@@ default is `--no-fork-point`, otherwis
        of the rebased commits (see linkgit:git-am[1]).
        Incompatible with the --interactive option.
  
+ --signoff::
+       This flag is passed to 'git am' to sign off all the rebased
+       commits (see linkgit:git-am[1]). Incompatible with the
+       --interactive option.
  -i::
  --interactive::
        Make a list of the commits which are about to be rebased.  Let the
diff --combined builtin/am.c
index 805f56cec2f523f8248e2893e10d99cc4e1d1b88,831b680038794f204eb79efa21b2ad9e839848fc..f08b7e6626021e425e4712763bee2236b8eab47b
@@@ -762,18 -762,14 +762,18 @@@ static int split_mail_conv(mail_conv_f
                mail = mkpath("%s/%0*d", state->dir, state->prec, i + 1);
  
                out = fopen(mail, "w");
 -              if (!out)
 +              if (!out) {
 +                      if (in != stdin)
 +                              fclose(in);
                        return error_errno(_("could not open '%s' for writing"),
                                           mail);
 +              }
  
                ret = fn(out, in, keep_cr);
  
                fclose(out);
 -              fclose(in);
 +              if (in != stdin)
 +                      fclose(in);
  
                if (ret)
                        return error(_("could not parse patch '%s'"), *paths);
@@@ -1053,7 -1049,7 +1053,7 @@@ static void am_setup(struct am_state *s
        } else {
                write_state_text(state, "abort-safety", "");
                if (!state->rebasing)
 -                      delete_ref("ORIG_HEAD", NULL, 0);
 +                      delete_ref(NULL, "ORIG_HEAD", NULL, 0);
        }
  
        /*
@@@ -1123,7 -1119,7 +1123,7 @@@ static void refresh_and_write_cache(voi
  {
        struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
  
 -      hold_locked_index(lock_file, 1);
 +      hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
        refresh_cache(REFRESH_QUIET);
        if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
                die(_("unable to write index file"));
@@@ -1185,42 -1181,39 +1185,39 @@@ static void NORETURN die_user_resolve(c
        exit(128);
  }
  
- static void am_signoff(struct strbuf *sb)
+ /**
+  * Appends signoff to the "msg" field of the am_state.
+  */
+ static void am_append_signoff(struct am_state *state)
  {
        char *cp;
        struct strbuf mine = STRBUF_INIT;
+       struct strbuf sb = STRBUF_INIT;
  
-       /* Does it end with our own sign-off? */
+       strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);
+       /* our sign-off */
        strbuf_addf(&mine, "\n%s%s\n",
                    sign_off_header,
                    fmt_name(getenv("GIT_COMMITTER_NAME"),
                             getenv("GIT_COMMITTER_EMAIL")));
-       if (mine.len < sb->len &&
-           !strcmp(mine.buf, sb->buf + sb->len - mine.len))
+       /* Does sb end with it already? */
+       if (mine.len < sb.len &&
+           !strcmp(mine.buf, sb.buf + sb.len - mine.len))
                goto exit; /* no need to duplicate */
  
        /* Does it have any Signed-off-by: in the text */
-       for (cp = sb->buf;
+       for (cp = sb.buf;
             cp && *cp && (cp = strstr(cp, sign_off_header)) != NULL;
             cp = strchr(cp, '\n')) {
-               if (sb->buf == cp || cp[-1] == '\n')
+               if (sb.buf == cp || cp[-1] == '\n')
                        break;
        }
  
-       strbuf_addstr(sb, mine.buf + !!cp);
+       strbuf_addstr(&sb, mine.buf + !!cp);
  exit:
        strbuf_release(&mine);
- }
- /**
-  * Appends signoff to the "msg" field of the am_state.
-  */
- static void am_append_signoff(struct am_state *state)
- {
-       struct strbuf sb = STRBUF_INIT;
-       strbuf_attach(&sb, state->msg, state->msg_len, state->msg_len);
-       am_signoff(&sb);
        state->msg = strbuf_detach(&sb, &state->msg_len);
  }
  
@@@ -1325,9 -1318,6 +1322,6 @@@ static int parse_mail(struct am_state *
        strbuf_addbuf(&msg, &mi.log_message);
        strbuf_stripspace(&msg, 0);
  
-       if (state->signoff)
-               am_signoff(&msg);
        assert(!state->author_name);
        state->author_name = strbuf_detach(&author_name, NULL);
  
@@@ -1852,6 -1842,9 +1846,9 @@@ static void am_run(struct am_state *sta
                        if (skip)
                                goto next; /* mail should be skipped */
  
+                       if (state->signoff)
+                               am_append_signoff(state);
                        write_author_script(state);
                        write_commit_msg(state);
                }
@@@ -1980,7 -1973,7 +1977,7 @@@ static int fast_forward_to(struct tree 
                return -1;
  
        lock_file = xcalloc(1, sizeof(struct lock_file));
 -      hold_locked_index(lock_file, 1);
 +      hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
  
        refresh_cache(REFRESH_QUIET);
  
@@@ -2020,7 -2013,7 +2017,7 @@@ static int merge_tree(struct tree *tree
                return -1;
  
        lock_file = xcalloc(1, sizeof(struct lock_file));
 -      hold_locked_index(lock_file, 1);
 +      hold_locked_index(lock_file, LOCK_DIE_ON_ERROR);
  
        memset(&opts, 0, sizeof(opts));
        opts.head_idx = 1;
@@@ -2176,7 -2169,7 +2173,7 @@@ static void am_abort(struct am_state *s
                                has_curr_head ? &curr_head : NULL, 0,
                                UPDATE_REFS_DIE_ON_ERR);
        else if (curr_branch)
 -              delete_ref(curr_branch, NULL, REF_NODEREF);
 +              delete_ref(NULL, curr_branch, NULL, REF_NODEREF);
  
        free(curr_branch);
        am_destroy(state);
diff --combined git-rebase.sh
index 48d7c5ded40e1801a36a897849e0f32b314e5981,0bced9b0959f51f448bd7dd1947b5b658499951b..db1deed8464f0643763ed6e3c5e54221cad8c985
@@@ -34,6 -34,7 +34,7 @@@ root!              rebase all reachabl
  autosquash         move commits that begin with squash!/fixup! under -i
  committer-date-is-author-date! passed to 'git am'
  ignore-date!       passed to 'git am'
+ signoff            passed to 'git am'
  whitespace=!       passed to 'git apply'
  ignore-whitespace! passed to 'git apply'
  C=!                passed to 'git apply'
@@@ -43,7 -44,6 +44,7 @@@ continue!          continu
  abort!             abort and check out the original branch
  skip!              skip current patch and continue
  edit-todo!         edit the todo list during an interactive rebase
 +quit!              abort but keep HEAD where it is
  "
  . git-sh-setup
  set_reflog_action rebase
@@@ -242,7 -242,7 +243,7 @@@ d
        --verify)
                ok_to_skip_pre_rebase=
                ;;
 -      --continue|--skip|--abort|--edit-todo)
 +      --continue|--skip|--abort|--quit|--edit-todo)
                test $total_argc -eq 2 || usage
                action=${1##--}
                ;;
        --ignore-whitespace)
                git_am_opt="$git_am_opt $1"
                ;;
-       --committer-date-is-author-date|--ignore-date)
+       --committer-date-is-author-date|--ignore-date|--signoff|--no-signoff)
                git_am_opt="$git_am_opt $1"
                force_rebase=t
                ;;
@@@ -400,9 -400,6 +401,9 @@@ abort
        finish_rebase
        exit
        ;;
 +quit)
 +      exec rm -rf "$state_dir"
 +      ;;
  edit-todo)
        run_specific_rebase
        ;;