Re: [PATCH v3] checkout & worktree: introduce checkout.implicitRemote
From: Ævar Arnfjörð Bjarmason <hidden>
Date: 2018-05-31 07:46:01
On Thu, May 24 2018, Ævar Arnfjörð Bjarmason wrote:
struct tracking_name_data {
/* const */ char *src_ref;
char *dst_ref;
struct object_id *dst_oid;
int unique;
+ const char *implicit_remote;
+ char *implicit_dst_ref;
};There's a bug here that I'll fix in a v3. We need to have a implicit_* variant for dst_oid as well. Currently this will be buggy and check out origin/<branch>, but then check the index out to the tree of whatever the last <someremote>/<branch> we iterated over was. Easiy fix and I already have it locally, I just want to improve some of the testing. I missed it because in my tests I'd just re-add the same remote again, so the trees were the same.
quoted hunk ↗ jump to hunk
static int check_tracking_name(struct remote *remote, void *cb_data)@@ -20,6 +23,8 @@ static int check_tracking_name(struct remote *remote, void *cb_data) free(query.dst); return 0; } + if (cb->implicit_remote && !strcmp(remote->name, cb->implicit_remote)) + cb->implicit_dst_ref = xstrdup(query.dst); if (cb->dst_ref) { free(query.dst); cb->unique = 0;@@ -31,13 +36,21 @@ static int check_tracking_name(struct remote *remote, void *cb_data) const char *unique_tracking_name(const char *name, struct object_id *oid) { - struct tracking_name_data cb_data = { NULL, NULL, NULL, 1 }; + const char *implicit_remote = NULL; + struct tracking_name_data cb_data = { NULL, NULL, NULL, 1, NULL, NULL }; + if (!git_config_get_string_const("checkout.implicitremote", &implicit_remote)) + cb_data.implicit_remote = implicit_remote; 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) + free((char *)implicit_remote); + if (cb_data.unique) { + free(cb_data.implicit_dst_ref); return cb_data.dst_ref; + } free(cb_data.dst_ref); + if (cb_data.implicit_dst_ref) + return cb_data.implicit_dst_ref; return NULL; }diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh index 3e5ac81bd2..da6bd74bbc 100755 --- a/t/t2024-checkout-dwim.sh +++ b/t/t2024-checkout-dwim.sh@@ -68,6 +68,16 @@ test_expect_success 'checkout of branch from multiple remotes fails #1' ' test_branch master ' +test_expect_success 'checkout of branch from multiple remotes succeeds with checkout.implicitRemote #1' ' + git checkout -B master && + test_might_fail git branch -D foo && + + git -c checkout.implicitRemote=repo_a checkout foo && + test_branch foo && + test_cmp_rev remotes/repo_a/foo HEAD && + test_branch_upstream foo repo_a foo +' + test_expect_success 'checkout of branch from a single remote succeeds #1' ' git checkout -B master && test_might_fail git branch -D bar &&diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh index 2240498924..271a6413f0 100755 --- a/t/t2025-worktree-add.sh +++ b/t/t2025-worktree-add.sh@@ -402,6 +402,24 @@ test_expect_success '"add" <path> <branch> dwims' ' ) ' +test_expect_success '"add" <path> <branch> dwims with checkout.implicitRemote' ' + 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 remote add repo_upstream2 ../repo_upstream && + git fetch repo_upstream2 && + test_must_fail git worktree add ../foo foo && + git -c checkout.implicitRemote=repo_upstream 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 &&