All of lore.kernel.org
 help / color / mirror / Atom feed
* Finding a branch point in git
@ 2012-05-27 12:37 Felipe Contreras
  2012-05-28  6:20 ` Jeff King
  0 siblings, 1 reply; 13+ messages in thread
From: Felipe Contreras @ 2012-05-27 12:37 UTC (permalink / raw)
  To: git

Hi,

When discussing git vs. mercurial, and what can mercurial do that git
can't, I inevitably see somebody mention that mercurial branches can
be used to find the branch point (the point at which a branch started;
even if it's a long-lived one that has been merged to 'master'
multiple times).

There have been a few solutions in stackoverflow[1], but none that
work in all cases.

But I think I've found an ad-hoc one that uses the commit messages to
find the first merge of a branch, and then the merge-base.

For reference, if somebody is interested:

---
[alias]
    branch-point = !sh -c 'merge=$(git rev-list --min-parents=2
--grep="Merge.*$1" --all | tail -1) && git merge-base $merge^1
$merge^2'
---

Cheers.

[1] http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git/

-- 
Felipe Contreras

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

* Re: Finding a branch point in git
  2012-05-27 12:37 Finding a branch point in git Felipe Contreras
@ 2012-05-28  6:20 ` Jeff King
  2012-05-28 12:36   ` Felipe Contreras
  2012-05-30 16:52   ` Felipe Contreras
  0 siblings, 2 replies; 13+ messages in thread
From: Jeff King @ 2012-05-28  6:20 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Sun, May 27, 2012 at 02:37:32PM +0200, Felipe Contreras wrote:

> When discussing git vs. mercurial, and what can mercurial do that git
> can't, I inevitably see somebody mention that mercurial branches can
> be used to find the branch point (the point at which a branch started;
> even if it's a long-lived one that has been merged to 'master'
> multiple times).
> 
> There have been a few solutions in stackoverflow[1], but none that
> work in all cases.
> 
> But I think I've found an ad-hoc one that uses the commit messages to
> find the first merge of a branch, and then the merge-base.
> 
> For reference, if somebody is interested:
> 
> ---
> [alias]
>     branch-point = !sh -c 'merge=$(git rev-list --min-parents=2
> --grep="Merge.*$1" --all | tail -1) && git merge-base $merge^1
> $merge^2'
> ---

I think this approach works for two-branch cases, but there is some
subtlety with the regex. My initial thought was that you were looking
for "Merge 'branch_A'" in the commit message (and that is what is
implied by your stackoverflow response). If you always merge the topic
into the main branch, then you will find the first merge. But imagine
this history:

-- X -- A -- B -- C -- D --  E  (master)
         \         \        /
          \         \      /
           G -- H -- I -- J  (branch A)

where I is a merge from master to branch A (e.g., for testing), and then
E is a merge from branch A to master (the actual integration).

Searching for "Merge 'branch_A'" will find E, and then you will take
the merge base of J and D, which is C. But the answer you want is A.
However, we also say "Merge master into 'branch_A'" when HEAD is not
master. So your regex _would_ catch that, and would find I, for which
the merge base is A.

What about a history with multiple branches?

--X--A--B--C--D----E  (master)
      \           /
       G--H--I---J   (branch X)
           \    /
            K--L    (branch Y)

where Y is merged to X (commit J), and then X is merged to master
(commit E). Searching for the earliest merge mentioning X will find J,
the merge between X and Y. But the merge base of its parents is H.

