Merge branch 'tg/worktree-create-tracking'
authorJunio C Hamano <gitster@pobox.com>
Tue, 19 Dec 2017 19:33:57 +0000 (11:33 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 19 Dec 2017 19:33:57 +0000 (11:33 -0800)
The way "git worktree add" determines what branch to create from
where and checkout in the new worktree has been updated a bit.

* tg/worktree-create-tracking:
add worktree.guessRemote config option
worktree: add --guess-remote flag to add subcommand
worktree: make add <path> <branch> dwim
worktree: add --[no-]track option to the add subcommand
worktree: add can be created from any commit-ish
checkout: factor out functions to new lib file

1  2 
Documentation/config.txt
Makefile
builtin/checkout.c
diff --combined Documentation/config.txt
index c1598ee7039fca0439a18b31f186052bbb40bbce,4966d90ebb0de9f8eb37c5116a6253fde703b136..9fac2f2b88c4b26a771b698b40483f3472600c96
@@@ -2108,40 -2108,15 +2108,40 @@@ matched against are those given directl
  visited as a result of a redirection do not participate in matching.
  
  ssh.variant::
 -      Depending on the value of the environment variables `GIT_SSH` or
 -      `GIT_SSH_COMMAND`, or the config setting `core.sshCommand`, Git
 -      auto-detects whether to adjust its command-line parameters for use
 -      with plink or tortoiseplink, as opposed to the default (OpenSSH).
 +      By default, Git determines the command line arguments to use
 +      based on the basename of the configured SSH command (configured
 +      using the environment variable `GIT_SSH` or `GIT_SSH_COMMAND` or
 +      the config setting `core.sshCommand`). If the basename is
 +      unrecognized, Git will attempt to detect support of OpenSSH
 +      options by first invoking the configured SSH command with the
 +      `-G` (print configuration) option and will subsequently use
 +      OpenSSH options (if that is successful) or no options besides
 +      the host and remote command (if it fails).
 ++
 +The config variable `ssh.variant` can be set to override this detection.
 +Valid values are `ssh` (to use OpenSSH options), `plink`, `putty`,
 +`tortoiseplink`, `simple` (no options except the host and remote command).
 +The default auto-detection can be explicitly requested using the value
 +`auto`.  Any other value is treated as `ssh`.  This setting can also be
 +overridden via the environment variable `GIT_SSH_VARIANT`.
 ++
 +The current command-line parameters used for each variant are as
 +follows:
  +
 -The config variable `ssh.variant` can be set to override this auto-detection;
 -valid values are `ssh`, `plink`, `putty` or `tortoiseplink`. Any other value
 -will be treated as normal ssh. This setting can be overridden via the
 -environment variable `GIT_SSH_VARIANT`.
 +--
 +
 +* `ssh` - [-p port] [-4] [-6] [-o option] [username@]host command
 +
 +* `simple` - [username@]host command
 +
 +* `plink` or `putty` - [-P port] [-4] [-6] [username@]host command
 +
 +* `tortoiseplink` - [-P port] [-4] [-6] -batch [username@]host command
 +
 +--
 ++
 +Except for the `simple` variant, command-line parameters are likely to
 +change as git gains new features.
  
  i18n.commitEncoding::
        Character encoding the commit messages are stored in; Git itself
@@@ -2569,23 -2544,6 +2569,23 @@@ The protocol names currently used by gi
      `hg` to allow the `git-remote-hg` helper)
  --
  
 +protocol.version::
 +      Experimental. If set, clients will attempt to communicate with a
 +      server using the specified protocol version.  If unset, no
 +      attempt will be made by the client to communicate using a
 +      particular protocol version, this results in protocol version 0
 +      being used.
 +      Supported versions:
 ++
 +--
 +
 +* `0` - the original wire protocol.
 +
 +* `1` - the original wire protocol with the addition of a version string
 +  in the initial response from the server.
 +
 +--
 +
  pull.ff::
        By default, Git does not create an extra merge commit when merging
        a commit that is a descendant of the current commit. Instead, the
@@@ -3049,7 -3007,6 +3049,7 @@@ sendemail.smtpPass:
  sendemail.suppresscc::
  sendemail.suppressFrom::
  sendemail.to::
 +sendemail.tocmd::
  sendemail.smtpDomain::
  sendemail.smtpServer::
  sendemail.smtpServerPort::
@@@ -3468,3 -3425,13 +3468,13 @@@ web.browser:
        Specify a web browser that may be used by some commands.
        Currently only linkgit:git-instaweb[1] and linkgit:git-help[1]
        may use it.
