git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* (unknown)
@ 2015-08-05 12:47 Ivan Chernyavsky
  2015-08-05 17:03 ` Which branch(es) contain certain commits? (was Re: (unknown)) Junio C Hamano
  2015-08-15  9:19 ` Duy Nguyen
  0 siblings, 2 replies; 12+ messages in thread
From: Ivan Chernyavsky @ 2015-08-05 12:47 UTC (permalink / raw)
  To: git

Dear community,

For some time I'm wondering why there's no "--grep" option to the "git branch" command, which would request to print only branches having specified string/regexp in their history.

So for example:

    $ git branch -r --grep=BUG12345

should be roughly equivalent to following expression I'm using now for the same task:

    $ for r in `git rev-list --grep=BUG12345 --remotes=origin`; do git branch -r --list --contains=$r 'origin/*'; done | sort -u

Am I missing something, is there some smarter/simpler way to do this?

Thanks a lot in advance!

-- 
  Ivan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Which branch(es) contain certain commits? (was Re: (unknown))
  2015-08-05 12:47 (unknown) Ivan Chernyavsky
@ 2015-08-05 17:03 ` Junio C Hamano
  2015-08-05 17:05   ` Junio C Hamano
  2015-08-15  9:19 ` Duy Nguyen
  1 sibling, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2015-08-05 17:03 UTC (permalink / raw)
  To: Ivan Chernyavsky; +Cc: git

Ivan Chernyavsky <camposer@yandex.ru> writes:

> For some time I'm wondering why there's no "--grep" option to the "git
> branch" command, which would request to print only branches having
> specified string/regexp in their history.
>
> So for example:
>
>     $ git branch -r --grep=BUG12345
>
> should be roughly equivalent to following expression I'm using now for the same task:
>
>     $ for r in `git rev-list --grep=BUG12345 --remotes=origin`; do git
> branch -r --list --contains=$r 'origin/*'; done | sort -u
>
> Am I missing something, is there some smarter/simpler way to do this?

I think people do things like:

    git log --all --decorate --grep=...

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Which branch(es) contain certain commits? (was Re: (unknown))
  2015-08-05 17:03 ` Which branch(es) contain certain commits? (was Re: (unknown)) Junio C Hamano
@ 2015-08-05 17:05   ` Junio C Hamano
  2015-08-05 19:48     ` Ivan Chernyavsky
  0 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2015-08-05 17:05 UTC (permalink / raw)
  To: Ivan Chernyavsky; +Cc: git

Junio C Hamano <gitster@pobox.com> writes:

> I think people do things like:
>
>     git log --all --decorate --grep=...

s/decorate/source/; sorry for the noise.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Which branch(es) contain certain commits? (was Re: (unknown))
  2015-08-05 17:05   ` Junio C Hamano
@ 2015-08-05 19:48     ` Ivan Chernyavsky
  0 siblings, 0 replies; 12+ messages in thread
From: Ivan Chernyavsky @ 2015-08-05 19:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git@vger.kernel.org

Sorry for empty subject in the original mail, somehow I've deleted it and didn't even notice.

05.08.2015, 20:05, "Junio C Hamano" <gitster@pobox.com>:
> Junio C Hamano <gitster@pobox.com> writes:
>
>>  I think people do things like:
>>
>>      git log --all --decorate --grep=...
>
> s/decorate/source/; sorry for the noise.

Thanks Junio!

I was actually considering using --source, but for me the problem is it always returns *just one* branch for every matching commit. So the caller must then use his own knowledge to deduce all branches where this branch merged.

Considering following history:

* b46f30e       refs/heads/zzz eee
| * dc0280f     refs/heads/yyy ddd
|/
| * 31739da     refs/heads/xxx ccc
|/
* a42bd23       refs/heads/master bbb
* 01a8291       refs/heads/master aaa

Command "git log --all --source --grep=bbb --oneline" will return:

a42bd23 refs/heads/master bbb

While I'm expecting something like "git branch --contains=a42bd23" output in terms of *all* topics being listed:

  master
  xxx
  yyy
* zzz

The most common use case is when support people need to quickly get at least rough idea which branches have specific ticket/CR mentioned.

-- 
  Ivan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re:
  2015-08-05 12:47 (unknown) Ivan Chernyavsky
  2015-08-05 17:03 ` Which branch(es) contain certain commits? (was Re: (unknown)) Junio C Hamano
@ 2015-08-15  9:19 ` Duy Nguyen
  2015-08-17  6:45   ` Which branch(es) contain certain commits? (was Re: (unknown)) Ivan Chernyavsky
  2015-08-17 17:49   ` Junio C Hamano
  1 sibling, 2 replies; 12+ messages in thread