You can improve your regex by specifying a pair of branches and
looking for "Merge X into master" and "Merge master into X" (IOW, make
sure we don't see merges between X and other branches). Then you would
find E, which yields the correct answer.

There are also even more complex cases. It doesn't make much sense to
ask about where branch Y split from master, since it actually came from
branch X in the above example. But let's say we branched straight from
master, merged our result to X, which got merged to master, and then we
built some more commits on Y and merged them to master. Like:

--X--A--B--C--D----E--F (master)
     |\           /  /
     | \         /  /
      \ G--H----I  /  (branch X)
       \       /  /
        K--L--M--O  (branch Y)

The only merge between master and X is F, but its merge base is M. We
missed the earlier merge to master because it actually happened across
two different commits.

-Peff

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

* Re: Finding a branch point in git
  2012-05-28  6:20 ` Jeff King
@ 2012-05-28 12:36   ` Felipe Contreras
  2012-05-28 19:06     ` Jeff King
  2012-05-30 16:52   ` Felipe Contreras
  1 sibling, 1 reply; 13+ messages in thread
From: Felipe Contreras @ 2012-05-28 12:36 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Mon, May 28, 2012 at 8:20 AM, Jeff King <peff@peff.net> wrote:
> On Sun, May 27, 2012 at 02:37:32PM +0200, Felipe Contreras wrote:
>
>> When discussing git vs. mercurial, and what can mercurial do that git
>> can't, I inevitably see somebody mention that mercurial branches can
>> be used to find the branch point (the point at which a branch started;
>> even if it's a long-lived one that has been merged to 'master'
>> multiple times).
>>
>> There have been a few solutions in stackoverflow[1], but none that
>> work in all cases.
>>
>> But I think I've found an ad-hoc one that uses the commit messages to
>> find the first merge of a branch, and then the merge-base.
>>
>> For reference, if somebody is interested:
>>
>> ---
>> [alias]
>>     branch-point = !sh -c 'merge=$(git rev-list --min-parents=2
>> --grep="Merge.*$1" --all | tail -1) && git merge-base $merge^1
>> $merge^2'
>> ---
>
> I think this approach works for two-branch cases, but there is some
> subtlety with the regex. My initial thought was that you were looking
> for "Merge 'branch_A'" in the commit message (and that is what is
> implied by your stackoverflow response). If you always merge the topic
> into the main branch, then you will find the first merge. But imagine
> this history:
>
> -- X -- A -- B -- C -- D --  E  (master)
>         \         \        /
>          \         \      /
>           G -- H -- I -- J  (branch A)
>
> where I is a merge from master to branch A (e.g., for testing), and then
> E is a merge from branch A to master (the actual integration).
>
> Searching for "Merge 'branch_A'" will find E, and then you will take
> the merge base of J and D, which is C. But the answer you want is A.
> However, we also say "Merge master into 'branch_A'" when HEAD is not
> master. So your regex _would_ catch that, and would find I, for which
> the merge base is A.

Yeap.

> What about a history with multiple branches?
>
> --X--A--B--C--D----E  (master)
>      \           /
>       G--H--I---J   (branch X)
>           \    /
>            K--L    (branch Y)
>
> where Y is merged to X (commit J), and then X is merged to master
> (commit E). Searching for the earliest merge mentioning X will find J,
> the merge between X and Y. But the merge base of its parents is H.
>
> You can improve your regex by specifying a pair of branches and
> looking for "Merge X into master" and "Merge master into X" (IOW, make
> sure we don't see merges between X and other branches). Then you would
> find E, which yields the correct answer.

Yes, but then you would need to specify a second branch. I would avoid
that if possible.

> There are also even more complex cases. It doesn't make much sense to
> ask about where branch Y split from master, since it actually came from
> branch X in the above example. But let's say we branched straight from
> master, merged our result to X, which got merged to master, and then we
> built some more commits on Y and merged them to master. Like:
>
> --X--A--B--C--D----E--F (master)
>     |\           /  /
>     | \         /  /
>      \ G--H----I  /  (branch X)
>       \       /  /
>        K--L--M--O  (branch Y)
>
> The only merge between master and X is F, but its merge base is M. We
> missed the earlier merge to master because it actually happened across
> two different commits.

Cases 2) and 3) would work if the search was for "Merge branch 'X'",
but then case 1) would fail. One possible solution would be to find
the earliest "Merge branch 'X' into (\w+)", and then search if there
are any earlier "Merge branch '$1' into X".

There's also another case that doesn't work:

-- X -- A -- B (master)
         \
          \
           C (branch A)