+ worktree.guessRemote::
+       With `add`, if no branch argument, and neither of `-b` nor
+       `-B` nor `--detach` are given, the command defaults to
+       creating a new branch from HEAD.  If `worktree.guessRemote` is
+       set to true, `worktree add` tries to find a remote-tracking
+       branch whose name uniquely matches the new branch name.  If
+       such a branch exists, it is checked out and set as "upstream"
+       for the new branch.  If no such match can be found, it falls
+       back to creating a new branch from the current HEAD.
diff --combined Makefile
index fef9c8d2725d6806d9ef4516de64c6d68bd7a7fe,a80a8fcca999ed55eee4bdff1d5549dd3c52cd1e..9dc5a588e2998ba5acffd20247a9ac7a4859682a
+++ b/Makefile
@@@ -759,6 -759,7 +759,7 @@@ LIB_OBJS += branch.
  LIB_OBJS += bulk-checkin.o
  LIB_OBJS += bundle.o
  LIB_OBJS += cache-tree.o
+ LIB_OBJS += checkout.o
  LIB_OBJS += color.o
  LIB_OBJS += column.o
  LIB_OBJS += combine-diff.o
@@@ -849,7 -850,6 +850,7 @@@ LIB_OBJS += pretty.
  LIB_OBJS += prio-queue.o
  LIB_OBJS += progress.o
  LIB_OBJS += prompt.o
 +LIB_OBJS += protocol.o
  LIB_OBJS += quote.o
  LIB_OBJS += reachable.o
  LIB_OBJS += read-cache.o
diff --combined builtin/checkout.c
index e1e157d205a06ffad39a9685cab55b16c69d339c,ad8f94044cfcfe4b73176c35093a5f2994ca77c0..9b886356bff5005a2775e5d2cbe998df1d3d5cf1
@@@ -1,5 -1,6 +1,6 @@@
  #include "builtin.h"
  #include "config.h"
+ #include "checkout.h"
  #include "lockfile.h"
  #include "parse-options.h"
  #include "refs.h"
@@@ -514,7 -515,7 +515,7 @@@ static int merge_working_tree(const str
                }
                tree = parse_tree_indirect(old->commit ?
                                           &old->commit->object.oid :
 -                                         &empty_tree_oid);
 +                                         the_hash_algo->empty_tree);
                init_tree_desc(&trees[0], tree->buffer, tree->size);
                tree = parse_tree_indirect(&new->commit->object.oid);
                init_tree_desc(&trees[1], tree->buffer, tree->size);
@@@ -872,46 -873,6 +873,6 @@@ static int git_checkout_config(const ch
        return git_xmerge_config(var, value, NULL);
  }
  
- struct tracking_name_data {
-       /* const */ char *src_ref;
-       char *dst_ref;
-       struct object_id *dst_oid;
-       int unique;
- };
- static int check_tracking_name(struct remote *remote, void *cb_data)
- {
-       struct tracking_name_data *cb = cb_data;
-       struct refspec query;
-       memset(&query, 0, sizeof(struct refspec));
-       query.src = cb->src_ref;
-       if (remote_find_tracking(remote, &query) ||
-           get_oid(query.dst, cb->dst_oid)) {
-               free(query.dst);
-               return 0;
-       }
-       if (cb->dst_ref) {
-               free(query.dst);
-               cb->unique = 0;
-               return 0;
-       }
-       cb->dst_ref = query.dst;
-       return 0;
- }
- static const char *unique_tracking_name(const char *name, struct object_id *oid)
- {
-       struct tracking_name_data cb_data = { NULL, NULL, NULL, 1 };
-       cb_data.src_ref = xstrfmt("refs/heads/%s", name);
-       cb_data.dst_oid = oid;
-       for_each_remote(check_tracking_name, &cb_data);
-       free(cb_data.src_ref);
-       if (cb_data.unique)
-               return cb_data.dst_ref;
-       free(cb_data.dst_ref);
-       return NULL;
- }
  static int parse_branchname_arg(int argc, const char **argv,
                                int dwim_new_local_branch_ok,
                                struct branch_info *new,
@@@ -1287,11 -1248,11 +1248,11 @@@ int cmd_checkout(int argc, const char *
        if (opts.new_branch) {
                struct strbuf buf = STRBUF_INIT;
  
 -              opts.branch_exists =
 -                      validate_new_branchname(opts.new_branch, &buf,
 -                                              !!opts.new_branch_force,
 -                                              !!opts.new_branch_force);
 -
 +              if (opts.new_branch_force)
 +                      opts.branch_exists = validate_branchname(opts.new_branch, &buf);
 +              else
 +                      opts.branch_exists =
 +                              validate_new_branchname(opts.new_branch, &buf, 0);
                strbuf_release(&buf);
        }