Merge branch 'jk/pull-to-integrate'
authorJunio C Hamano <gitster@pobox.com>
Fri, 12 Jul 2013 19:04:06 +0000 (12:04 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 12 Jul 2013 19:04:06 +0000 (12:04 -0700)
* jk/pull-to-integrate:
pull: change the description to "integrate" changes
push: avoid suggesting "merging" remote changes

1  2 
builtin/push.c
git-pull.sh
diff --combined builtin/push.c
index a2580a94f577e5e1a5e58fc91c67f9ca48a78f19,878dd9d8bbe66d6a9e24f122c53987044fe27c2c..6d36c24268bea3cb658a1aa94f3a037f403d5895
@@@ -113,20 -113,17 +113,20 @@@ static NORETURN int die_push_simple(str
            remote->name, branch->name, advice_maybe);
  }
  
 -static void setup_push_upstream(struct remote *remote, int simple)
 +static const char message_detached_head_die[] =
 +      N_("You are not currently on a branch.\n"
 +         "To push the history leading to the current (detached HEAD)\n"
 +         "state now, use\n"
 +         "\n"
 +         "    git push %s HEAD:<name-of-remote-branch>\n");
 +
 +static void setup_push_upstream(struct remote *remote, struct branch *branch,
 +                              int triangular)
  {
        struct strbuf refspec = STRBUF_INIT;
 -      struct branch *branch = branch_get(NULL);
 +
        if (!branch)
 -              die(_("You are not currently on a branch.\n"
 -                  "To push the history leading to the current (detached HEAD)\n"
 -                  "state now, use\n"
 -                  "\n"
 -                  "    git push %s HEAD:<name-of-remote-branch>\n"),
 -                  remote->name);
 +              die(_(message_detached_head_die), remote->name);
        if (!branch->merge_nr || !branch->merge || !branch->remote_name)
                die(_("The current branch %s has no upstream branch.\n"
                    "To push the current branch and set the remote as upstream, use\n"
        if (branch->merge_nr != 1)
                die(_("The current branch %s has multiple upstream branches, "
                    "refusing to push."), branch->name);
 -      if (strcmp(branch->remote_name, remote->name))
 +      if (triangular)
                die(_("You are pushing to remote '%s', which is not the upstream of\n"
                      "your current branch '%s', without telling me what to push\n"
                      "to update which remote branch."),
                    remote->name, branch->name);
 -      if (simple && strcmp(branch->refname, branch->merge[0]->src))
 -              die_push_simple(branch, remote);
 +
 +      if (push_default == PUSH_DEFAULT_SIMPLE) {
 +              /* Additional safety */
 +              if (strcmp(branch->refname, branch->merge[0]->src))
 +                      die_push_simple(branch, remote);
 +      }
  
        strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
        add_refspec(refspec.buf);
  }
  
 +static void setup_push_current(struct remote *remote, struct branch *branch)
 +{
 +      if (!branch)
 +              die(_(message_detached_head_die), remote->name);
 +      add_refspec(branch->name);
 +}
 +
  static char warn_unspecified_push_default_msg[] =
  N_("push.default is unset; its implicit value is changing in\n"
     "Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@@ -185,17 -171,8 +185,17 @@@ static void warn_unspecified_push_defau
        warning("%s\n", _(warn_unspecified_push_default_msg));
  }
  
 +static int is_workflow_triangular(struct remote *remote)
 +{
 +      struct remote *fetch_remote = remote_get(NULL);
 +      return (fetch_remote && fetch_remote != remote);
 +}
 +
  static void setup_default_push_refspecs(struct remote *remote)
  {
 +      struct branch *branch = branch_get(NULL);
 +      int triangular = is_workflow_triangular(remote);
 +
        switch (push_default) {
        default:
        case PUSH_DEFAULT_UNSPECIFIED:
                break;
  
        case PUSH_DEFAULT_SIMPLE:
 -              setup_push_upstream(remote, 1);
 +              if (triangular)
 +                      setup_push_current(remote, branch);
 +              else
 +                      setup_push_upstream(remote, branch, triangular);
                break;
  
        case PUSH_DEFAULT_UPSTREAM:
 -              setup_push_upstream(remote, 0);
 +              setup_push_upstream(remote, branch, triangular);
                break;
  
        case PUSH_DEFAULT_CURRENT:
 -              add_refspec("HEAD");
 +              setup_push_current(remote, branch);
                break;
  
        case PUSH_DEFAULT_NOTHING:
  
  static const char message_advice_pull_before_push[] =
        N_("Updates were rejected because the tip of your current branch is behind\n"
-          "its remote counterpart. Merge the remote changes (e.g. 'git pull')\n"
-          "before pushing again.\n"
+          "its remote counterpart. Integrate the remote changes (e.g.\n"
+          "'git pull ...') before pushing again.\n"
           "See the 'Note about fast-forwards' in 'git push --help' for details.");
  
  static const char message_advice_use_upstream[] =
  
  static const char message_advice_checkout_pull_push[] =
        N_("Updates were rejected because a pushed branch tip is behind its remote\n"
-          "counterpart. Check out this branch and merge the remote changes\n"
-          "(e.g. 'git pull') before pushing again.\n"
+          "counterpart. Check out this branch and integrate the remote changes\n"
+          "(e.g. 'git pull ...') before pushing again.\n"
           "See the 'Note about fast-forwards' in 'git push --help' for details.");
  
  static const char message_advice_ref_fetch_first[] =
        N_("Updates were rejected because the remote contains work that you do\n"
           "not have locally. This is usually caused by another repository pushing\n"
-          "to the same ref. You may want to first merge the remote changes (e.g.,\n"
-          "'git pull') before pushing again.\n"
+          "to the same ref. You may want to first integrate the remote changes\n"
+          "(e.g., 'git pull ...') before pushing again.\n"
           "See the 'Note about fast-forwards' in 'git push --help' for details.");
  
  static const char message_advice_ref_already_exists[] =
diff --combined git-pull.sh
index 6828e2c7157fd80905e864b475c11ccc7a330e03,58597dbd9b6b7464dc9e02af3ae72b1cca3c34a6..f0df41c841644208c89230516677db162498be26
@@@ -5,7 -5,7 +5,7 @@@
  # Fetch one or more remote refs and merge it/them into the current HEAD.
  
  USAGE='[-n | --no-stat] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
- LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
+ LONG_USAGE='Fetch one or more remote refs and integrate it/them with the current HEAD.'
  SUBDIRECTORY_OK=Yes
  OPTIONS_SPEC=
  . git-sh-setup
@@@ -266,17 -266,10 +266,17 @@@ case "$merge_head" i
        ;;
  esac
  
 +# Pulling into unborn branch: a shorthand for branching off
 +# FETCH_HEAD, for lazy typers.
  if test -z "$orig_head"
  then
 -      git update-ref -m "initial pull" HEAD $merge_head "$curr_head" &&
 -      git read-tree -m -u HEAD || exit 1
 +      # Two-way merge: we claim the index is based on an empty tree,
 +      # and try to fast-forward to HEAD.  This ensures we will not
 +      # lose index/worktree changes that the user already made on
 +      # the unborn branch.
 +      empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
 +      git read-tree -m -u $empty_tree $merge_head &&
 +      git update-ref -m "initial pull" HEAD $merge_head "$curr_head"
        exit
  fi