Shouldn't be hard to add checks for those cases I think.

Cheers.

-- 
Felipe Contreras

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

* Re: Finding a branch point in git
  2012-05-28 12:36   ` Felipe Contreras
@ 2012-05-28 19:06     ` Jeff King
  2012-05-30 17:07       ` Felipe Contreras
  0 siblings, 1 reply; 13+ messages in thread
From: Jeff King @ 2012-05-28 19:06 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:

> > What about a history with multiple branches?
> >
> > --X--A--B--C--D----E  (master)
> >      \           /
> >       G--H--I---J   (branch X)
> >           \    /
> >            K--L    (branch Y)
> [...]
> 
> Yes, but then you would need to specify a second branch. I would avoid
> that if possible.

I agree that is less nice. But I don't think the operation is
well-defined with a single branch. If you ask for "when did branch X
split", then in the above graph it is unclear if you meant "split from
master", or "split from Y".

Maybe you could assume "master", or assume "git symbolic-ref HEAD" as
the second branch?

> There's also another case that doesn't work:
> 
> -- X -- A -- B (master)
>          \
>           \
>            C (branch A)
> 
> Shouldn't be hard to add checks for those cases I think.

Actually, I think that one extends naturally. They are never merged, so
your rev-list never finds a merge commit, and you can just take the
merge base of the branch tips.

-Peff

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

* Re: Finding a branch point in git
  2012-05-28  6:20 ` Jeff King
  2012-05-28 12:36   ` Felipe Contreras
@ 2012-05-30 16:52   ` Felipe Contreras
  2012-05-30 21:45     ` Jeff King
  1 sibling, 1 reply; 13+ messages in thread
From: Felipe Contreras @ 2012-05-30 16:52 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Mon, May 28, 2012 at 8:20 AM, Jeff King <peff@peff.net> wrote:

> There are also even more complex cases. It doesn't make much sense to
> ask about where branch Y split from master, since it actually came from
> branch X in the above example. But let's say we branched straight from
> master, merged our result to X, which got merged to master, and then we
> built some more commits on Y and merged them to master. Like:
>
> --X--A--B--C--D----E--F (master)
>     |\           /  /
>     | \         /  /
>      \ G--H----I  /  (branch X)
>       \       /  /
>        K--L--M--O  (branch Y)
>
> The only merge between master and X is F, but its merge base is M. We
> missed the earlier merge to master because it actually happened across
> two different commits.

I assume you mean the merge between master and Y.

-- 
Felipe Contreras

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

* Re: Finding a branch point in git
  2012-05-28 19:06     ` Jeff King
@ 2012-05-30 17:07       ` Felipe Contreras
  2012-05-30 21:54         ` Jeff King
  0 siblings, 1 reply; 13+ messages in thread
From: Felipe Contreras @ 2012-05-30 17:07 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:
> On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:
>
>> > What about a history with multiple branches?
>> >
>> > --X--A--B--C--D----E  (master)
>> >      \           /
>> >       G--H--I---J   (branch X)
>> >           \    /
>> >            K--L    (branch Y)
>> [...]
>>
>> Yes, but then you would need to specify a second branch. I would avoid
>> that if possible.
>
> I agree that is less nice. But I don't think the operation is
> well-defined with a single branch. If you ask for "when did branch X
> split", then in the above graph it is unclear if you meant "split from
> master", or "split from Y".

If you look from the context that I explained in the first mail; it
would be from *any* branch; IOW; find the first commit from branch X
(G), and then find the parent. That would be the first commit where
branch X started.

> Maybe you could assume "master", or assume "git symbolic-ref HEAD" as
> the second branch?

No.

I think it would be easy to support this case if somehow there was a
way to find all the commits that comprise a branch;

 % git log branch ^<any-other-branch>

I could swear I saw such an option, but I've been looking for days and
I can't find it.

IOW; all the commits were 'git branch --contains' would show 'branch'
and nothing else.

