Message ID | 9628d145881cb875f8e284967e10f587b9f686f9.1631126999.git.steadmon@google.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [RFC] branch: add "inherit" option for branch.autoSetupMerge | expand |
Actually, this patch probably makes zero sense without [1], an old RFC patch to use a more repo-like workflow that we've been using internally at $job. Hopefully I can get a v2 that doesn't depend on this. [1]: https://lore.kernel.org/git/20180927221603.148025-1-sbeller@google.com/
Josh Steadmon <steadmon@google.com> writes: > +static int inherit_tracking(struct tracking *tracking, const char *orig_ref) > +{ > + struct strbuf key = STRBUF_INIT; > + char *remote; > + const char *bare_ref; > + > + bare_ref = orig_ref; > + skip_prefix(orig_ref, "refs/heads/", &bare_ref); > + > + strbuf_addf(&key, "branch.%s.remote", bare_ref); > + if (git_config_get_string(key.buf, &remote)) { > + warning("branch.autoSetupMerge=inherit, but could not find %s", > + key.buf); > + strbuf_release(&key); > + return 1; > + } > + tracking->remote = remote; > + > + strbuf_reset(&key); > + strbuf_addf(&key, "branch.%s.merge", bare_ref); > + if (git_config_get_string(key.buf, &tracking->src)) { > + warning("branch.autoSetupMerge=inherit, but could not find %s", > + key.buf); > + strbuf_release(&key); > + return 1; > + } > + > + tracking->matches = 1; > + strbuf_release(&key); > + return 0; > +} I believe that we can get the branch remote via struct branch. Instead of reading the config, we could do something along the lines of: int *explicit; struct branch *branch = branch_get(); char *remote = remote_for_branch(branch, explicit); /* Optionally check explicit if we don't want to fall back to * "origin" */ I'm not sure which is the idiomatic way to get the branch remote, feel free to correct me.
Glen Choo <chooglen@google.com> writes: > I believe that we can get the branch remote via struct branch. Instead > of reading the config, we could do something along the lines of: > > int *explicit; > struct branch *branch = branch_get(); > char *remote = remote_for_branch(branch, explicit); > /* Optionally check explicit if we don't want to fall back to > * "origin" */ > > I'm not sure which is the idiomatic way to get the branch remote, feel > free to correct me. Gah, I read and responded to v1 thinking it was v3. Reading v3, it looks like the feedback is still relevant, so please pretend I responded to the right email :P
On 2021.10.18 10:50, Glen Choo wrote: > Josh Steadmon <steadmon@google.com> writes: > > > +static int inherit_tracking(struct tracking *tracking, const char *orig_ref) > > +{ > > + struct strbuf key = STRBUF_INIT; > > + char *remote; > > + const char *bare_ref; > > + > > + bare_ref = orig_ref; > > + skip_prefix(orig_ref, "refs/heads/", &bare_ref); > > + > > + strbuf_addf(&key, "branch.%s.remote", bare_ref); > > + if (git_config_get_string(key.buf, &remote)) { > > + warning("branch.autoSetupMerge=inherit, but could not find %s", > > + key.buf); > > + strbuf_release(&key); > > + return 1; > > + } > > + tracking->remote = remote; > > + > > + strbuf_reset(&key); > > + strbuf_addf(&key, "branch.%s.merge", bare_ref); > > + if (git_config_get_string(key.buf, &tracking->src)) { > > + warning("branch.autoSetupMerge=inherit, but could not find %s", > > + key.buf); > > + strbuf_release(&key); > > + return 1; > > + } > > + > > + tracking->matches = 1; > > + strbuf_release(&key); > > + return 0; > > +} > > I believe that we can get the branch remote via struct branch. Instead > of reading the config, we could do something along the lines of: > > int *explicit; > struct branch *branch = branch_get(); > char *remote = remote_for_branch(branch, explicit); > /* Optionally check explicit if we don't want to fall back to > * "origin" */ > > I'm not sure which is the idiomatic way to get the branch remote, feel > free to correct me. Will fix in V4, thanks.
diff --git a/branch.c b/branch.c index 7a88a4861e..17d4cc5128 100644 --- a/branch.c +++ b/branch.c @@ -126,6 +126,38 @@ int install_branch_config(int flag, const char *local, const char *origin, const return -1; } +static int inherit_tracking(struct tracking *tracking, const char *orig_ref) +{ + struct strbuf key = STRBUF_INIT; + char *remote; + const char *bare_ref; + + bare_ref = orig_ref; + skip_prefix(orig_ref, "refs/heads/", &bare_ref); + + strbuf_addf(&key, "branch.%s.remote", bare_ref); + if (git_config_get_string(key.buf, &remote)) { + warning("branch.autoSetupMerge=inherit, but could not find %s", + key.buf); + strbuf_release(&key); + return 1; + } + tracking->remote = remote; + + strbuf_reset(&key); + strbuf_addf(&key, "branch.%s.merge", bare_ref); + if (git_config_get_string(key.buf, &tracking->src)) { + warning("branch.autoSetupMerge=inherit, but could not find %s", + key.buf); + strbuf_release(&key); + return 1; + } + + tracking->matches = 1; + strbuf_release(&key); + return 0; +} + /* * This is called when new_ref is branched off of orig_ref, and tries * to infer the settings for branch.<new_ref>.{remote,merge} from the @@ -139,7 +171,9 @@ static void setup_tracking(const char *new_ref, const char *orig_ref, memset(&tracking, 0, sizeof(tracking)); tracking.spec.dst = (char *)orig_ref; - if (for_each_remote(find_tracked_branch, &tracking)) + if (track == BRANCH_TRACK_INHERIT && inherit_tracking(&tracking, orig_ref)) + return; + else if (for_each_remote(find_tracked_branch, &tracking)) return; if (!tracking.matches) diff --git a/branch.h b/branch.h index df0be61506..6484bda8a2 100644 --- a/branch.h +++ b/branch.h @@ -10,7 +10,8 @@ enum branch_track { BRANCH_TRACK_REMOTE, BRANCH_TRACK_ALWAYS, BRANCH_TRACK_EXPLICIT, - BRANCH_TRACK_OVERRIDE + BRANCH_TRACK_OVERRIDE, + BRANCH_TRACK_INHERIT }; extern enum branch_track git_branch_track; diff --git a/config.c b/config.c index cb4a8058bf..4bd5a18faf 100644 --- a/config.c +++ b/config.c @@ -1580,6 +1580,9 @@ static int git_default_branch_config(const char *var, const char *value) if (value && !strcasecmp(value, "always")) { git_branch_track = BRANCH_TRACK_ALWAYS; return 0; + } else if (value && !strcasecmp(value, "inherit")) { + git_branch_track = BRANCH_TRACK_INHERIT; + return 0; } git_branch_track = git_config_bool(var, value); return 0;
It can be helpful when creating a new branch to use the existing tracking configuration from the branch point. However, there is currently not a method to automatically do so. Teach branch.autoSetupMerge a new "inherit" option. When this is set, creating a new branch will cause the tracking configuration to default to the configuration of the branch point, if set. NEEDS WORK: * this breaks `git checkout -b new-branch --recurse-submodules` * add documentation * add tests * check corner cases, including whether this plays well with related cmd-line options (switch, checkout, branch) Signed-off-by: Josh Steadmon <steadmon@google.com> --- I'll be looking into the --recurse-submodules breakage today, and then I'll work on polishing the patch after that's fixed. But I thought it's worth getting an idea of how the list feels about the feature in general while I sort through the issues. branch.c | 36 +++++++++++++++++++++++++++++++++++- branch.h | 3 ++- config.c | 3 +++ 3 files changed, 40 insertions(+), 2 deletions(-)