From: Duy Nguyen @ 2015-08-15  9:19 UTC (permalink / raw)
  To: Ivan Chernyavsky; +Cc: Git Mailing List

On Wed, Aug 5, 2015 at 7:47 PM, Ivan Chernyavsky <camposer@yandex.ru> wrote:
> Dear community,
>
> For some time I'm wondering why there's no "--grep" option to the "git branch" command, which would request to print only branches having specified string/regexp in their history.

Probably because nobody is interested and steps up to do it. The lack
of response to you mail is a sign. Maybe you can try make a patch? I
imagine it would not be so different from current --contains code, but
this time we need to look into commits, not just commit id.

> So for example:
>
>     $ git branch -r --grep=BUG12345
>
> should be roughly equivalent to following expression I'm using now for the same task:
>
>     $ for r in `git rev-list --grep=BUG12345 --remotes=origin`; do git branch -r --list --contains=$r 'origin/*'; done | sort -u
>
> Am I missing something, is there some smarter/simpler way to do this?
>
> Thanks a lot in advance!
>
> --
>   Ivan
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Duy

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Which branch(es) contain certain commits? (was Re: (unknown))
  2015-08-15  9:19 ` Duy Nguyen
@ 2015-08-17  6:45   ` Ivan Chernyavsky
  2015-08-17 17:49   ` Junio C Hamano
  1 sibling, 0 replies; 12+ messages in thread
From: Ivan Chernyavsky @ 2015-08-17  6:45 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Git Mailing List



15.08.2015, 12:19, "Duy Nguyen" <pclouds@gmail.com>:
>
> Probably because nobody is interested and steps up to do it. The lack
> of response to you mail is a sign. Maybe you can try make a patch? I
> imagine it would not be so different from current --contains code, but
> this time we need to look into commits, not just commit id.
>

Yeah thanks much, I'll try. Actually that was my original intention, I just wanted to have some "reasonability check" for my idea.

-- 
  Ivan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re:
  2015-08-15  9:19 ` Duy Nguyen
  2015-08-17  6:45   ` Which branch(es) contain certain commits? (was Re: (unknown)) Ivan Chernyavsky
@ 2015-08-17 17:49   ` Junio C Hamano
  2015-08-21 21:29     ` Which branch(es) contain certain commits? (was Re: (unknown)) Ivan Chernyavsky
  1 sibling, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2015-08-17 17:49 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Ivan Chernyavsky, Git Mailing List

Duy Nguyen <pclouds@gmail.com> writes:

> On Wed, Aug 5, 2015 at 7:47 PM, Ivan Chernyavsky <camposer@yandex.ru> wrote:
>> Dear community,
>>
>> For some time I'm wondering why there's no "--grep" option to the
>> "git branch" command, which would request to print only branches
>> having specified string/regexp in their history.
>
> Probably because nobody is interested and steps up to do it. The lack
> of response to you mail is a sign. Maybe you can try make a patch? I
> imagine it would not be so different from current --contains code, but
> this time we need to look into commits, not just commit id.

That is a dangeous thought.  I'd understand if it were internally
two step process, i.e. (1) the first pass finds commits that hits
the --grep criteria and then (2) the second pass does "--contains"
for all the hits found in the first pass using existing code, but
still, this operation is bound to dig all the way through the root
of the history when asked to find something that does not exist.

>> So for example:
>>
>>     $ git branch -r --grep=BUG12345
>>
>> should be roughly equivalent to following expression I'm using now for the same task:
>>
>>     $ for r in `git rev-list --grep=BUG12345 --remotes=origin`; do git branch -r --list --contains=$r 'origin/*'; done | sort -u

You should at least feed all --contains to a single invocation of
"git branch".  They are designed to be OR'ed together.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Which branch(es) contain certain commits? (was Re: (unknown))
  2015-08-17 17:49   ` Junio C Hamano
@ 2015-08-21 21:29     ` Ivan Chernyavsky
  2015-08-21 22:39       ` Junio C Hamano
  0 siblings, 1 reply; 12+ messages in thread
From: Ivan Chernyavsky @ 2015-08-21 21:29 UTC (permalink / raw)
  To: Junio C Hamano, Duy Nguyen; +Cc: Git Mailing List