>> There's also another case that doesn't work:
>>
>> -- X -- A -- B (master)
>>          \
>>           \
>>            C (branch A)
>>
>> Shouldn't be hard to add checks for those cases I think.
>
> Actually, I think that one extends naturally. They are never merged, so
> your rev-list never finds a merge commit, and you can just take the
> merge base of the branch tips.

Sure, I can _just_ do that, but I need to do it :)

So, here it is... I hope people can find ways to simplify it:

find_merge ()
{
	local selection extra
	test "$2" && extra=" into $2"
	git rev-list --min-parents=2 --grep="Merge branch '$1'$extra"
--topo-order ${3:---all} | tail -1
}

branch_point ()
{
	local first_merge second_merge merge
	first_merge=$(find_merge $1 "" "$1 $2")
	second_merge=$(find_merge $2 $1 $first_merge)
	merge=${second_merge:-$first_merge}

	if [ "$merge" ]; then
		git merge-base $merge^1 $merge^2
	else
		git merge-base $1 $2
	fi
}

And I've added tests:
https://raw.github.com/gist/2837595/0734e7f17a4597f81c5129e3cbfee09a183e93cd/branch-point

Seems to work :)

Cheers.

-- 
Felipe Contreras

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

* Re: Finding a branch point in git
  2012-05-30 16:52   ` Felipe Contreras
@ 2012-05-30 21:45     ` Jeff King
  0 siblings, 0 replies; 13+ messages in thread
From: Jeff King @ 2012-05-30 21:45 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Wed, May 30, 2012 at 06:52:15PM +0200, Felipe Contreras wrote:

> > --X--A--B--C--D----E--F (master)
> >     |\           /  /
> >     | \         /  /
> >      \ G--H----I  /  (branch X)
> >       \       /  /
> >        K--L--M--O  (branch Y)
> >
> > The only merge between master and X is F, but its merge base is M. We
> > missed the earlier merge to master because it actually happened across
> > two different commits.
> 
> I assume you mean the merge between master and Y.

Oops, yes.

-Peff

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

* Re: Finding a branch point in git
  2012-05-30 17:07       ` Felipe Contreras
@ 2012-05-30 21:54         ` Jeff King
  2012-05-31 15:27           ` Felipe Contreras
  2012-05-31 15:37           ` Martin Langhoff
  0 siblings, 2 replies; 13+ messages in thread
From: Jeff King @ 2012-05-30 21:54 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: git

On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:

> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:
> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:
> >
> >> > What about a history with multiple branches?
> >> >
> >> > --X--A--B--C--D----E  (master)
> >> >      \           /
> >> >       G--H--I---J   (branch X)
> >> >           \    /
> >> >            K--L    (branch Y)
> >> [...]
> >>
> >> Yes, but then you would need to specify a second branch. I would avoid
> >> that if possible.
> >
> > I agree that is less nice. But I don't think the operation is
> > well-defined with a single branch. If you ask for "when did branch X
> > split", then in the above graph it is unclear if you meant "split from
> > master", or "split from Y".
> 
> If you look from the context that I explained in the first mail; it
> would be from *any* branch; IOW; find the first commit from branch X
> (G), and then find the parent. That would be the first commit where
> branch X started.

I'm not sure that's possible, though, in the face of criss-cross merges.
How do we distinguish the history above from one in which branch Y was
forked from master at G, and then branch X was forked from branch Y at
H?

> I think it would be easy to support this case if somehow there was a
> way to find all the commits that comprise a branch;
> 
>  % git log branch ^<any-other-branch>
> 
> I could swear I saw such an option, but I've been looking for days and
> I can't find it.

I don't think there is such an option. You have to do something like:

  {
    echo "--not"
    git for-each-ref --format='%(refname)' | grep -v "^$branch\$"
  } |
  git rev-list --stdin $branch

-Peff

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

