Merge branch 'fc/doc-fast-forward'
authorJunio C Hamano <gitster@pobox.com>
Mon, 16 Nov 2009 00:41:02 +0000 (16:41 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 16 Nov 2009 00:41:02 +0000 (16:41 -0800)
* fc/doc-fast-forward:
Use 'fast-forward' all over the place

Conflicts:
builtin-merge.c

1  2 
Documentation/config.txt
Documentation/git-push.txt
builtin-fetch.c
builtin-merge.c
builtin-push.c
builtin-receive-pack.c
git-pull.sh
git-rebase--interactive.sh
transport.c
diff --combined Documentation/config.txt
index d1e2120e15b37a14eec5b3d1de9752da8f6ad7af,52bbafbefa01d868cec4a533f7472cce2ad7aebc..cb73d7571f25deffb061441577ce1ae531fdf5d9
@@@ -416,17 -416,13 +416,17 @@@ core.whitespace:
        consider them as errors.  You can prefix `-` to disable
        any of them (e.g. `-trailing-space`):
  +
 -* `trailing-space` treats trailing whitespaces at the end of the line
 +* `blank-at-eol` treats trailing whitespaces at the end of the line
    as an error (enabled by default).
  * `space-before-tab` treats a space character that appears immediately
    before a tab character in the initial indent part of the line as an
    error (enabled by default).
  * `indent-with-non-tab` treats a line that is indented with 8 or more
    space characters as an error (not enabled by default).
 +* `blank-at-eof` treats blank lines added at the end of file as an error
 +  (enabled by default).
 +* `trailing-space` is a short-hand to cover both `blank-at-eol` and
 +  `blank-at-eof`.
  * `cr-at-eol` treats a carriage-return at the end of line as
    part of the line terminator, i.e. with it, `trailing-space`
    does not trigger if the character before such a carriage-return
@@@ -1324,11 -1320,6 +1324,11 @@@ rebase.stat:
        Whether to show a diffstat of what changed upstream since the last
        rebase. False by default.
  
 +receive.autogc::
 +      By default, git-receive-pack will run "git-gc --auto" after
 +      receiving data from git-push and updating refs.  You can stop
 +      it by setting this variable to false.
 +
  receive.fsckObjects::
        If it is set to true, git-receive-pack will check all received
        objects. It will abort in the case of a malformed object or a
@@@ -1360,14 -1351,10 +1360,14 @@@ receive.denyCurrentBranch:
  
  receive.denyNonFastForwards::
        If set to true, git-receive-pack will deny a ref update which is
-       not a fast forward. Use this to prevent such an update via a push,
+       not a fast-forward. Use this to prevent such an update via a push,
        even if that push is forced. This configuration variable is
        set when initializing a shared repository.
  
 +receive.updateserverinfo::
 +      If set to true, git-receive-pack will run git-update-server-info
 +      after receiving data from git-push and updating refs.
 +
  remote.<name>.url::
        The URL of a remote repository.  See linkgit:git-fetch[1] or
        linkgit:git-push[1].
index 37c88953d1a08c0498c794aeb4d0d38eac8a36db,1a9d886bb3e10338ea66743a9dec355581835f50..52c0538df528ecbb5b755a2e75fc1715762bfc00
@@@ -50,9 -50,9 +50,9 @@@ updated
  +
  The object referenced by <src> is used to update the <dst> reference
  on the remote side, but by default this is only allowed if the
- update can fast forward <dst>.  By having the optional leading `{plus}`,
+ update can fast-forward <dst>.  By having the optional leading `{plus}`,
  you can tell git to update the <dst> ref even when the update is not a
- fast forward.  This does *not* attempt to merge <src> into <dst>.  See
+ fast-forward.  This does *not* attempt to merge <src> into <dst>.  See
  EXAMPLES below for details.
  +
  `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
@@@ -60,7 -60,7 +60,7 @@@
  Pushing an empty <src> allows you to delete the <dst> ref from
  the remote repository.
  +
- The special refspec `:` (or `{plus}:` to allow non-fast forward updates)
+ The special refspec `:` (or `{plus}:` to allow non-fast-forward updates)
  directs git to push "matching" branches: for every branch that exists on
  the local side, the remote side is updated if a branch of the same name
  already exists on the remote side.  This is the default operation mode
@@@ -138,11 -138,6 +138,11 @@@ useful if you write an alias or script 
  --verbose::
        Run verbosely.
  
 +-q::
 +--quiet::
 +      Suppress all output, including the listing of updated refs,
 +      unless an error occurs.
 +
  include::urls-remotes.txt[]
  
  OUTPUT
@@@ -176,10 -171,10 +176,10 @@@ summary:
        For a successfully pushed ref, the summary shows the old and new
        values of the ref in a form suitable for using as an argument to
        `git log` (this is `<old>..<new>` in most cases, and
-       `<old>...<new>` for forced non-fast forward updates). For a
+       `<old>...<new>` for forced non-fast-forward updates). For a
        failed update, more details are given for the failure.
        The string `rejected` indicates that git did not try to send the
-       ref at all (typically because it is not a fast forward). The
+       ref at all (typically because it is not a fast-forward). The
        string `remote rejected` indicates that the remote end refused
        the update; this rejection is typically caused by a hook on the
        remote side. The string `remote failure` indicates that the
@@@ -347,9 -342,9 +347,9 @@@ git push origin :experimental:
  
  git push origin {plus}dev:master::
        Update the origin repository's master branch with the dev branch,
-       allowing non-fast forward updates.  *This can leave unreferenced
+       allowing non-fast-forward updates.  *This can leave unreferenced
        commits dangling in the origin repository.*  Consider the
-       following situation, where a fast forward is not possible:
+       following situation, where a fast-forward is not possible:
  +
  ----
            o---o---o---A---B  origin/master
diff --combined builtin-fetch.c
index a35a6f8cb8030bf9be98a001da26fddf0efdb912,6303aa0f581ace87381fb6a6d425ea8031915c21..f871f2bfe8b81a508c8850c607a88249a63933f6
@@@ -269,7 -269,7 +269,7 @@@ static int update_local_ref(struct ref 
                strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
                strcat(quickref, "..");
                strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
-               r = s_update_ref("fast forward", ref, 1);
+               r = s_update_ref("fast-forward", ref, 1);
                sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : ' ',
                        SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote,
                        pretty_ref, r ? "  (unable to update local ref)" : "");
                        r ? "unable to update local ref" : "forced update");
                return r;
        } else {
-               sprintf(display, "! %-*s %-*s -> %s  (non fast forward)",
+               sprintf(display, "! %-*s %-*s -> %s  (non-fast-forward)",
                        SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
                        pretty_ref);
                return 1;
@@@ -504,98 -504,57 +504,98 @@@ static int will_fetch(struct ref **head
        return 0;
  }
  
 +struct tag_data {
 +      struct ref **head;
 +      struct ref ***tail;
 +};
 +
 +static int add_to_tail(struct string_list_item *item, void *cb_data)
 +{
 +      struct tag_data *data = (struct tag_data *)cb_data;
 +      struct ref *rm = NULL;
 +
 +      /* We have already decided to ignore this item */
 +      if (!item->util)
 +              return 0;
 +
 +      rm = alloc_ref(item->string);
 +      rm->peer_ref = alloc_ref(item->string);
 +      hashcpy(rm->old_sha1, item->util);
 +
 +      **data->tail = rm;
 +      *data->tail = &rm->next;
 +
 +      return 0;
 +}
 +
  static void find_non_local_tags(struct transport *transport,
                        struct ref **head,
                        struct ref ***tail)
  {
        struct string_list existing_refs = { NULL, 0, 0, 0 };
 -      struct string_list new_refs = { NULL, 0, 0, 1 };
 -      char *ref_name;
 -      int ref_name_len;
 -      const unsigned char *ref_sha1;
 -      const struct ref *tag_ref;
 -      struct ref *rm = NULL;
 +      struct string_list remote_refs = { NULL, 0, 0, 0 };
 +      struct tag_data data = {head, tail};
        const struct ref *ref;
 +      struct string_list_item *item = NULL;
  
        for_each_ref(add_existing, &existing_refs);
        for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
                if (prefixcmp(ref->name, "refs/tags"))
                        continue;
  
 -              ref_name = xstrdup(ref->name);
 -              ref_name_len = strlen(ref_name);
 -              ref_sha1 = ref->old_sha1;
 -
 -              if (!strcmp(ref_name + ref_name_len - 3, "^{}")) {
 -                      ref_name[ref_name_len - 3] = 0;
 -                      tag_ref = transport_get_remote_refs(transport);
 -                      while (tag_ref) {
 -                              if (!strcmp(tag_ref->name, ref_name)) {
 -                                      ref_sha1 = tag_ref->old_sha1;
 -                                      break;
 -                              }
 -                              tag_ref = tag_ref->next;
 -                      }
 +              /*
 +               * The peeled ref always follows the matching base
 +               * ref, so if we see a peeled ref that we don't want
 +               * to fetch then we can mark the ref entry in the list
 +               * as one to ignore by setting util to NULL.
 +               */
 +              if (!strcmp(ref->name + strlen(ref->name) - 3, "^{}")) {
 +                      if (item && !has_sha1_file(ref->old_sha1) &&
 +                          !will_fetch(head, ref->old_sha1) &&
 +                          !has_sha1_file(item->util) &&
 +                          !will_fetch(head, item->util))
 +                              item->util = NULL;
 +                      item = NULL;
 +                      continue;
                }
  
 -              if (!string_list_has_string(&existing_refs, ref_name) &&
 -                  !string_list_has_string(&new_refs, ref_name) &&
 -                  (has_sha1_file(ref->old_sha1) ||
 -                   will_fetch(head, ref->old_sha1))) {
 -                      string_list_insert(ref_name, &new_refs);
 +              /*
 +               * If item is non-NULL here, then we previously saw a
 +               * ref not followed by a peeled reference, so we need
 +               * to check if it is a lightweight tag that we want to
 +               * fetch.
 +               */
 +              if (item && !has_sha1_file(item->util) &&
 +                  !will_fetch(head, item->util))
 +                      item->util = NULL;
  
 -                      rm = alloc_ref(ref_name);
 -                      rm->peer_ref = alloc_ref(ref_name);
 -                      hashcpy(rm->old_sha1, ref_sha1);
 +              item = NULL;
  
 -                      **tail = rm;
 -                      *tail = &rm->next;
 -              }
 -              free(ref_name);
 +              /* skip duplicates and refs that we already have */
 +              if (string_list_has_string(&remote_refs, ref->name) ||
 +                  string_list_has_string(&existing_refs, ref->name))
 +                      continue;
 +
 +              item = string_list_insert(ref->name, &remote_refs);
 +              item->util = (void *)ref->old_sha1;
        }
        string_list_clear(&existing_refs, 0);
 -      string_list_clear(&new_refs, 0);
 +
 +      /*
 +       * We may have a final lightweight tag that needs to be
 +       * checked to see if it needs fetching.
 +       */
 +      if (item && !has_sha1_file(item->util) &&
 +          !will_fetch(head, item->util))
 +              item->util = NULL;
 +
 +      /*
 +       * For all the tags in the remote_refs string list, call
 +       * add_to_tail to add them to the list of refs to be fetched
 +       */
 +      for_each_string_list(add_to_tail, &remote_refs, &data);
 +
 +      string_list_clear(&remote_refs, 0);
  }
  
  static void check_not_current_branch(struct ref *ref_map)
diff --combined builtin-merge.c
index c8d7bdecc4e91392fa9e2614a6b9790e48fc0abd,a595b8b47b5eebae08ac02775679e066265552bd..57eedd447d0f899a258998bb3039905a5a49babb
@@@ -43,7 -43,6 +43,7 @@@ static const char * const builtin_merge
  
  static int show_diffstat = 1, option_log, squash;
  static int option_commit = 1, allow_fast_forward = 1;
 +static int fast_forward_only;
  static int allow_trivial = 1, have_message;
  static struct strbuf merge_msg;
  static struct commit_list *remoteheads;
@@@ -167,9 -166,7 +167,9 @@@ static struct option builtin_merge_opti
        OPT_BOOLEAN(0, "commit", &option_commit,
                "perform a commit if the merge succeeds (default)"),
        OPT_BOOLEAN(0, "ff", &allow_fast_forward,
-               "allow fast forward (default)"),
+               "allow fast-forward (default)"),
 +      OPT_BOOLEAN(0, "ff-only", &fast_forward_only,
-               "abort if fast forward is not possible"),
++              "abort if fast-forward is not possible"),
        OPT_CALLBACK('s', "strategy", &use_strategies, "strategy",
                "merge strategy to use", option_parse_strategy),
        OPT_CALLBACK('m', "message", &merge_msg, "message",
@@@ -267,7 -264,6 +267,7 @@@ static void squash_message(void
        struct strbuf out = STRBUF_INIT;
        struct commit_list *j;
        int fd;
 +      struct pretty_print_context ctx = {0};
  
        printf("Squash commit -- not updating HEAD\n");
        fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
        if (prepare_revision_walk(&rev))
                die("revision walk setup failed");
  
 +      ctx.abbrev = rev.abbrev;
 +      ctx.date_mode = rev.date_mode;
 +
        strbuf_addstr(&out, "Squashed commit of the following:\n");
        while ((commit = get_revision(&rev)) != NULL) {
                strbuf_addch(&out, '\n');
                strbuf_addf(&out, "commit %s\n",
                        sha1_to_hex(commit->object.sha1));
 -              pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev,
 -                      NULL, NULL, rev.date_mode, 0);
 +              pretty_print_commit(rev.commit_format, commit, &out, &ctx);
        }
        if (write(fd, out.buf, out.len) < 0)
                die_errno("Writing SQUASH_MSG");
@@@ -846,6 -840,7 +846,6 @@@ int cmd_merge(int argc, const char **ar
        const char *best_strategy = NULL, *wt_strategy = NULL;
        struct commit_list **remotes = &remoteheads;
  
 -      setup_work_tree();
        if (file_exists(git_path("MERGE_HEAD")))
                die("You have not concluded your merge. (MERGE_HEAD exists)");
        if (read_cache_unmerged())
                option_commit = 0;
        }
  
 +      if (!allow_fast_forward && fast_forward_only)
 +              die("You cannot combine --no-ff with --ff-only.");
 +
        if (!argc)
                usage_with_options(builtin_merge_usage,
                        builtin_merge_options);
                                hex,
                                find_unique_abbrev(remoteheads->item->object.sha1,
                                DEFAULT_ABBREV));
-               strbuf_addstr(&msg, "Fast forward");
+               strbuf_addstr(&msg, "Fast-forward");
                if (have_message)
                        strbuf_addstr(&msg,
                                " (no commit created; -m option ignored)");
        } else if (!remoteheads->next && common->next)
                ;
                /*
-                * We are not doing octopus and not fast forward.  Need
+                * We are not doing octopus and not fast-forward.  Need
                 * a real merge.
                 */
        else if (!remoteheads->next && !common->next && option_commit) {
                /*
-                * We are not doing octopus, not fast forward, and have
+                * We are not doing octopus, not fast-forward, and have
                 * only one common.
                 */
                refresh_cache(REFRESH_QUIET);
 -              if (allow_trivial) {
 +              if (allow_trivial && !fast_forward_only) {
                        /* See if it is really trivial. */
                        git_committer_info(IDENT_ERROR_ON_NO_NAME);
                        printf("Trying really trivial in-index merge...\n");
                }
        }
  
-               die("Not possible to fast forward, aborting.");
 +      if (fast_forward_only)
++              die("Not possible to fast-forward, aborting.");
 +
        /* We are going to make a new commit. */
        git_committer_info(IDENT_ERROR_ON_NO_NAME);
  
diff --combined builtin-push.c
index 752121f2479eb9d3d9e60726645f204f676a5bd3,e883574f0330989b8f192387d5aea4f4b8db9261..356d7c1fd3a6fae9558e93eb4f240242a60da368
@@@ -10,7 -10,7 +10,7 @@@
  #include "parse-options.h"
  
  static const char * const push_usage[] = {
 -      "git push [--all | --mirror] [-n | --dry-run] [--porcelain] [--tags] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [-v] [<repository> <refspec>...]",
 +      "git push [<options>] [<repository> <refspec>...]",
        NULL,
  };
  
@@@ -66,6 -66,7 +66,6 @@@ static void setup_push_tracking(void
  
  static void setup_default_push_refspecs(void)
  {
 -      git_config(git_default_config, NULL);
        switch (push_default) {
        default:
        case PUSH_DEFAULT_MATCHING:
@@@ -158,7 -159,7 +158,7 @@@ static int do_push(const char *repo, in
                error("failed to push some refs to '%s'", url[i]);
                if (nonfastforward && advice_push_nonfastforward) {
                        printf("To prevent you from losing history, non-fast-forward updates were rejected\n"
-                              "Merge the remote changes before pushing again.  See the 'non-fast forward'\n"
+                              "Merge the remote changes before pushing again.  See the 'non-fast-forward'\n"
                               "section of 'git push --help' for details.\n");
                }
                errs++;
@@@ -172,6 -173,7 +172,6 @@@ int cmd_push(int argc, const char **arg
        int tags = 0;
        int rc;
        const char *repo = NULL;        /* default repository */
 -
        struct option options[] = {
                OPT_BIT('q', "quiet", &flags, "be quiet", TRANSPORT_PUSH_QUIET),
                OPT_BIT('v', "verbose", &flags, "be verbose", TRANSPORT_PUSH_VERBOSE),
                OPT_BIT( 0 , "all", &flags, "push all refs", TRANSPORT_PUSH_ALL),
                OPT_BIT( 0 , "mirror", &flags, "mirror all refs",
                            (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
 -              OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
 +              OPT_BOOLEAN( 0 , "tags", &tags, "push tags (can't be used with --all or --mirror)"),
                OPT_BIT('n' , "dry-run", &flags, "dry run", TRANSPORT_PUSH_DRY_RUN),
                OPT_BIT( 0,  "porcelain", &flags, "machine-readable output", TRANSPORT_PUSH_PORCELAIN),
                OPT_BIT('f', "force", &flags, "force updates", TRANSPORT_PUSH_FORCE),
                OPT_END()
        };
  
 +      git_config(git_default_config, NULL);
        argc = parse_options(argc, argv, prefix, options, push_usage, 0);
  
        if (tags)
diff --combined builtin-receive-pack.c
index e8bde02c271ace4745e245b001652b3b96d798f5,fea8fcdd8aa27e3210bf08d48cb2e9275f4def97..b6895d3f992f17e215d98f185a024a3e4041e507
@@@ -28,8 -28,6 +28,8 @@@ static int transfer_unpack_limit = -1
  static int unpack_limit = 100;
  static int report_status;
  static int prefer_ofs_delta = 1;
 +static int auto_update_server_info;
 +static int auto_gc = 1;
  static const char *head_name;
  static char *capabilities_to_send;
  
@@@ -90,16 -88,6 +90,16 @@@ static int receive_pack_config(const ch
                return 0;
        }
  
 +      if (strcmp(var, "receive.updateserverinfo") == 0) {
 +              auto_update_server_info = git_config_bool(var, value);
 +              return 0;
 +      }
 +
 +      if (strcmp(var, "receive.autogc") == 0) {
 +              auto_gc = git_config_bool(var, value);
 +              return 0;
 +      }
 +
        return git_default_config(var, value, cb);
  }
  
@@@ -341,9 -329,9 +341,9 @@@ static const char *update(struct comman
                                break;
                free_commit_list(bases);
                if (!ent) {
-                       error("denying non-fast forward %s"
+                       error("denying non-fast-forward %s"
                              " (you should pull first)", name);
-                       return "non-fast forward";
+                       return "non-fast-forward";
                }
        }
        if (run_update_hook(cmd)) {
@@@ -684,14 -672,6 +684,14 @@@ int cmd_receive_pack(int argc, const ch
                        report(unpack_status);
                run_receive_hook(post_receive_hook);
                run_update_post_hook(commands);
 +              if (auto_gc) {
 +                      const char *argv_gc_auto[] = {
 +                              "gc", "--auto", "--quiet", NULL,
 +                      };
 +                      run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
 +              }
 +              if (auto_update_server_info)
 +                      update_server_info(0);
        }
        return 0;
  }
diff --combined git-pull.sh
index 37f3d9301715cd9db92c346c6dcbfe6602a19a35,f36eb3e39736620a4f47d95c795f792bddd0d0e3..bfeb4a0ff65fabaa49b212411ee2451cbf656f3d
@@@ -16,8 -16,7 +16,8 @@@ cd_to_topleve
  test -z "$(git ls-files -u)" ||
        die "You are in the middle of a conflicted merge."
  
 -strategy_args= diffstat= no_commit= squash= no_ff= log_arg= verbosity=
 +strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
 +log_arg= verbosity=
  curr_branch=$(git symbolic-ref -q HEAD)
  curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||")
  rebase=$(git config --bool branch.$curr_branch_short.rebase)
@@@ -46,8 -45,6 +46,8 @@@ d
                no_ff=--ff ;;
        --no-ff)
                no_ff=--no-ff ;;
 +      --ff-only)
 +              ff_only=--ff-only ;;
        -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
                --strateg=*|--strategy=*|\
        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
@@@ -174,7 -171,7 +174,7 @@@ the
        # First update the working tree to match $curr_head.
  
        echo >&2 "Warning: fetch updated the current branch head."
-       echo >&2 "Warning: fast forwarding your working tree from"
+       echo >&2 "Warning: fast-forwarding your working tree from"
        echo >&2 "Warning: commit $orig_head."
        git update-index -q --refresh
        git read-tree -u -m "$orig_head" "$curr_head" ||
@@@ -218,5 -215,5 +218,5 @@@ merge_name=$(git fmt-merge-msg $log_ar
  test true = "$rebase" &&
        exec git-rebase $diffstat $strategy_args --onto $merge_head \
        ${oldremoteref:-$merge_head}
 -exec git-merge $diffstat $no_commit $squash $no_ff $log_arg $strategy_args \
 +exec git-merge $diffstat $no_commit $squash $no_ff $ff_only $log_arg $strategy_args \
        "$merge_name" HEAD $merge_head $verbosity
index 53ad248ee505091d8e11cb9eb82ebb9b017b4262,c8987887f22d844679055c086c0b9ed7dd6d46dd..27daaa9ded9745b6747dc2995ea344ad038443a5
@@@ -168,7 -168,7 +168,7 @@@ pick_one () 
                output git reset --hard $sha1
                test "a$1" = a-n && output git reset --soft $current_sha1
                sha1=$(git rev-parse --short $sha1)
-               output warn Fast forward to $sha1
+               output warn Fast-forward to $sha1
        else
                output git cherry-pick "$@"
        fi
@@@ -248,9 -248,9 +248,9 @@@ pick_one_preserving_merges () 
        done
        case $fast_forward in
        t)
-               output warn "Fast forward to $sha1"
+               output warn "Fast-forward to $sha1"
                output git reset --hard $sha1 ||
-                       die "Cannot fast forward to $sha1"
+                       die "Cannot fast-forward to $sha1"
                ;;
        f)
                first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
@@@ -340,14 -340,6 +340,14 @@@ do_next () 
                pick_one $sha1 ||
                        die_with_patch $sha1 "Could not apply $sha1... $rest"
                ;;
 +      reword|r)
 +              comment_for_reflog reword
 +
 +              mark_action_done
 +              pick_one $sha1 ||
 +                      die_with_patch $sha1 "Could not apply $sha1... $rest"
 +              git commit --amend
 +              ;;
        edit|e)
                comment_for_reflog edit
  
                ;;
        *)
                warn "Unknown command: $command $sha1 $rest"
 -              die_with_patch $sha1 "Please fix this in the file $TODO."
 +              if git rev-parse --verify -q "$sha1" >/dev/null
 +              then
 +                      die_with_patch $sha1 "Please fix this in the file $TODO."
 +              else
 +                      die "Please fix this in the file $TODO."
 +              fi
                ;;
        esac
        test -s "$TODO" && return
@@@ -765,7 -752,6 +765,7 @@@ first and then run 'git rebase --contin
  #
  # Commands:
  #  p, pick = use commit
 +#  r, reword = use commit, but edit the commit message
  #  e, edit = use commit, but stop for amending
  #  s, squash = use commit, but meld into previous commit
  #
diff --combined transport.c
index 298dc46ec5ede0b972ec9be46556ffbec17df253,d81a42aec4fc2e3ab5dfd1fcbb1d6af3372eaf77..d249203eac88810ffef1cdd646e112a082d2c8b8
@@@ -668,7 -668,7 +668,7 @@@ static int print_one_push_status(struc
                break;
        case REF_STATUS_REJECT_NONFASTFORWARD:
                print_ref_status('!', "[rejected]", ref, ref->peer_ref,
-                                                "non-fast forward", porcelain);
+                                                "non-fast-forward", porcelain);
                break;
        case REF_STATUS_REMOTE_REJECT:
                print_ref_status('!', "[remote rejected]", ref,
@@@ -812,9 -812,6 +812,9 @@@ struct transport *transport_get(struct 
  {
        struct transport *ret = xcalloc(1, sizeof(*ret));
  
 +      if (!remote)
 +              die("No remote provided to transport_get()");
 +
        ret->remote = remote;
        ret->url = url;
  
                data->thin = 1;
                data->conn = NULL;
                data->uploadpack = "git-upload-pack";
 -              if (remote && remote->uploadpack)
 +              if (remote->uploadpack)
                        data->uploadpack = remote->uploadpack;
                data->receivepack = "git-receive-pack";
 -              if (remote && remote->receivepack)
 +              if (remote->receivepack)
                        data->receivepack = remote->receivepack;
        }