Merge branch 'tg/worktree-create-tracking'
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 filemaint
commit
66d3f19324
|
@ -3468,3 +3468,13 @@ web.browser::
|
||||||
Specify a web browser that may be used by some commands.
|
Specify a web browser that may be used by some commands.
|
||||||
Currently only linkgit:git-instaweb[1] and linkgit:git-help[1]
|
Currently only linkgit:git-instaweb[1] and linkgit:git-help[1]
|
||||||
may use it.
|
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.
|
||||||
|
|
|
@ -9,7 +9,7 @@ git-worktree - Manage multiple working trees
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git worktree add' [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<branch>]
|
'git worktree add' [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>]
|
||||||
'git worktree list' [--porcelain]
|
'git worktree list' [--porcelain]
|
||||||
'git worktree lock' [--reason <string>] <worktree>
|
'git worktree lock' [--reason <string>] <worktree>
|
||||||
'git worktree prune' [-n] [-v] [--expire <expire>]
|
'git worktree prune' [-n] [-v] [--expire <expire>]
|
||||||
|
@ -45,14 +45,22 @@ specifying `--reason` to explain why the working tree is locked.
|
||||||
|
|
||||||
COMMANDS
|
COMMANDS
|
||||||
--------
|
--------
|
||||||
add <path> [<branch>]::
|
add <path> [<commit-ish>]::
|
||||||
|
|
||||||
Create `<path>` and checkout `<branch>` into it. The new working directory
|
Create `<path>` and checkout `<commit-ish>` into it. The new working directory
|
||||||
is linked to the current repository, sharing everything except working
|
is linked to the current repository, sharing everything except working
|
||||||
directory specific files such as HEAD, index, etc. `-` may also be
|
directory specific files such as HEAD, index, etc. `-` may also be
|
||||||
specified as `<branch>`; it is synonymous with `@{-1}`.
|
specified as `<commit-ish>`; it is synonymous with `@{-1}`.
|
||||||
+
|
+
|
||||||
If `<branch>` is omitted and neither `-b` nor `-B` nor `--detach` used,
|
If <commit-ish> is a branch name (call it `<branch>` and is not found,
|
||||||
|
and neither `-b` nor `-B` nor `--detach` are used, but there does
|
||||||
|
exist a tracking branch in exactly one remote (call it `<remote>`)
|
||||||
|
with a matching name, treat as equivalent to
|
||||||
|
------------
|
||||||
|
$ git worktree add --track -b <branch> <path> <remote>/<branch>
|
||||||
|
------------
|
||||||
|
+
|
||||||
|
If `<commit-ish>` is omitted and neither `-b` nor `-B` nor `--detach` used,
|
||||||
then, as a convenience, a new branch based at HEAD is created automatically,
|
then, as a convenience, a new branch based at HEAD is created automatically,
|
||||||
as if `-b $(basename <path>)` was specified.
|
as if `-b $(basename <path>)` was specified.
|
||||||
|
|
||||||
|
@ -84,29 +92,45 @@ OPTIONS
|
||||||
|
|
||||||
-f::
|
-f::
|
||||||
--force::
|
--force::
|
||||||
By default, `add` refuses to create a new working tree when `<branch>`
|
By default, `add` refuses to create a new working tree when `<commit-ish>` is a branch name and
|
||||||
is already checked out by another working tree. This option overrides
|
is already checked out by another working tree. This option overrides
|
||||||
that safeguard.
|
that safeguard.
|
||||||
|
|
||||||
-b <new-branch>::
|
-b <new-branch>::
|
||||||
-B <new-branch>::
|
-B <new-branch>::
|
||||||
With `add`, create a new branch named `<new-branch>` starting at
|
With `add`, create a new branch named `<new-branch>` starting at
|
||||||
`<branch>`, and check out `<new-branch>` into the new working tree.
|
`<commit-ish>`, and check out `<new-branch>` into the new working tree.
|
||||||
If `<branch>` is omitted, it defaults to HEAD.
|
If `<commit-ish>` is omitted, it defaults to HEAD.
|
||||||
By default, `-b` refuses to create a new branch if it already
|
By default, `-b` refuses to create a new branch if it already
|
||||||
exists. `-B` overrides this safeguard, resetting `<new-branch>` to
|
exists. `-B` overrides this safeguard, resetting `<new-branch>` to
|
||||||
`<branch>`.
|
`<commit-ish>`.
|
||||||
|
|
||||||
--detach::
|
--detach::
|
||||||
With `add`, detach HEAD in the new working tree. See "DETACHED HEAD"
|
With `add`, detach HEAD in the new working tree. See "DETACHED HEAD"
|
||||||
in linkgit:git-checkout[1].
|
in linkgit:git-checkout[1].
|
||||||
|
|
||||||
--[no-]checkout::
|
--[no-]checkout::
|
||||||
By default, `add` checks out `<branch>`, however, `--no-checkout` can
|
By default, `add` checks out `<commit-ish>`, however, `--no-checkout` can
|
||||||
be used to suppress checkout in order to make customizations,
|
be used to suppress checkout in order to make customizations,
|
||||||
such as configuring sparse-checkout. See "Sparse checkout"
|
such as configuring sparse-checkout. See "Sparse checkout"
|
||||||
in linkgit:git-read-tree[1].
|
in linkgit:git-read-tree[1].
|
||||||
|
|
||||||
|
--[no-]guess-remote::
|
||||||
|
With `worktree add <path>`, without `<commit-ish>`, instead
|
||||||
|
of creating a new branch from HEAD, if there exists a tracking
|
||||||
|
branch in exactly one remote matching the basename of `<path>,
|
||||||
|
base the new branch on the remote-tracking branch, and mark
|
||||||
|
the remote-tracking branch as "upstream" from the new branch.
|
||||||
|
+
|
||||||
|
This can also be set up as the default behaviour by using the
|
||||||
|
`worktree.guessRemote` config option.
|
||||||
|
|
||||||
|
--[no-]track::
|
||||||
|
When creating a new branch, if `<commit-ish>` is a branch,
|
||||||
|
mark it as "upstream" from the new branch. This is the
|
||||||
|
default if `<commit-ish>` is a remote-tracking branch. See
|
||||||
|
"--track" in linkgit:git-branch[1] for details.
|
||||||
|
|
||||||
--lock::
|
--lock::
|
||||||
Keep the working tree locked after creation. This is the
|
Keep the working tree locked after creation. This is the
|
||||||
equivalent of `git worktree lock` after `git worktree add`,
|
equivalent of `git worktree lock` after `git worktree add`,
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -759,6 +759,7 @@ LIB_OBJS += branch.o
|
||||||
LIB_OBJS += bulk-checkin.o
|
LIB_OBJS += bulk-checkin.o
|
||||||
LIB_OBJS += bundle.o
|
LIB_OBJS += bundle.o
|
||||||
LIB_OBJS += cache-tree.o
|
LIB_OBJS += cache-tree.o
|
||||||
|
LIB_OBJS += checkout.o
|
||||||
LIB_OBJS += color.o
|
LIB_OBJS += color.o
|
||||||
LIB_OBJS += column.o
|
LIB_OBJS += column.o
|
||||||
LIB_OBJS += combine-diff.o
|
LIB_OBJS += combine-diff.o
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "checkout.h"
|
||||||
#include "lockfile.h"
|
#include "lockfile.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
|
@ -872,46 +873,6 @@ static int git_checkout_config(const char *var, const char *value, void *cb)
|
||||||
return git_xmerge_config(var, value, NULL);
|
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,
|
static int parse_branchname_arg(int argc, const char **argv,
|
||||||
int dwim_new_local_branch_ok,
|
int dwim_new_local_branch_ok,
|
||||||
struct branch_info *new,
|
struct branch_info *new,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "checkout.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
|
@ -32,8 +33,19 @@ struct add_opts {
|
||||||
|
|
||||||
static int show_only;
|
static int show_only;
|
||||||
static int verbose;
|
static int verbose;
|
||||||
|
static int guess_remote;
|
||||||
static timestamp_t expire;
|
static timestamp_t expire;
|
||||||
|
|
||||||
|
static int git_worktree_config(const char *var, const char *value, void *cb)
|
||||||
|
{
|
||||||
|
if (!strcmp(var, "worktree.guessremote")) {
|
||||||
|
guess_remote = git_config_bool(var, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return git_default_config(var, value, cb);
|
||||||
|
}
|
||||||
|
|
||||||
static int prune_worktree(const char *id, struct strbuf *reason)
|
static int prune_worktree(const char *id, struct strbuf *reason)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -341,6 +353,7 @@ static int add(int ac, const char **av, const char *prefix)
|
||||||
const char *new_branch_force = NULL;
|
const char *new_branch_force = NULL;
|
||||||
char *path;
|
char *path;
|
||||||
const char *branch;
|
const char *branch;
|
||||||
|
const char *opt_track = NULL;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT__FORCE(&opts.force, N_("checkout <branch> even if already checked out in other worktree")),
|
OPT__FORCE(&opts.force, N_("checkout <branch> even if already checked out in other worktree")),
|
||||||
OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
|
OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
|
||||||
|
@ -350,6 +363,11 @@ static int add(int ac, const char **av, const char *prefix)
|
||||||
OPT_BOOL(0, "detach", &opts.detach, N_("detach HEAD at named commit")),
|
OPT_BOOL(0, "detach", &opts.detach, N_("detach HEAD at named commit")),
|
||||||
OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")),
|
OPT_BOOL(0, "checkout", &opts.checkout, N_("populate the new working tree")),
|
||||||
OPT_BOOL(0, "lock", &opts.keep_locked, N_("keep the new working tree locked")),
|
OPT_BOOL(0, "lock", &opts.keep_locked, N_("keep the new working tree locked")),
|
||||||
|
OPT_PASSTHRU(0, "track", &opt_track, NULL,
|
||||||
|
N_("set up tracking mode (see git-branch(1))"),
|
||||||
|
PARSE_OPT_NOARG | PARSE_OPT_OPTARG),
|
||||||
|
OPT_BOOL(0, "guess-remote", &guess_remote,
|
||||||
|
N_("try to match the new branch name with a remote-tracking branch")),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -384,6 +402,28 @@ static int add(int ac, const char **av, const char *prefix)
|
||||||
int n;
|
int n;
|
||||||
const char *s = worktree_basename(path, &n);
|
const char *s = worktree_basename(path, &n);
|
||||||
opts.new_branch = xstrndup(s, n);
|
opts.new_branch = xstrndup(s, n);
|
||||||
|
if (guess_remote) {
|
||||||
|
struct object_id oid;
|
||||||
|
const char *remote =
|
||||||
|
unique_tracking_name(opts.new_branch, &oid);
|
||||||
|
if (remote)
|
||||||
|
branch = remote;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ac == 2 && !opts.new_branch && !opts.detach) {
|
||||||
|
struct object_id oid;
|
||||||
|
struct commit *commit;
|
||||||
|
const char *remote;
|
||||||
|
|
||||||
|
commit = lookup_commit_reference_by_name(branch);
|
||||||
|
if (!commit) {
|
||||||
|
remote = unique_tracking_name(branch, &oid);
|
||||||
|
if (remote) {
|
||||||
|
opts.new_branch = branch;
|
||||||
|
branch = remote;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.new_branch) {
|
if (opts.new_branch) {
|
||||||
|
@ -394,9 +434,13 @@ static int add(int ac, const char **av, const char *prefix)
|
||||||
argv_array_push(&cp.args, "--force");
|
argv_array_push(&cp.args, "--force");
|
||||||
argv_array_push(&cp.args, opts.new_branch);
|
argv_array_push(&cp.args, opts.new_branch);
|
||||||
argv_array_push(&cp.args, branch);
|
argv_array_push(&cp.args, branch);
|
||||||
|
if (opt_track)
|
||||||
|
argv_array_push(&cp.args, opt_track);
|
||||||
if (run_command(&cp))
|
if (run_command(&cp))
|
||||||
return -1;
|
return -1;
|
||||||
branch = opts.new_branch;
|
branch = opts.new_branch;
|
||||||
|
} else if (opt_track) {
|
||||||
|
die(_("--[no-]track can only be used if a new branch is created"));
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLEAK(path);
|
UNLEAK(path);
|
||||||
|
@ -557,7 +601,7 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
git_config(git_default_config, NULL);
|
git_config(git_worktree_config, NULL);
|
||||||
|
|
||||||
if (ac < 2)
|
if (ac < 2)
|
||||||
usage_with_options(worktree_usage, options);
|
usage_with_options(worktree_usage, options);
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#include "cache.h"
|
||||||
|
#include "remote.h"
|
||||||
|
#include "checkout.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef CHECKOUT_H
|
||||||
|
#define CHECKOUT_H
|
||||||
|
|
||||||
|
#include "cache.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the branch name uniquely matches a branch name on a remote
|
||||||
|
* tracking branch. Return the name of the remote if such a branch
|
||||||
|
* exists, NULL otherwise.
|
||||||
|
*/
|
||||||
|
extern const char *unique_tracking_name(const char *name, struct object_id *oid);
|
||||||
|
|
||||||
|
#endif /* CHECKOUT_H */
|
|
@ -313,5 +313,135 @@ test_expect_success 'checkout a branch under bisect' '
|
||||||
test_expect_success 'rename a branch under bisect not allowed' '
|
test_expect_success 'rename a branch under bisect not allowed' '
|
||||||
test_must_fail git branch -M under-bisect bisect-with-new-name
|
test_must_fail git branch -M under-bisect bisect-with-new-name
|
||||||
'
|
'
|
||||||
|
# Is branch "refs/heads/$1" set to pull from "$2/$3"?
|
||||||
|
test_branch_upstream () {
|
||||||
|
printf "%s\n" "$2" "refs/heads/$3" >expect.upstream &&
|
||||||
|
{
|
||||||
|
git config "branch.$1.remote" &&
|
||||||
|
git config "branch.$1.merge"
|
||||||
|
} >actual.upstream &&
|
||||||
|
test_cmp expect.upstream actual.upstream
|
||||||
|
}
|
||||||
|
|
||||||
|
test_expect_success '--track sets up tracking' '
|
||||||
|
test_when_finished rm -rf track &&
|
||||||
|
git worktree add --track -b track track master &&
|
||||||
|
test_branch_upstream track . master
|
||||||
|
'
|
||||||
|
|
||||||
|
# setup remote repository $1 and repository $2 with $1 set up as
|
||||||
|
# remote. The remote has two branches, master and foo.
|
||||||
|
setup_remote_repo () {
|
||||||
|
git init $1 &&
|
||||||
|
(
|
||||||
|
cd $1 &&
|
||||||
|
test_commit $1_master &&
|
||||||
|
git checkout -b foo &&
|
||||||
|
test_commit upstream_foo
|
||||||
|
) &&
|
||||||
|
git init $2 &&
|
||||||
|
(
|
||||||
|
cd $2 &&
|
||||||
|
test_commit $2_master &&
|
||||||
|
git remote add $1 ../$1 &&
|
||||||
|
git config remote.$1.fetch \
|
||||||
|
"refs/heads/*:refs/remotes/$1/*" &&
|
||||||
|
git fetch --all
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
test_expect_success '--no-track avoids setting up tracking' '
|
||||||
|
test_when_finished rm -rf repo_upstream repo_local foo &&
|
||||||
|
setup_remote_repo repo_upstream repo_local &&
|
||||||
|
(
|
||||||
|
cd repo_local &&
|
||||||
|
git worktree add --no-track -b foo ../foo repo_upstream/foo
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd foo &&
|
||||||
|
test_must_fail git config "branch.foo.remote" &&
|
||||||
|
test_must_fail git config "branch.foo.merge" &&
|
||||||
|
test_cmp_rev refs/remotes/repo_upstream/foo refs/heads/foo
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '"add" <path> <non-existent-branch> fails' '
|
||||||
|
test_must_fail git worktree add foo non-existent
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '"add" <path> <branch> dwims' '
|
||||||
|
test_when_finished rm -rf repo_upstream repo_dwim foo &&
|
||||||
|
setup_remote_repo repo_upstream repo_dwim &&
|
||||||
|
git init repo_dwim &&
|
||||||
|
(
|
||||||
|
cd repo_dwim &&
|
||||||
|
git worktree add ../foo foo
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd foo &&
|
||||||
|
test_branch_upstream foo repo_upstream foo &&
|
||||||
|
test_cmp_rev refs/remotes/repo_upstream/foo refs/heads/foo
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'git worktree add does not match remote' '
|
||||||
|
test_when_finished rm -rf repo_a repo_b foo &&
|
||||||
|
setup_remote_repo repo_a repo_b &&
|
||||||
|
(
|
||||||
|
cd repo_b &&
|
||||||
|
git worktree add ../foo
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd foo &&
|
||||||
|
test_must_fail git config "branch.foo.remote" &&
|
||||||
|
test_must_fail git config "branch.foo.merge" &&
|
||||||
|
! test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'git worktree add --guess-remote sets up tracking' '
|
||||||
|
test_when_finished rm -rf repo_a repo_b foo &&
|
||||||
|
setup_remote_repo repo_a repo_b &&
|
||||||
|
(
|
||||||
|
cd repo_b &&
|
||||||
|
git worktree add --guess-remote ../foo
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd foo &&
|
||||||
|
test_branch_upstream foo repo_a foo &&
|
||||||
|
test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'git worktree add with worktree.guessRemote sets up tracking' '
|
||||||
|
test_when_finished rm -rf repo_a repo_b foo &&
|
||||||
|
setup_remote_repo repo_a repo_b &&
|
||||||
|
(
|
||||||
|
cd repo_b &&
|
||||||
|
git config worktree.guessRemote true &&
|
||||||
|
git worktree add ../foo
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd foo &&
|
||||||
|
test_branch_upstream foo repo_a foo &&
|
||||||
|
test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'git worktree --no-guess-remote option overrides config' '
|
||||||
|
test_when_finished rm -rf repo_a repo_b foo &&
|
||||||
|
setup_remote_repo repo_a repo_b &&
|
||||||
|
(
|
||||||
|
cd repo_b &&
|
||||||
|
git config worktree.guessRemote true &&
|
||||||
|
git worktree add --no-guess-remote ../foo
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cd foo &&
|
||||||
|
test_must_fail git config "branch.foo.remote" &&
|
||||||
|
test_must_fail git config "branch.foo.merge" &&
|
||||||
|
! test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in New Issue