17.08.2015, 20:49, "Junio C Hamano" <gitster@pobox.com>:
>  Duy Nguyen <pclouds@gmail.com> writes:
>
>>   On Wed, Aug 5, 2015 at 7:47 PM, Ivan Chernyavsky <camposer@yandex.ru> wrote:
>
>  That is a dangeous thought. I'd understand if it were internally
>  two step process, i.e. (1) the first pass finds commits that hits
>  the --grep criteria and then (2) the second pass does "--contains"
>  for all the hits found in the first pass using existing code, but
>  still, this operation is bound to dig all the way through the root
>  of the history when asked to find something that does not exist.

My intention was to use existing git-branch filters such as -a or -r and pattern to limit the scope, then apply --grep machinery.

But now I had a look on the source and I can see that builtin/branch.c builds the list of references and prints them in a single place (print_ref_list()) so I will have to split that function into two in order to reuse existing functionality.

Another problem is that builtin/branch.c currently does not use setup_revisions(), so I'll have to hook it there as well.

Then, I assume, I'll need to use the initial ref_list (filled the same as for the current "list" case) to configure the rev_info structure after setup_revisions(), and start revision traversal.

I'm not sure I've got it all right from the source in those few days, so I apologize in advance if it's stupid in some part or as a whole.

That said, do you think the goal is worth such changes? Seems like git-branch currently has it's own way of doing things and I'm trying to teach it to use git-rev-list's.

Maybe it is more reasonable to add an option to "git log --all --source --grep=..." to print *all* branch tips which are reachable from the found commits, not only the first one encountered? E.g. --decorate-all or --source-all?

>  You should at least feed all --contains to a single invocation of
>  "git branch". They are designed to be OR'ed together.


Yep thanks I overlooked that. In my repository, this takes 40 seconds instead of 2 minutes 30 seconds for my construct.

-- 
  Ivan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Which branch(es) contain certain commits? (was Re: (unknown))
  2015-08-21 21:29     ` Which branch(es) contain certain commits? (was Re: (unknown)) Ivan Chernyavsky
@ 2015-08-21 22:39       ` Junio C Hamano
  2015-08-22  9:19         ` Ivan Chernyavsky
  0 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2015-08-21 22:39 UTC (permalink / raw)
  To: Ivan Chernyavsky; +Cc: Duy Nguyen, Git Mailing List

Ivan Chernyavsky <camposer@yandex.ru> writes:

> But now I had a look on the source and I can see that builtin/branch.c
> builds the list of references and prints them in a single place
> (print_ref_list()) so I will have to split that function into two in
> order to reuse existing functionality.
>
> Another problem is that builtin/branch.c currently does not use
> setup_revisions(), so I'll have to hook it there as well.
>
> Then, I assume, I'll need to use the initial ref_list (filled the same
> as for the current "list" case) to configure the rev_info structure
> after setup_revisions(), and start revision traversal.
>
> I'm not sure I've got it all right from the source in those few days,
> so I apologize in advance if it's stupid in some part or as a whole.

Heh, you say "problem" above, but I do not think it is a "problem"
per-se.  If you want to teach branch some preprocessing based on the
revision traversal API, you naturally need to call setup_revisions().

The outlined steps above all feel sensible; one thing you did not
mention is that you may probably have to clear object flags after
you are done with the initial "--grep" revision traversal, as some
features of branch may want to use the object flags (e.g. --merged
would use in_merge_bases()).  Other than that, all of it sounds
easily implementable.

Note that "branch --list", "tag --list" and "for-each-ref" are being
revamped to share more internal code.  If you want to pursue this,
you probably would want to build on top of that effort once it is
done.  That way, you may get "tag --grep=FIX123" for free.

> That said, do you think the goal is worth such changes?

That is a dangerous question.  As Duy already said,

> Probably because nobody is interested and steps up to do it. The lack
> of response to you mail is a sign.

apparently not many people thought it is worth; otherwise we would
already have such a feature.

If you are asking me personally, I'm sorry but I have to say no.

The reason why I personally do not think your "branch --grep=FIX123"
would be very useful to me is because I would imagine that I would
be interested in learning the exact commit that mentions FIX123 as
well as which branches contain it, if I had a need for such a
feature.

That is, it would inherently be two step process for me anyway, i.e.

 (1) I'd run "log -p --grep" to find which commits are about FIX123
     and check that what they did indeed make sense; and

 (2) I'd then run "branch --contains" to learn which ones are
     already up to date with respect to the fix.

Your "branch --grep=FIX123" that only tells me the names of branches
would have no use in that workflow, as it would not even give me an
indication that the request --grep=FIX123 found the right commit in
the first place.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Which branch(es) contain certain commits? (was Re: (unknown))
  2015-08-21 22:39       ` Junio C Hamano