* Re: Finding a branch point in git
  2012-05-30 21:54         ` Jeff King
@ 2012-05-31 15:27           ` Felipe Contreras
  2012-05-31 16:10             ` Felipe Contreras
  2012-05-31 20:37             ` PJ Weisberg
  2012-05-31 15:37           ` Martin Langhoff
  1 sibling, 2 replies; 13+ messages in thread
From: Felipe Contreras @ 2012-05-31 15:27 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Wed, May 30, 2012 at 11:54 PM, Jeff King <peff@peff.net> wrote:
> On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:
>
>> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:
>> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:
>> >
>> >> > What about a history with multiple branches?
>> >> >
>> >> > --X--A--B--C--D----E  (master)
>> >> >      \           /
>> >> >       G--H--I---J   (branch X)
>> >> >           \    /
>> >> >            K--L    (branch Y)
>> >> [...]
>> >>
>> >> Yes, but then you would need to specify a second branch. I would avoid
>> >> that if possible.
>> >
>> > I agree that is less nice. But I don't think the operation is
>> > well-defined with a single branch. If you ask for "when did branch X
>> > split", then in the above graph it is unclear if you meant "split from
>> > master", or "split from Y".
>>
>> If you look from the context that I explained in the first mail; it
>> would be from *any* branch; IOW; find the first commit from branch X
>> (G), and then find the parent. That would be the first commit where
>> branch X started.
>
> I'm not sure that's possible, though, in the face of criss-cross merges.
> How do we distinguish the history above from one in which branch Y was
> forked from master at G, and then branch X was forked from branch Y at
> H?

That is true, but we could use the algorithm used by name-rev: G would
have a distance 3 from branch X, and distance 2 from Y, so it would be
considered part of branch Y.

Sure, it's not possible to know _for sure_, but this is a bit like
renames; we don't really know if a file was renamed or not, but we can
make a good guess.

>> I think it would be easy to support this case if somehow there was a
>> way to find all the commits that comprise a branch;
>>
>>  % git log branch ^<any-other-branch>
>>
>> I could swear I saw such an option, but I've been looking for days and
>> I can't find it.
>
> I don't think there is such an option. You have to do something like:
>
>  {
>    echo "--not"
>    git for-each-ref --format='%(refname)' | grep -v "^$branch\$"

Rather:
git for-each-ref --format='%(refname:short)' refs/heads | grep -v "^$branch\$"

>  } |
>  git rev-list --stdin $branch

Cheers.

-- 
Felipe Contreras

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

* Re: Finding a branch point in git
  2012-05-30 21:54         ` Jeff King
  2012-05-31 15:27           ` Felipe Contreras
@ 2012-05-31 15:37           ` Martin Langhoff
  1 sibling, 0 replies; 13+ messages in thread
From: Martin Langhoff @ 2012-05-31 15:37 UTC (permalink / raw)
  To: Jeff King; +Cc: Felipe Contreras, git

On Wed, May 30, 2012 at 5:54 PM, Jeff King <peff@peff.net> wrote:
> >  % git log branch ^<any-other-branch>
> >
> > I could swear I saw such an option, but I've been looking for days and
> > I can't find it.
>
> I don't think there is such an option. You have to do something like:

I do

   gitk olpc-kernel-branch ^origin/master

to peruse OLPC's branch of the linux kernel without reading a
bazillion commits into memory.

Anyway, this whole discussion assumes a very simplistic branching and
development scenario. Some forks and merges are due to developers
working offline or in per-developer repos. No automatic way to know
what's an intentional branch.

cheers,



m
--
 martin.langhoff@gmail.com
 martin@laptop.org -- Software Architect - OLPC
 - ask interesting questions
 - don't get distracted with shiny stuff  - working code first
 - http://wiki.laptop.org/go/User:Martinlanghoff

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

