Hi all, is there a way to verify, using the UI, whether a local branch is tracking a remote branch?
Ciao,
-- Paolo http://paolo.ciarrocchi.googlepages.com/ http://mypage.vodafone.it/
threads / discuss / 18733
Subject: [question] how can i verify whether a local branch is tracking a remote branch?
Hi all, is there a way to verify, using the UI, whether a local branch is tracking a remote branch?
Ciao,
-- Paolo http://paolo.ciarrocchi.googlepages.com/ http://mypage.vodafone.it/
Re: [question] how can i verify whether a local branch is tracking a remote branch?
On Sun, Apr 05, 2009 at 12:32:29PM +0200, Paolo Ciarrocchi wrote:
> is there a way to verify, using the UI, whether a local branch is > tracking a remote branch?
Do you mean "whether it is tracking any branch", or "whether the branch is is tracking is remote"?
If the former, then I think if one of branch.$branch.{merge,rebase} is set, it is tracking something. The tracked thing is remote unless branch.$branch.remote is ".".
-Peff
Re: [question] how can i verify whether a local branch is tracking a remote branch?
On 4/5/09, Jeff King <peff@peff.net> wrote:
> On Sun, Apr 05, 2009 at 12:32:29PM +0200, Paolo Ciarrocchi wrote: > >> is there a way to verify, using the UI, whether a local branch is >> tracking a remote branch? > > Do you mean "whether it is tracking any branch", or "whether the branch > is is tracking is remote"?
I mean whether it is tracking a branch and if it is I want to know which branch is being tracked.
> If the former, then I think if one of branch.$branch.{merge,rebase}
> is set, it is tracking something. The tracked thing is remote unless
> branch.$branch.remote is ".".An example: $ git clone -n URL temp $ cd temp $ git branch -r origin/master origin/foo Origin/bar $ git checkout --track -b foo origin/foo
Now, how can I know that foo is tracking origin/foo ?
Thanks.
Ciao,
-- Paolo http://paolo.ciarrocchi.googlepages.com/ http://mypage.vodafone.it/
Re: [question] how can i verify whether a local branch is tracking a remote branch?
On Sun, Apr 05, 2009 at 11:25:29PM +0200, Paolo Ciarrocchi wrote:
> An example: > $ git clone -n URL temp > $ cd temp > $ git branch -r > origin/master > origin/foo > Origin/bar > $ git checkout --track -b foo origin/foo > > Now, how can I know that foo is tracking origin/foo ?
Doing it right is hard. You have to:
1. check branch.foo.merge and branch.foo.rebase; if no value, it is not
tracking anything; if it is, remember that value as $m2. check branch.foo.remote for the remote name, $r
3. check the fetch refspecs for remote $r; these can come from
the config, or from .git/remotes/* files. Maybe even .git/branches
files; I don't even remember how those work. 4. find the refspec that fetches from $m; then find the matching
destination for that refspec. That is the tracking branch.E.g., in your example (and using a modern git):
1. $m is refs/heads/foo
2. $r is origin
3. The fetch refspec is in remote.origin.fetch, and is generally
"refs/heads/*:refs/remotes/origin/*"
4. So refs/heads/foo becomes refs/remotes/origin/foo.
refs/remotes/origin/foo is your tracking branch.Steps 1 and 2 are easy, but 3 and 4 are a bit nasty. You can fake it by assuming that "refs/heads/$m" on "$r" is always "refs/remotes/$r/$m", which is true for very vanilla setups.
There is C code that does this, but there is not a good way of accessing it from the command-line. The best you can do is "git remote show origin", which on recent git versions should show something like:
...
Local branches configured for 'git pull':
foo merges with remote foo
...But of course that implies that you already guessed the remote "origin". And it's not using plumbing, so it's not very suitable for scripts.
I don't think it would be unreasonable to expose this functionality via "for-each-ref". Something like this (which would need cleanup, documentation, and perhaps a :short variant):
---
diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index 5cbb4b0..3f418e4 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -8,6 +8,7 @@ #include "blob.h" #include "quote.h" #include "parse-options.h" +#include "remote.h" /* Quoting styles */ #define QUOTE_NONE 0 @@ -66,6 +67,7 @@ static struct { { "subject" }, { "body" }, { "contents" }, + { "tracking" }, }; /* @@ -699,6 +701,18 @@ static void populate_value(struct refinfo *ref) v->s = s; } } + if (!strcmp(name, "tracking")) { + struct branch *branch; + if (prefixcmp(ref->refname, "refs/heads/")) + continue; + branch = branch_get(ref->refname + 11); + if (branch && branch->merge && branch->merge[0] && + branch->merge[0]->dst) + v->s = branch->merge[0]->dst; + else + v->s = NULL; + free(branch); /* XXX should also free other parts? */ + } } grab_values(ref->value, 0, obj, buf, size); > > Thanks. > > > Ciao, > -- > Paolo > http://paolo.ciarrocchi.googlepages.com/ > http://mypage.vodafone.it/
Re: [question] how can i verify whether a local branch is tracking a remote branch?
Jeff King <peff@peff.net> writes:
> I don't think it would be unreasonable to expose this functionality via > "for-each-ref". Something like this (which would need cleanup, > documentation, and perhaps a :short variant):
I think that is a sane approach, but isn't "tracking" a misnomer? I think what you are describing is what is called "the upstream branch" by the description of Documentation/config.txt::branch.<name>.merge, and not what people call "tracking branch" (see Documentation/glossary-content.txt).
In a repository with a handcrafted fetch refspec, being able to show "tracking" information would also be interesting (e.g. a clone of git.git made with pre-1.5.0 git would say "origin's master" for refs/heads/origin and "origin's next" for refs/heads/next), but the separate-remote layout is the default these days, so it wouldn't be so interesting anymore. In other words, I am not suggesting you to add "tracking" information.
I also wonder if you want to say "this remote" and "that branch" separately. As far as I can tell you are not giving the former but only the latter information?
Re: [question] how can i verify whether a local branch is tracking a remote branch?
On Sun, Apr 05, 2009 at 10:28:02PM -0700, Junio C Hamano wrote:
> > I don't think it would be unreasonable to expose this functionality via > > "for-each-ref". Something like this (which would need cleanup, > > documentation, and perhaps a :short variant): > > I think that is a sane approach, but isn't "tracking" a misnomer? I think > what you are describing is what is called "the upstream branch" by the > description of Documentation/config.txt::branch.<name>.merge, and not what > people call "tracking branch" (see Documentation/glossary-content.txt).
I think this is the classic "both of these concepts are called tracking and it is confusing" that people complain about from time to time. This is the value created by "--track", and most of the internal functions call it that (e.g., stat_tracking_info, fill_tracking_info, etc).
But I am happy to call it something else if it will reduce confusion. "upstream" is a fine name, I think (though that is often referring to the upstream _repository_, so maybe somebody might expect it to print "origin" here).
> I also wonder if you want to say "this remote" and "that branch" > separately. As far as I can tell you are not giving the former but only > the latter information?
Well, I don't think they are two separate parts. "that branch" has already used information about the remote to reach its answer, and is self-contained. It's all you need to know to do any non-fetching operations (like seeing how your commits compare with upstream's, for example).
Which isn't to say "this remote" might not be interesting. But I think that is somewhat independent of this value, and moreover, it is already trivial to find via "branch.*.remote" (or are there lookup rules I am forgetting about?). The point of this exercise was that it is very tricky to do the "upstream" correctly, so exposing the C code makes sense.
-Peff
Re: [question] how can i verify whether a local branch is tracking a remote branch?
On Mon, Apr 6, 2009 at 6:34 AM, Jeff King <peff@peff.net> wrote:
> On Sun, Apr 05, 2009 at 11:25:29PM +0200, Paolo Ciarrocchi wrote: > >> An example: >> $ git clone -n URL temp >> $ cd temp >> $ git branch -r >> origin/master >> origin/foo >> Origin/bar >> $ git checkout --track -b foo origin/foo >> >> Now, how can I know that foo is tracking origin/foo ? > > Doing it right is hard. You have to: > > 1. check branch.foo.merge and branch.foo.rebase; if no value, it is not > tracking anything; if it is, remember that value as $m > > 2. check branch.foo.remote for the remote name, $r > > 3. check the fetch refspecs for remote $r; these can come from > the config, or from .git/remotes/* files. Maybe even .git/branches > files; I don't even remember how those work. > > 4. find the refspec that fetches from $m; then find the matching > destination for that refspec. That is the tracking branch. > > E.g., in your example (and using a modern git): > > 1. $m is refs/heads/foo > 2. $r is origin > 3. The fetch refspec is in remote.origin.fetch, and is generally > "refs/heads/*:refs/remotes/origin/*" > 4. So refs/heads/foo becomes refs/remotes/origin/foo. > refs/remotes/origin/foo is your tracking branch. > > Steps 1 and 2 are easy, but 3 and 4 are a bit nasty. You can fake it by > assuming that "refs/heads/$m" on "$r" is always "refs/remotes/$r/$m", > which is true for very vanilla setups. > > There is C code that does this, but there is not a good way of accessing > it from the command-line. The best you can do is "git remote show > origin", which on recent git versions should show something like: > > ... > Local branches configured for 'git pull': > foo merges with remote foo > ... > > But of course that implies that you already guessed the remote "origin". > And it's not using plumbing, so it's not very suitable for scripts. > > I don't think it would be unreasonable to expose this functionality via > "for-each-ref". Something like this (which would need cleanup, > documentation, and perhaps a :short variant):
Jeff, thank you very much for your prompt answers and for your patch.
I often act like a GIT "evangelist" trying to help friends and colleagues in starting using GIT and one of the "complaint" I'm getting is that people expect to get this information out of the branch command.
I mean something like: $ git branch * foo <-> origin/foo
What do you think?
Ciao,
-- Paolo http://paolo.ciarrocchi.googlepages.com/ http://mypage.vodafone.it/
Re: [question] how can i verify whether a local branch is tracking a remote branch?
On Mon, Apr 06, 2009 at 10:30:21AM +0200, Paolo Ciarrocchi wrote:
> I often act like a GIT "evangelist" trying to help friends and > colleagues in starting using GIT and one of the "complaint" I'm > getting is that people expect to get this information out of the > branch command. > > I mean something like: > $ git branch > * foo <-> origin/foo > > What do you think?
Ah. Well, if you just want it for human consumption, that is much easier. :) That information is already shown by "git status":
$ git status # On branch next # Your branch is ahead of 'origin/next' by 8 commits. ...
"git branch -v" is already looking at the information, but it prints only the "ahead/behind" summary. E.g.,:
$ git branch -v
bar 1e0672d [behind 5] some commit
* baz dccc1cd [ahead 1, behind 3] other commit
foo 787d5a8 [ahead 1] another commit
master a0e632e actual upstream masterIt would be pretty trivial to make it do something fancier. The (extremely rough) patch below shows the tracking branch when double-verbosity is given:
$ git branch -vv * next 2d44318 [origin/next: ahead 9] branch -vv wip
So the questions are:
- is this worth it? The verbose information is already available via
git status, but only for the current branch. - should it be the default with "-v", or require "-vv"? It take up a
bit of screen real estate, which is already in short supply for
"branch -v" - in both the "status" and "branch" cases, we show nothing if they
are equivalent. I guess you would want to see* next 2d44318 [origin/next] branch -vv wip
or
* next 2d44318 [origin/next: uptodate] branch -vv wip
-Peff
Re: [question] how can i verify whether a local branch is tracking a remote branch?
On 4/6/09, Jeff King <peff@peff.net> wrote:
> On Mon, Apr 06, 2009 at 10:30:21AM +0200, Paolo Ciarrocchi wrote:
>> I mean something like: >> $ git branch >> * foo <-> origin/foo >> >> What do you think? > > Ah. Well, if you just want it for human consumption, that is much > easier. :) That information is already shown by "git status": > > $ git status > # On branch next > # Your branch is ahead of 'origin/next' by 8 commits. > ...
right, but it can only ne used for the current branch.
> "git branch -v" is already looking at the information, but it > prints only the "ahead/behind" summary. E.g.,: > > $ git branch -v > bar 1e0672d [behind 5] some commit > * baz dccc1cd [ahead 1, behind 3] other commit > foo 787d5a8 [ahead 1] another commit > master a0e632e actual upstream master > > It would be pretty trivial to make it do something fancier. The > (extremely rough) patch below shows the tracking branch when > double-verbosity is given: > > $ git branch -vv > * next 2d44318 [origin/next: ahead 9] branch -vv wip
I like it!
> So the questions are: > > - is this worth it? The verbose information is already available via > git status, but only for the current branch.
I think it's a very usefull information. I feel like it would be nice to have this information being part of the basic git branch output and not associated to the -vv option.
> - should it be the default with "-v", or require "-vv"? It take up a > bit of screen real estate, which is already in short supply for > "branch -v"
How about be just part of the default git branch output?
> - in both the "status" and "branch" cases, we show nothing if they > are equivalent. I guess you would want to see > > * next 2d44318 [origin/next] branch -vv wip > > or > > * next 2d44318 [origin/next: uptodate] branch -vv wip
Sure.
Thanks!
Ciao,
-- Paolo http://paolo.ciarrocchi.googlepages.com/ http://mypage.vodafone.it/
Re: [question] how can i verify whether a local branch is tracking a remote branch?
On Tue, Apr 07, 2009 at 12:00:20AM +0200, Paolo Ciarrocchi wrote:
> > So the questions are: > > > > - is this worth it? The verbose information is already available via > > git status, but only for the current branch. > > I think it's a very usefull information. > I feel like it would be nice to have this information being part of > the basic git branch output and not associated to the -vv option.
I'm not sure we should disrupt the simplicity of the current "git branch" output. I would be curious to hear what others think.
-Peff
Re: [question] how can i verify whether a local branch is tracking a remote branch?
Jeff King venit, vidit, dixit 06.04.2009 06:34:
> On Sun, Apr 05, 2009 at 11:25:29PM +0200, Paolo Ciarrocchi wrote:
>
>> An example:
>> $ git clone -n URL temp
>> $ cd temp
>> $ git branch -r
>> origin/master
>> origin/foo
>> Origin/bar
>> $ git checkout --track -b foo origin/foo
>>
>> Now, how can I know that foo is tracking origin/foo ?
>
> Doing it right is hard. You have to:
>
> 1. check branch.foo.merge and branch.foo.rebase; if no value, it is not
> tracking anything; if it is, remember that value as $m
>
> 2. check branch.foo.remote for the remote name, $r
>
> 3. check the fetch refspecs for remote $r; these can come from
> the config, or from .git/remotes/* files. Maybe even .git/branches
> files; I don't even remember how those work.
>
> 4. find the refspec that fetches from $m; then find the matching
> destination for that refspec. That is the tracking branch.
>
> E.g., in your example (and using a modern git):
>
> 1. $m is refs/heads/foo
> 2. $r is origin
> 3. The fetch refspec is in remote.origin.fetch, and is generally
> "refs/heads/*:refs/remotes/origin/*"
> 4. So refs/heads/foo becomes refs/remotes/origin/foo.
> refs/remotes/origin/foo is your tracking branch.
>
> Steps 1 and 2 are easy, but 3 and 4 are a bit nasty. You can fake it by
> assuming that "refs/heads/$m" on "$r" is always "refs/remotes/$r/$m",
> which is true for very vanilla setups.
>
> There is C code that does this, but there is not a good way of accessing
> it from the command-line. The best you can do is "git remote show
> origin", which on recent git versions should show something like:
>
> ...
> Local branches configured for 'git pull':
> foo merges with remote foo
> ...
>
> But of course that implies that you already guessed the remote "origin".
> And it's not using plumbing, so it's not very suitable for scripts.
>
> I don't think it would be unreasonable to expose this functionality via
> "for-each-ref". Something like this (which would need cleanup,
> documentation, and perhaps a :short variant):
>
> ---
> diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
> index 5cbb4b0..3f418e4 100644
> --- a/builtin-for-each-ref.c
> +++ b/builtin-for-each-ref.c
> @@ -8,6 +8,7 @@
> #include "blob.h"
> #include "quote.h"
> #include "parse-options.h"
> +#include "remote.h"
>
> /* Quoting styles */
> #define QUOTE_NONE 0
> @@ -66,6 +67,7 @@ static struct {
> { "subject" },
> { "body" },
> { "contents" },
> + { "tracking" },
> };
>
> /*
> @@ -699,6 +701,18 @@ static void populate_value(struct refinfo *ref)
> v->s = s;
> }
> }
> + if (!strcmp(name, "tracking")) {
> + struct branch *branch;
> + if (prefixcmp(ref->refname, "refs/heads/"))
> + continue;
> + branch = branch_get(ref->refname + 11);
> + if (branch && branch->merge && branch->merge[0] &&
> + branch->merge[0]->dst)
> + v->s = branch->merge[0]->dst;Isn't that missing out on those cases where you --track (i.e. follow) a local (upstream) branch? See 5e6e2b4 (Make local branches behave like remote branches when --tracked, 2009-04-01)
> + else > + v->s = NULL; > + free(branch); /* XXX should also free other parts? */ > + } > } > > grab_values(ref->value, 0, obj, buf, size); > > > > >
If we hook it up into git-branch there would be to useful directions:
- "git branch --follows foo" could list all branches which follow foo, analogous to --contains. It gives you all your feature work on top of foo, all branches affected by rebasing foo etc.
- "git branch --whatever foo" could list the branch whoch foo follows.
I just notices that "git branch -v foo" does not give me the "-v" output for foo... Improving that would open up the possibility to go for -vv foo.
Michael
Re: [question] how can i verify whether a local branch is tracking a remote branch?
On Mon, Apr 06, 2009 at 02:00:34PM +0200, Michael J Gruber wrote:
> > + if (!strcmp(name, "tracking")) {
> > + struct branch *branch;
> > + if (prefixcmp(ref->refname, "refs/heads/"))
> > + continue;
> > + branch = branch_get(ref->refname + 11);
> > + if (branch && branch->merge && branch->merge[0] &&
> > + branch->merge[0]->dst)
> > + v->s = branch->merge[0]->dst;
>
> Isn't that missing out on those cases where you --track (i.e. follow) a
> local (upstream) branch? See
> 5e6e2b4 (Make local branches behave like remote branches when --tracked,
> 2009-04-01)I thought the logic was in branch_get to handle it. And indeed:
$ git checkout --track -b new master Branch new set up to track local branch master. Switched to a new branch "new" $ git for-each-ref --format='%(refname) %(tracking)' refs/heads/master refs/heads/new refs/heads/master
So it will point either to something in refs/remotes or in refs/heads, as applicable.
> If we hook it up into git-branch there would be to useful directions:
The difference being that git-branch is porcelain and git-for-each-ref is plumbing. So they really serve different purposes.
> - "git branch --follows foo" could list all branches which follow foo, > analogous to --contains. It gives you all your feature work on top of > foo, all branches affected by rebasing foo etc.
Sure, that would probably be useful.
> - "git branch --whatever foo" could list the branch whoch foo follows. > > I just notices that "git branch -v foo" does not give me the "-v" output > for foo... Improving that would open up the possibility to go for -vv foo.
See the "-vv" patch I just posted elsewhere in the thread.
-Peff
Re: [question] how can i verify whether a local branch is tracking a remote branch?
Jeff King venit, vidit, dixit 06.04.2009 23:29:
> On Mon, Apr 06, 2009 at 02:00:34PM +0200, Michael J Gruber wrote:
>
>>> + if (!strcmp(name, "tracking")) {
>>> + struct branch *branch;
>>> + if (prefixcmp(ref->refname, "refs/heads/"))
>>> + continue;
>>> + branch = branch_get(ref->refname + 11);
>>> + if (branch && branch->merge && branch->merge[0] &&
>>> + branch->merge[0]->dst)
>>> + v->s = branch->merge[0]->dst;
>>
>> Isn't that missing out on those cases where you --track (i.e. follow) a
>> local (upstream) branch? See
>> 5e6e2b4 (Make local branches behave like remote branches when --tracked,
>> 2009-04-01)
>
> I thought the logic was in branch_get to handle it. And indeed:
>
> $ git checkout --track -b new master
> Branch new set up to track local branch master.
> Switched to a new branch "new"
> $ git for-each-ref --format='%(refname) %(tracking)'
> refs/heads/master
> refs/heads/new refs/heads/master
>
> So it will point either to something in refs/remotes or in refs/heads,
> as applicable.Uhm, yes, sorry for the noise. It was actually me who fixed branch_get()...
> >> If we hook it up into git-branch there would be to useful directions: > > The difference being that git-branch is porcelain and git-for-each-ref > is plumbing. So they really serve different purposes. > >> - "git branch --follows foo" could list all branches which follow foo, >> analogous to --contains. It gives you all your feature work on top of >> foo, all branches affected by rebasing foo etc. > > Sure, that would probably be useful. > >> - "git branch --whatever foo" could list the branch whoch foo follows. >> >> I just notices that "git branch -v foo" does not give me the "-v" output >> for foo... Improving that would open up the possibility to go for -vv foo. > > See the "-vv" patch I just posted elsewhere in the thread.
I'll comment there ;)
Michael