@ 2015-08-22  9:19         ` Ivan Chernyavsky
  2015-08-22 10:32           ` Ivan Chernyavsky
  2015-08-22 10:59           ` Karthik Nayak
  0 siblings, 2 replies; 12+ messages in thread
From: Ivan Chernyavsky @ 2015-08-22  9:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List



22.08.2015, 01:39, "Junio C Hamano" <gitster@pobox.com>:
>  Ivan Chernyavsky <camposer@yandex.ru> writes:
>
>>   Another problem is that builtin/branch.c currently does not use
>>   setup_revisions(), so I'll have to hook it there as well.
>
>  Heh, you say "problem" above, but I do not think it is a "problem"
>  per-se. If you want to teach branch some preprocessing based on the
>  revision traversal API, you naturally need to call setup_revisions().

I meant "my problem" mostly ;) Yes I see git-branch currently has it's own way of doing things, I assume it avoids more heavy machinery from git-rev-list and friends.

>  The outlined steps above all feel sensible; one thing you did not
>  mention is that you may probably have to clear object flags after
>  you are done with the initial "--grep" revision traversal, as some
>  features of branch may want to use the object flags (e.g. --merged
>  would use in_merge_bases()). Other than that, all of it sounds
>  easily implementable.

I still need to understand a lot how it all works. Any hint on where to look is appreciated. (I started from looking on builtin/shortlog.c just because it's one of the shortest ones using setup_revisions().)

One thing I'm worried about is that git-branch already has option --all. So we'll get a semantics conflict with setup_revisions() ("all branches" vs "all refs"). This will have to be treated carefully, e.g. retrace and fix effects of --all after setup_revisions() to include just branches but not other refs. Will such mangling be ok? Or could I prepare the call of setup_revisions() in a way that only branches will be included by --all? Anyway the semantics of --all will be different for git-branch and git-rev-list, but I believe more important is to keep it unchanged for git-branch.

>  Note that "branch --list", "tag --list" and "for-each-ref" are being
>  revamped to share more internal code. If you want to pursue this,
>  you probably would want to build on top of that effort once it is
>  done. That way, you may get "tag --grep=FIX123" for free.
>

This is interesting. So can I have a look on some repo/branch or just wait until it'll be merged?

>>   That said, do you think the goal is worth such changes?
>
>  That is a dangerous question. As Duy already said,
>
>>   Probably because nobody is interested and steps up to do it. The lack
>>   of response to you mail is a sign.
>
>  apparently not many people thought it is worth; otherwise we would
>  already have such a feature.
>
>  If you are asking me personally, I'm sorry but I have to say no.
>
>  The reason why I personally do not think your "branch --grep=FIX123"
>  would be very useful to me is because I would imagine that I would
>  be interested in learning the exact commit that mentions FIX123 as
>  well as which branches contain it, if I had a need for such a
>  feature.
>
>  That is, it would inherently be two step process for me anyway, i.e.
>
>   (1) I'd run "log -p --grep" to find which commits are about FIX123
>       and check that what they did indeed make sense; and
>
>   (2) I'd then run "branch --contains" to learn which ones are
>       already up to date with respect to the fix.
>
>  Your "branch --grep=FIX123" that only tells me the names of branches
>  would have no use in that workflow, as it would not even give me an
>  indication that the request --grep=FIX123 found the right commit in
>  the first place.

Yes, I see your point. But let me also explain my use case so it'll be probably more clear. Sorry if it's too long.

I work for HP as SCM and build manager for a product >15 years old. One of this product's greatest strenghts always was support for many old releases and customizations for particular users. So right now we are providing support for 10 subsequent releases (oldest one released back in 2006), and each release has 5 to 10 "customer" branches with their specific enhancements and fixes. (Though, as you would expect, all the fixes are generally merged to mainline, some customers are reluctant to apply fixes they don't need, so even here we must be flexible when preparing a patch.) So basically now I'm managing around 60 public branches in the repository.

SCM was ClearCase at the beginning, then StarTeam (whoa, complete disaster). At this point I joined the team and performed migration to Git last year (took a whole year). So now our history is a mixture of ancient baselines from ClearCase and artificial branches imported from StarTeam (thanks to my colleague who wrote a Git helper for StarTeam, https://github.com/AndreyPavlenko/git-st). So many changes which are 100% identical are represented by different commits, only identifiable with --cherry-pick option to git-log and friends. Even if I spent a great amount of time manually cutting and glueing history in Git to have the shortest logs.

And obviously, our workflow is based on cherry-picks, because very very often fixes and enhancements have to be merged *back* to many old customer branches. And you could immagine that when you port something to a codebase which is 5 years old, it rarely applies cleanly, so even --cherry-pick will not be able to identify it. And even if something is merged forward, it's only merged selectively when we are speaking about features and customer branches.

Supporting all this is a mess, as you could immagine. But that's what customers want, so I have no problem with that. After all, not every team has a dedicated SCM/build manager.

So quite often I or QA or support need to quickly find out, for example, which branches have specific enhancement or fix (ticket id) in their history. Commits which implement the actual feature or fix could be completely different, but the ticket id will be the same. True, it's not enough per se: you will still need to go and look into the branch. But having some initial set of branches is necessary anyway. And usually I trust our developers to mark their commits properly.

I had a look in the Internet before asking to this List, and I was a bit surprised to see that very few people really needed that. So I assumed that either I'm doing something wrong or we are really really special with our 10 years LTS, 60 public branches and cherry-picks. From your answers I tend to think that latter assumption is more correct.

Thanks a lot for your quick and detailed answers.

-- 
  Ivan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Which branch(es) contain certain commits? (was Re: (unknown))
  2015-08-22  9:19         ` Ivan Chernyavsky