* Re: Finding a branch point in git
  2012-05-31 15:27           ` Felipe Contreras
@ 2012-05-31 16:10             ` Felipe Contreras
  2012-05-31 20:37             ` PJ Weisberg
  1 sibling, 0 replies; 13+ messages in thread
From: Felipe Contreras @ 2012-05-31 16:10 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Thu, May 31, 2012 at 5:27 PM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> On Wed, May 30, 2012 at 11:54 PM, Jeff King <peff@peff.net> wrote:
>> On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:
>>
>>> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:
>>> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:
>>> >
>>> >> > What about a history with multiple branches?
>>> >> >
>>> >> > --X--A--B--C--D----E  (master)
>>> >> >      \           /
>>> >> >       G--H--I---J   (branch X)
>>> >> >           \    /
>>> >> >            K--L    (branch Y)
>>> >> [...]
>>> >>
>>> >> Yes, but then you would need to specify a second branch. I would avoid
>>> >> that if possible.
>>> >
>>> > I agree that is less nice. But I don't think the operation is
>>> > well-defined with a single branch. If you ask for "when did branch X
>>> > split", then in the above graph it is unclear if you meant "split from
>>> > master", or "split from Y".
>>>
>>> If you look from the context that I explained in the first mail; it
>>> would be from *any* branch; IOW; find the first commit from branch X
>>> (G), and then find the parent. That would be the first commit where
>>> branch X started.
>>
>> I'm not sure that's possible, though, in the face of criss-cross merges.
>> How do we distinguish the history above from one in which branch Y was
>> forked from master at G, and then branch X was forked from branch Y at
>> H?
>
> That is true, but we could use the algorithm used by name-rev: G would
> have a distance 3 from branch X, and distance 2 from Y, so it would be
> considered part of branch Y.

Er, actually that would list X as branch Y. Now I believe there is a
real problem.

However, I don't believe mercurial branch labels are the solution;
probably a pointer to the tail of the branch would provide with all
the information needed.

Cheers.

-- 
Felipe Contreras

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

* Re: Finding a branch point in git
  2012-05-31 15:27           ` Felipe Contreras
  2012-05-31 16:10             ` Felipe Contreras
@ 2012-05-31 20:37             ` PJ Weisberg
  2012-06-01  9:15               ` Felipe Contreras
  1 sibling, 1 reply; 13+ messages in thread
From: PJ Weisberg @ 2012-05-31 20:37 UTC (permalink / raw)
  To: Felipe Contreras; +Cc: Jeff King, git

On Thu, May 31, 2012 at 8:27 AM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> On Wed, May 30, 2012 at 11:54 PM, Jeff King <peff@peff.net> wrote:
>> On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:
>>
>>> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:
>>> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:
>>> >
>>> >> > What about a history with multiple branches?
>>> >> >
>>> >> > --X--A--B--C--D----E  (master)
>>> >> >      \           /
>>> >> >       G--H--I---J   (branch X)
>>> >> >           \    /
>>> >> >            K--L    (branch Y)
>>> >> [...]
>>> >>
>>> >> Yes, but then you would need to specify a second branch. I would avoid
>>> >> that if possible.
>>> >
>>> > I agree that is less nice. But I don't think the operation is
>>> > well-defined with a single branch. If you ask for "when did branch X
>>> > split", then in the above graph it is unclear if you meant "split from
>>> > master", or "split from Y".
>>>
>>> If you look from the context that I explained in the first mail; it
>>> would be from *any* branch; IOW; find the first commit from branch X
>>> (G), and then find the parent. That would be the first commit where
>>> branch X started.
>>
>> I'm not sure that's possible, though, in the face of criss-cross merges.
>> How do we distinguish the history above from one in which branch Y was
>> forked from master at G, and then branch X was forked from branch Y at
>> H?
>
> That is true, but we could use the algorithm used by name-rev: G would
> have a distance 3 from branch X, and distance 2 from Y, so it would be
> considered part of branch Y.
>
> Sure, it's not possible to know _for sure_, but this is a bit like
> renames; we don't really know if a file was renamed or not, but we can
> make a good guess.

Obviously G is part of branch Y, branch X, and branch master.  I'm
sure I'm missing the whole point of this exercise, because it seems to
me that it's just needlessly confusing to say anything else.

-PJ

Gehm's Corollary to Clark's Law: Any technology distinguishable from
magic is insufficiently advanced.

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

* Re: Finding a branch point in git
  2012-05-31 20:37             ` PJ Weisberg
