* [RFC/PATCH] branch: new option --will-track
@ 2009-12-16 9:39 Dave Olszewski
2009-12-18 0:07 ` Junio C Hamano
0 siblings, 1 reply; 5+ messages in thread
From: Dave Olszewski @ 2009-12-16 9:39 UTC (permalink / raw)
To: git; +Cc: Dave Olszewski
A common question from users creating branches in an environment where
they intend to push the branch to a shared bare repository, and then
later pull commits from upstream into the branch that they initially
created, is how do they create the branch with this tracking info
already set up.
This feature allows them to pre-specify the tracking info in their
config, so that after the branch has been pushed, no futher action is
needed to pull future commits.
Signed-off-by: Dave Olszewski <cxreg@pobox.com>
---
Documentation/git-branch.txt | 7 +++++++
Documentation/git-checkout.txt | 4 ++++
branch.c | 7 +++++--
branch.h | 2 +-
builtin-branch.c | 18 +++++++++++++++++-
builtin-checkout.c | 19 +++++++++++++++++--
cache.h | 1 +
t/t3200-branch.sh | 8 ++++++++
t/t7201-co.sh | 10 ++++++++++
9 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 0e83680..ca7b120 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -129,6 +129,13 @@ start-point is either a local or remote branch.
Do not set up "upstream" configuration, even if the
branch.autosetupmerge configuration variable is true.
+--will-track <remote ref>::
+ Instead of tracking the starting point, a user might wish to set
+ up tracking info for a future location of the branch once it's
+ been pushed to a remote. Specifying this allows you to
+ configure the branch in such a way before the branch actually
+ exists on the remote.
+
--contains <commit>::
Only list branches which contain the specified commit.
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 37c1810..c18852a 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -86,6 +86,10 @@ explicitly give a name with '-b' in such a case.
Do not set up "upstream" configuration, even if the
branch.autosetupmerge configuration variable is true.
+--will-track <remote ref>::
+ Configure "upstream" as a yet-nonexistent remote branch. See
+ "--will-track" in linkgit:git-branch[1] for details.
+
-l::
Create the new branch's reflog; see linkgit:git-branch[1] for
details.
diff --git a/branch.c b/branch.c
index 05ef3f5..c3f6bbe 100644
--- a/branch.c
+++ b/branch.c
@@ -126,7 +126,8 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
void create_branch(const char *head,
const char *name, const char *start_name,
- int force, int reflog, enum branch_track track)
+ int force, int reflog, enum branch_track track,
+ const char *will_track)
{
struct ref_lock *lock;
struct commit *commit;
@@ -184,7 +185,9 @@ void create_branch(const char *head,
snprintf(msg, sizeof msg, "branch: Created from %s",
start_name);
- if (real_ref && track)
+ if (will_track)
+ setup_tracking(name, will_track, track);
+ else if (real_ref && track)
setup_tracking(name, real_ref, track);
if (write_ref_sha1(lock, sha1, msg) < 0)
diff --git a/branch.h b/branch.h
index eed817a..30fd5c7 100644
--- a/branch.h
+++ b/branch.h
@@ -13,7 +13,7 @@
* branch for (if any).
*/
void create_branch(const char *head, const char *name, const char *start_name,
- int force, int reflog, enum branch_track track);
+ int force, int reflog, enum branch_track track, const char *will_track);
/*
* Remove information about the state of working on the current
diff --git a/builtin-branch.c b/builtin-branch.c
index 05e876e..b29e6cf 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -556,12 +556,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
enum branch_track track;
int kinds = REF_LOCAL_BRANCH;
struct commit_list *with_commit = NULL;
+ char *will_track = NULL;
struct option options[] = {
OPT_GROUP("Generic options"),
OPT__VERBOSE(&verbose),
OPT_SET_INT('t', "track", &track, "set up tracking mode (see git-pull(1))",
BRANCH_TRACK_EXPLICIT),
+ OPT_STRING(0, "will-track", &will_track, "future remote branch",
+ "set up branch to track future remote branch"),
OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"),
OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
REF_REMOTE_BRANCH),
@@ -628,6 +631,16 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
if (!!delete + !!rename + !!force_create > 1)
usage_with_options(builtin_branch_usage, options);
+ if (will_track) {
+ will_track = xstrdup(will_track);
+ if (strncmp(will_track, "refs/remotes/", 13)) {
+ will_track = xrealloc(will_track, sizeof(char) * (strlen(will_track) + 14));
+ memmove(will_track + 13, will_track, strlen(will_track) + 1);
+ memcpy(will_track, "refs/remotes/", 13);
+ }
+ track = BRANCH_TRACK_FUTURE;
+ }
+
if (delete)
return delete_branches(argc, argv, delete > 1, kinds);
else if (argc == 0)
@@ -638,9 +651,12 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
rename_branch(argv[0], argv[1], rename > 1);
else if (argc <= 2)
create_branch(head, argv[0], (argc == 2) ? argv[1] : head,
- force_create, reflog, track);
+ force_create, reflog, track, will_track);
else
usage_with_options(builtin_branch_usage, options);
+ if (will_track)
+ free(will_track);
+
return 0;
}
diff --git a/builtin-checkout.c b/builtin-checkout.c
index 64f3a11..f69be79 100644
--- a/builtin-checkout.c
+++ b/builtin-checkout.c
@@ -34,6 +34,7 @@ struct checkout_opts {
const char *new_branch;
int new_branch_log;
enum branch_track track;
+ char *will_track;
};
static int post_checkout_hook(struct commit *old, struct commit *new,
@@ -484,7 +485,7 @@ static void update_refs_for_switch(struct checkout_opts *opts,
const char *old_desc;
if (opts->new_branch) {
create_branch(old->name, opts->new_branch, new->name, 0,
- opts->new_branch_log, opts->track);
+ opts->new_branch_log, opts->track, opts->will_track);
new->name = opts->new_branch;
setup_branch_path(new);
}
@@ -621,6 +622,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
struct option options[] = {
OPT__QUIET(&opts.quiet),
OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
+ OPT_STRING(0, "will-track", &opts.will_track, "future remote branch", "nonexistent branch on remote that will be tracked"),
OPT_BOOLEAN('l', NULL, &opts.new_branch_log, "log for new branch"),
OPT_SET_INT('t', "track", &opts.track, "track",
BRANCH_TRACK_EXPLICIT),
@@ -650,7 +652,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, checkout_usage,
PARSE_OPT_KEEP_DASHDASH);
- if (patch_mode && (opts.track > 0 || opts.new_branch
+ if (patch_mode && (opts.track > 0 || opts.new_branch || opts.will_track
|| opts.new_branch_log || opts.merge || opts.force))
die ("--patch is incompatible with all other options");
@@ -810,6 +812,19 @@ no_reference:
if (!get_sha1(buf.buf, rev))
die("git checkout: branch %s already exists", opts.new_branch);
strbuf_release(&buf);
+
+ if (opts.will_track) {
+ opts.will_track = xstrdup(opts.will_track);
+ if (strncmp(opts.will_track, "refs/remotes/", 13)) {
+ opts.will_track = xrealloc(opts.will_track,
+ sizeof(char) * (strlen(opts.will_track) + 14));
+ memmove(opts.will_track + 13, opts.will_track,
+ strlen(opts.will_track) + 1);
+ memcpy(opts.will_track, "refs/remotes/", 13);
+ }
+
+ opts.track = BRANCH_TRACK_FUTURE;
+ }
}
if (new.name && !new.commit) {
diff --git a/cache.h b/cache.h
index bf468e5..1dd7762 100644
--- a/cache.h
+++ b/cache.h
@@ -544,6 +544,7 @@ enum branch_track {
BRANCH_TRACK_REMOTE,
BRANCH_TRACK_ALWAYS,
BRANCH_TRACK_EXPLICIT,
+ BRANCH_TRACK_FUTURE,
};
enum rebase_setup_type {
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index d59a9b4..67e769a 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -137,6 +137,14 @@ test_expect_success 'test tracking setup via --track' \
test $(git config branch.my1.remote) = local &&
test $(git config branch.my1.merge) = refs/heads/master'
+test_expect_success 'test tracking setup via --will-track' \
+ 'git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch --will-track local/my11 my11 local/master &&
+ test $(git config branch.my11.remote) = local &&
+ test $(git config branch.my11.merge) = refs/heads/my11'
+
test_expect_success 'test tracking setup (non-wildcard, matching)' \
'git config remote.local.url . &&
git config remote.local.fetch refs/heads/master:refs/remotes/local/master &&
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index ebfd34d..803bcad 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -330,6 +330,16 @@ test_expect_success \
test "$(git config branch.track2.merge)"
git config branch.autosetupmerge false'
+test_expect_success \
+ 'checkout w/--will-track sets up tracking' '
+ git config branch.autosetupmerge false &&
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ git checkout master &&
+ git checkout --will-track local/track3 -b track3 &&
+ test "$(git config branch.track3.remote)" &&
+ test "$(git config branch.track3.merge)"'
+
test_expect_success 'checkout w/--track from non-branch HEAD fails' '
git checkout master^0 &&
test_must_fail git symbolic-ref HEAD &&
--
1.6.6.rc2.8.g5599df
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [RFC/PATCH] branch: new option --will-track
2009-12-16 9:39 [RFC/PATCH] branch: new option --will-track Dave Olszewski
@ 2009-12-18 0:07 ` Junio C Hamano
2009-12-18 6:18 ` Andreas Krey
2010-01-05 22:38 ` Nanako Shiraishi
0 siblings, 2 replies; 5+ messages in thread
From: Junio C Hamano @ 2009-12-18 0:07 UTC (permalink / raw)
To: Dave Olszewski; +Cc: git
Dave Olszewski <cxreg@pobox.com> writes:
> A common question from users creating branches in an environment where
> they intend to push the branch to a shared bare repository, and then
> later pull commits from upstream into the branch that they initially
> created, is how do they create the branch with this tracking info
> already set up.
We try reasonably hard not to force users to make a decision before it
gets absolutely necessary [*1*]. This option seems to only help users who
can decide upfront upon "git branch" time if the branch is worth sharing
with others and if the name of the branch will be the final one, and
people who forget to give this new option when they ran "git branch", or
those who changed their mind as to what the newly created branch with this
option should interact with, will still need to use "git config" to update
the settings.
Not very nice, not because it solves only a part of the problem, but
because it force users to decide early and not change their mind.
Instead perhaps we would want to add an option to retarget an existing
branch any time the user wants, e.g. "git branch --reconfigure"? Once we
have such an option, people who *can* decide upfront can use that feature
when creating a new branch at the same time.
Also "git pull --remember $there $this" might be a good way to tell the
configuration mechanism from the UI to remember that "I always want to
merge $this branch from $there while on the branch I am currently on", and
its implementation may probably use "git branch --reconfigure" internally.
Having said all that, I am not very interested in topics on the mechanism
that updates or uses these variables, as I tend to avoid relying on them
myself, and instead teach people to spell them out (which seems to foster
better understanding of what goes on, with reduced user confusion).
Hence, I wouldn't claim I have thought things through in this area, and
the above is just me thinking aloud [*2*].
[Footnote]
*1* There are ample examples, ranging from detached HEAD (you do not have
to decide if the experiment you are going to do deserves a separate branch
to store the result permanently) to the separation between commit and push
(what you commit does not have to be perfect and you have a chance to tidy
them up before publishing).
*2* IOW don't take my "I am not interested" as "patches in this area have
little chance of getting applied."
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC/PATCH] branch: new option --will-track
2009-12-18 0:07 ` Junio C Hamano
@ 2009-12-18 6:18 ` Andreas Krey
2009-12-18 7:16 ` Junio C Hamano
2010-01-05 22:38 ` Nanako Shiraishi
1 sibling, 1 reply; 5+ messages in thread
From: Andreas Krey @ 2009-12-18 6:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Dave Olszewski, git
On Thu, 17 Dec 2009 16:07:08 +0000, Junio C Hamano wrote:
...
> Also "git pull --remember $there $this" might be a good way to tell the
> configuration mechanism from the UI to remember that "I always want to
> merge $this branch from $there while on the branch I am currently on", and
> its implementation may probably use "git branch --reconfigure" internally.
Actually my favorite would be 'git push --track $there', pushing
the current local branch to $there and setting up tracking. That
way the tracking decision need not be made before the remote
branch actually exists.
Andreas
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC/PATCH] branch: new option --will-track
2009-12-18 6:18 ` Andreas Krey
@ 2009-12-18 7:16 ` Junio C Hamano
0 siblings, 0 replies; 5+ messages in thread
From: Junio C Hamano @ 2009-12-18 7:16 UTC (permalink / raw)
To: Andreas Krey; +Cc: Dave Olszewski, git
Andreas Krey <a.krey@gmx.de> writes:
> On Thu, 17 Dec 2009 16:07:08 +0000, Junio C Hamano wrote:
> ...
>> Also "git pull --remember $there $this" might be a good way to tell the
>> configuration mechanism from the UI to remember that "I always want to
>> merge $this branch from $there while on the branch I am currently on", and
>> its implementation may probably use "git branch --reconfigure" internally.
>
> Actually my favorite would be 'git push --track $there', pushing
> the current local branch to $there and setting up tracking. That
> way the tracking decision need not be made before the remote
> branch actually exists.
Yeah, it may be useful, but that belongs to the same "in addition to the
most flexible form, we might want to _also_ do so" category, as the one
that makes "git pull" remember.
The advantage of remembering upon the first pull is that the request to
remember doesn't involve any "push is reverse of pull" indirection.
Instead, it is exactly what the user actually has done once: "I'm doing
this once, remember it for me". Compared to it, I think it is less
obvious to make the first push remember its reverse [*1*].
Another issue that you need to think about is how you will allow users to
set up "integrate with merge or rebase" when making "push" remember.
An option with "pull" would make it much more obvious what is going on, as
the user would say "git pull --rebase --remember $there $this" if rebasing
is desired, and that is what is going to be remembered; again that is
thanks to the "I'm doing this once, remember it for me" semantics.
[Footnote]
*1* I am not saying "if you have 'pull --remember' you don't need 'push
--remember'" or vice versa. As long as each (judged individually) makes
sense we could have both.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [RFC/PATCH] branch: new option --will-track
2009-12-18 0:07 ` Junio C Hamano
2009-12-18 6:18 ` Andreas Krey
@ 2010-01-05 22:38 ` Nanako Shiraishi
1 sibling, 0 replies; 5+ messages in thread
From: Nanako Shiraishi @ 2010-01-05 22:38 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Dave Olszewski
Junio, could you tell us what happened to this thread?
After "--will-track" was discussed and agreed not to be the best
solution, and "pull --remember" and "branch --configure" were
suggested, nothing happened.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-01-05 22:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-16 9:39 [RFC/PATCH] branch: new option --will-track Dave Olszewski
2009-12-18 0:07 ` Junio C Hamano
2009-12-18 6:18 ` Andreas Krey
2009-12-18 7:16 ` Junio C Hamano
2010-01-05 22:38 ` Nanako Shiraishi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).