@ 2015-08-22 10:32           ` Ivan Chernyavsky
  2015-08-22 10:59           ` Karthik Nayak
  1 sibling, 0 replies; 12+ messages in thread
From: Ivan Chernyavsky @ 2015-08-22 10:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Duy Nguyen, Git Mailing List



22.08.2015, 12:19, "Ivan Chernyavsky" <camposer@yandex.ru>:
>   One thing I'm worried about is that git-branch already has option --all. So we'll get a semantics conflict with setup_revisions() ("all branches" vs "all refs"). This will have to be treated carefully, e.g. retrace and fix effects of --all after setup_revisions() to include just branches but not other refs. Will such mangling be ok? Or could I prepare the call of setup_revisions() in a way that only branches will be included by --all? Anyway the semantics of --all will be different for git-branch and git-rev-list, but I believe more important is to keep it unchanged for git-branch.
>

Please disregard this part. I should just gobble --all with the existing parse_options() and do not provide it to setup_revisions() altogether.

-- 
  Ivan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Which branch(es) contain certain commits? (was Re: (unknown))
  2015-08-22  9:19         ` Ivan Chernyavsky
  2015-08-22 10:32           ` Ivan Chernyavsky
@ 2015-08-22 10:59           ` Karthik Nayak
  1 sibling, 0 replies; 12+ messages in thread
From: Karthik Nayak @ 2015-08-22 10:59 UTC (permalink / raw)
  To: Ivan Chernyavsky; +Cc: Junio C Hamano, Duy Nguyen, Git Mailing List

On Sat, Aug 22, 2015 at 2:49 PM, Ivan Chernyavsky <camposer@yandex.ru> wrote
>
>>  Note that "branch --list", "tag --list" and "for-each-ref" are being
>>  revamped to share more internal code. If you want to pursue this,
>>  you probably would want to build on top of that effort once it is
>>  done. That way, you may get "tag --grep=FIX123" for free.
>>
>
> This is interesting. So can I have a look on some repo/branch or just wait until it'll be merged?
>

This should be what you're looking for:
http://thread.gmane.org/gmane.comp.version-control.git/276363
http://thread.gmane.org/gmane.comp.version-control.git/276377

This is the current progress, the rest is in git/next.

There is still a series of porting the printing part of branch.c to be done.

-- 
Regards,
Karthik Nayak

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-08-22 11:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-05 12:47 (unknown) Ivan Chernyavsky
2015-08-05 17:03 ` Which branch(es) contain certain commits? (was Re: (unknown)) Junio C Hamano
2015-08-05 17:05   ` Junio C Hamano
2015-08-05 19:48     ` Ivan Chernyavsky
2015-08-15  9:19 ` Duy Nguyen
2015-08-17  6:45   ` Which branch(es) contain certain commits? (was Re: (unknown)) Ivan Chernyavsky
2015-08-17 17:49   ` Junio C Hamano
2015-08-21 21:29     ` Which branch(es) contain certain commits? (was Re: (unknown)) Ivan Chernyavsky
2015-08-21 22:39       ` Junio C Hamano
2015-08-22  9:19         ` Ivan Chernyavsky
2015-08-22 10:32           ` Ivan Chernyavsky
2015-08-22 10:59           ` Karthik Nayak

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).