@ 2012-06-01  9:15               ` Felipe Contreras
  0 siblings, 0 replies; 13+ messages in thread
From: Felipe Contreras @ 2012-06-01  9:15 UTC (permalink / raw)
  To: PJ Weisberg; +Cc: Jeff King, git

On Thu, May 31, 2012 at 10:37 PM, PJ Weisberg
<pj@irregularexpressions.net> wrote:
> On Thu, May 31, 2012 at 8:27 AM, Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
>> On Wed, May 30, 2012 at 11:54 PM, Jeff King <peff@peff.net> wrote:
>>> On Wed, May 30, 2012 at 07:07:39PM +0200, Felipe Contreras wrote:
>>>
>>>> On Mon, May 28, 2012 at 9:06 PM, Jeff King <peff@peff.net> wrote:
>>>> > On Mon, May 28, 2012 at 02:36:04PM +0200, Felipe Contreras wrote:
>>>> >
>>>> >> > What about a history with multiple branches?
>>>> >> >
>>>> >> > --X--A--B--C--D----E  (master)
>>>> >> >      \           /
>>>> >> >       G--H--I---J   (branch X)
>>>> >> >           \    /
>>>> >> >            K--L    (branch Y)
>>>> >> [...]
>>>> >>
>>>> >> Yes, but then you would need to specify a second branch. I would avoid
>>>> >> that if possible.
>>>> >
>>>> > I agree that is less nice. But I don't think the operation is
>>>> > well-defined with a single branch. If you ask for "when did branch X
>>>> > split", then in the above graph it is unclear if you meant "split from
>>>> > master", or "split from Y".
>>>>
>>>> If you look from the context that I explained in the first mail; it
>>>> would be from *any* branch; IOW; find the first commit from branch X
>>>> (G), and then find the parent. That would be the first commit where
>>>> branch X started.
>>>
>>> I'm not sure that's possible, though, in the face of criss-cross merges.
>>> How do we distinguish the history above from one in which branch Y was
>>> forked from master at G, and then branch X was forked from branch Y at
>>> H?
>>
>> That is true, but we could use the algorithm used by name-rev: G would
>> have a distance 3 from branch X, and distance 2 from Y, so it would be
>> considered part of branch Y.
>>
>> Sure, it's not possible to know _for sure_, but this is a bit like
>> renames; we don't really know if a file was renamed or not, but we can
>> make a good guess.
>
> Obviously G is part of branch Y, branch X, and branch master.  I'm
> sure I'm missing the whole point of this exercise, because it seems to
> me that it's just needlessly confusing to say anything else.

It's not about which commit is part of which branch, but figuring out
which is the first commit that was created being in branch Y.

I don't see a tremendous value on this, but there is some, for example:

 % git rebase --onto master branch_Y@{tail} branch_Y

Depending on the case, this might not be what you want, but sometimes
it might, the problem is that you can't know automatically if
branch_Y@{tail} is G, or K. So normally you would fire gitk and select
the commit that you want, which is not a big deal, but still, it would
be nice if the tail of a branch was recorded somehow.

To be clear, if I do:

 % git checkout -b branch_Y
 % git commit <- this would be branch_Y's tail

 % git rebase --onto master <- now branch_Y's tail would be right on
top of master

Cheers.

-- 
Felipe Contreras

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

end of thread, other threads:[~2012-06-01  9:15 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-27 12:37 Finding a branch point in git Felipe Contreras
2012-05-28  6:20 ` Jeff King
2012-05-28 12:36   ` Felipe Contreras
2012-05-28 19:06     ` Jeff King
2012-05-30 17:07       ` Felipe Contreras
2012-05-30 21:54         ` Jeff King
2012-05-31 15:27           ` Felipe Contreras
2012-05-31 16:10             ` Felipe Contreras
2012-05-31 20:37             ` PJ Weisberg
2012-06-01  9:15               ` Felipe Contreras
2012-05-31 15:37           ` Martin Langhoff
2012-05-30 16:52   ` Felipe Contreras
2012-05-30 21:45     ` Jeff King

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.