git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* Getting an actuallt useful merge base?
@ 2021-02-24 17:58 Michal Suchánek
  2021-02-25  2:40 ` brian m. carlson
  0 siblings, 1 reply; 7+ messages in thread
From: Michal Suchánek @ 2021-02-24 17:58 UTC (permalink / raw)
  To: git

Hello,

I find the results of git merge-base A B quite useless.

Suppose you have a repository with file sets

S and T

where S are sources which are developed in mainline and number of stable
versions, and feature branches, and T are build tools (such as autoconf
tests or whatever) that are largely independent of the source version.

Because of the independence of T from S T are developed in a separate
branch t which is merged into all branches developing S as needed.

Fixes to S may affect more than one version, and depending on the
situation it might be useful to apply fixes to S to mutiple
stable/feature branche at once. For that one would need a merge base of
the branches in question.

However, merge-base almost always give a commit on branch t which is the
merge base of files in set T and does not contain files in set S at all.
In other words it is merge base only for files from set T and not set S.
Can I get merge base that is merge base for all files that have common
history between two branches?

Thanks

Michal

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

* Re: Getting an actuallt useful merge base?
  2021-02-24 17:58 Getting an actuallt useful merge base? Michal Suchánek
@ 2021-02-25  2:40 ` brian m. carlson
  2021-02-25 18:29   ` Michal Suchánek
  0 siblings, 1 reply; 7+ messages in thread
From: brian m. carlson @ 2021-02-25  2:40 UTC (permalink / raw)
  To: Michal Suchánek; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 1922 bytes --]

On 2021-02-24 at 17:58:34, Michal Suchánek wrote:
> Hello,
> 
> I find the results of git merge-base A B quite useless.
> 
> Suppose you have a repository with file sets
> 
> S and T
> 
> where S are sources which are developed in mainline and number of stable
> versions, and feature branches, and T are build tools (such as autoconf
> tests or whatever) that are largely independent of the source version.
> 
> Because of the independence of T from S T are developed in a separate
> branch t which is merged into all branches developing S as needed.
> 
> Fixes to S may affect more than one version, and depending on the
> situation it might be useful to apply fixes to S to mutiple
> stable/feature branche at once. For that one would need a merge base of
> the branches in question.
> 
> However, merge-base almost always give a commit on branch t which is the
> merge base of files in set T and does not contain files in set S at all.
> In other words it is merge base only for files from set T and not set S.
> Can I get merge base that is merge base for all files that have common
> history between two branches?

The merge base is determined by the history.  In your case, I imagine
you have a history like this:

 A -- B -- C -- D -- E -- F -- G (S)
        _/        _/        _/
 H -- I -- J -- K -- L -- M -- N (T)

Here, the merge base of N and G is M, and the merge base of F and M is
K.  Those are the most recent common ancestors, which are typically
chosen as the merge base.

In your case, you probably want to cherry-pick a commit, or maybe rebase
a small set of commits onto another set.  That would probably work
better than trying to merge.  It's possible that there's something about
this case that I'm missing where it wouldn't work properly, but it's
definitely the approach I would try.
-- 
brian m. carlson (he/him or they/them)
Houston, Texas, US

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

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

* Re: Getting an actuallt useful merge base?
  2021-02-25  2:40 ` brian m. carlson
@ 2021-02-25 18:29   ` Michal Suchánek
  2021-02-25 19:52     ` Elijah Newren
  0 siblings, 1 reply; 7+ messages in thread
From: Michal Suchánek @ 2021-02-25 18:29 UTC (permalink / raw)
  To: brian m. carlson, git

On Thu, Feb 25, 2021 at 02:40:59AM +0000, brian m. carlson wrote:
> On 2021-02-24 at 17:58:34, Michal Suchánek wrote:
> > Hello,
> > 
> > I find the results of git merge-base A B quite useless.
> > 
> > Suppose you have a repository with file sets
> > 
> > S and T
> > 
> > where S are sources which are developed in mainline and number of stable
> > versions, and feature branches, and T are build tools (such as autoconf
> > tests or whatever) that are largely independent of the source version.
> > 
> > Because of the independence of T from S T are developed in a separate
> > branch t which is merged into all branches developing S as needed.
> > 
> > Fixes to S may affect more than one version, and depending on the
> > situation it might be useful to apply fixes to S to mutiple
> > stable/feature branche at once. For that one would need a merge base of
> > the branches in question.
> > 
> > However, merge-base almost always give a commit on branch t which is the
> > merge base of files in set T and does not contain files in set S at all.
> > In other words it is merge base only for files from set T and not set S.
> > Can I get merge base that is merge base for all files that have common
> > history between two branches?
> 
> The merge base is determined by the history.  In your case, I imagine
> you have a history like this:
> 
>  A -- B -- C -- D -- E -- F -- G (S)
>         _/        _/        _/
>  H -- I -- J -- K -- L -- M -- N (T)
> 
> Here, the merge base of N and G is M, and the merge base of F and M is
> K.  Those are the most recent common ancestors, which are typically
> chosen as the merge base.
> 
> In your case, you probably want to cherry-pick a commit, or maybe rebase
> a small set of commits onto another set.  That would probably work
> better than trying to merge.  It's possible that there's something about
> this case that I'm missing where it wouldn't work properly, but it's
> definitely the approach I would try.

It's like this

T
----o----o----o----o----o----o----o----o----o----o----o----o---(t)---o----o----
     \             \     \                                      \\\
      \             \     \                                      \\\
       \             \     \                                      \\\
        \        o----o----o\̶---o---(s)---o----o----o----o----o----o\̶\̶-(a)
         \      /            \      /                                \\
S+T  o----o----o----o----o----o----o----o----o----o----o----o----o----o\̶--(b)
    /                                       /                           \
---o----o----o----o----o----o----o----o----o----o----o----o----o----o----o---(m)

So (t) is common ancestor for (a) and (b) that merge-base reports but it is
only ancestor for files in set T, and does not have files from set S at all.
The common ancestor I am insterested in is (s) which is merge base for both
sets of files.

Thanks

Michal

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

* Re: Getting an actuallt useful merge base?
  2021-02-25 18:29   ` Michal Suchánek
@ 2021-02-25 19:52     ` Elijah Newren
  2021-02-25 20:03       ` Junio C Hamano
  0 siblings, 1 reply; 7+ messages in thread
From: Elijah Newren @ 2021-02-25 19:52 UTC (permalink / raw)
  To: Michal Suchánek; +Cc: brian m. carlson, Git Mailing List

On Thu, Feb 25, 2021 at 10:34 AM Michal Suchánek <msuchanek@suse.de> wrote:
>
> On Thu, Feb 25, 2021 at 02:40:59AM +0000, brian m. carlson wrote:
> > On 2021-02-24 at 17:58:34, Michal Suchánek wrote:
> > > Hello,
> > >
> > > I find the results of git merge-base A B quite useless.
> > >
> > > Suppose you have a repository with file sets
> > >
> > > S and T
> > >
> > > where S are sources which are developed in mainline and number of stable
> > > versions, and feature branches, and T are build tools (such as autoconf
> > > tests or whatever) that are largely independent of the source version.
> > >
> > > Because of the independence of T from S T are developed in a separate
> > > branch t which is merged into all branches developing S as needed.
> > >
> > > Fixes to S may affect more than one version, and depending on the
> > > situation it might be useful to apply fixes to S to mutiple
> > > stable/feature branche at once. For that one would need a merge base of
> > > the branches in question.
> > >
> > > However, merge-base almost always give a commit on branch t which is the
> > > merge base of files in set T and does not contain files in set S at all.
> > > In other words it is merge base only for files from set T and not set S.
> > > Can I get merge base that is merge base for all files that have common
> > > history between two branches?
> >
> > The merge base is determined by the history.  In your case, I imagine
> > you have a history like this:
> >
> >  A -- B -- C -- D -- E -- F -- G (S)
> >         _/        _/        _/
> >  H -- I -- J -- K -- L -- M -- N (T)
> >
> > Here, the merge base of N and G is M, and the merge base of F and M is
> > K.  Those are the most recent common ancestors, which are typically
> > chosen as the merge base.
> >
> > In your case, you probably want to cherry-pick a commit, or maybe rebase
> > a small set of commits onto another set.  That would probably work
> > better than trying to merge.  It's possible that there's something about
> > this case that I'm missing where it wouldn't work properly, but it's
> > definitely the approach I would try.
>
> It's like this
>
> T
> ----o----o----o----o----o----o----o----o----o----o----o----o---(t)---o----o----
>      \             \     \                                      \\\
>       \             \     \                                      \\\
>        \             \     \                                      \\\
>         \        o----o----o\̶---o---(s)---o----o----o----o----o----o\̶\̶-(a)
>          \      /            \      /                                \\
> S+T  o----o----o----o----o----o----o----o----o----o----o----o----o----o\̶--(b)
>     /                                       /                           \
> ---o----o----o----o----o----o----o----o----o----o----o----o----o----o----o---(m)
>
> So (t) is common ancestor for (a) and (b) that merge-base reports but it is
> only ancestor for files in set T, and does not have files from set S at all.
> The common ancestor I am insterested in is (s) which is merge base for both
> sets of files.

From git-merge-base(1):

"When the history involves criss-cross merges, there can be more than
one best common ancestor for two commits...When the --all option is
not given, it is unspecified which best one is output."

Perhaps you want to specify --all to git merge-base, and then perform
additional checks on the output to select one yourself?

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

* Re: Getting an actuallt useful merge base?
  2021-02-25 19:52     ` Elijah Newren
@ 2021-02-25 20:03       ` Junio C Hamano
  2021-02-25 20:16         ` Elijah Newren
  2021-02-25 20:26         ` Michal Suchánek
  0 siblings, 2 replies; 7+ messages in thread
From: Junio C Hamano @ 2021-02-25 20:03 UTC (permalink / raw)
  To: Elijah Newren; +Cc: Michal Suchánek, brian m. carlson, Git Mailing List

Elijah Newren <newren@gmail.com> writes:

>> It's like this
>>
>> T
>> ----o----o----o----o----o----o----o----o----o----o----o----o---(t)---o----o----
>>      \             \     \                                      \\\
>>       \             \     \                                      \\\
>>        \             \     \                                      \\\
>>         \        o----o----o\̶---o---(s)---o----o----o----o----o----o\̶\̶-(a)
>>          \      /            \      /                                \\
>> S+T  o----o----o----o----o----o----o----o----o----o----o----o----o----o\̶--(b)
>>     /                                       /                           \
>> ---o----o----o----o----o----o----o----o----o----o----o----o----o----o----o---(m)
>>
>> So (t) is common ancestor for (a) and (b) that merge-base reports but it is
>> only ancestor for files in set T, and does not have files from set S at all.
>> The common ancestor I am insterested in is (s) which is merge base for both
>> sets of files.
>
> From git-merge-base(1):
>
> "When the history involves criss-cross merges, there can be more than
> one best common ancestor for two commits...When the --all option is
> not given, it is unspecified which best one is output."
>
> Perhaps you want to specify --all to git merge-base, and then perform
> additional checks on the output to select one yourself?

Ignore me, as it is likely I am just confused, but if we are merging
(a) and (b), I do not think (s) could be usable as a merge base; it
may be an ancestor of (a) but is not an ancestor of (b), no?


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

* Re: Getting an actuallt useful merge base?
  2021-02-25 20:03       ` Junio C Hamano
@ 2021-02-25 20:16         ` Elijah Newren
  2021-02-25 20:26         ` Michal Suchánek
  1 sibling, 0 replies; 7+ messages in thread
From: Elijah Newren @ 2021-02-25 20:16 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Michal Suchánek, brian m. carlson, Git Mailing List

On Thu, Feb 25, 2021 at 12:04 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Elijah Newren <newren@gmail.com> writes:
>
> >> It's like this
> >>
> >> T
> >> ----o----o----o----o----o----o----o----o----o----o----o----o---(t)---o----o----
> >>      \             \     \                                      \\\
> >>       \             \     \                                      \\\
> >>        \             \     \                                      \\\
> >>         \        o----o----o\̶---o---(s)---o----o----o----o----o----o\̶\̶-(a)
> >>          \      /            \      /                                \\
> >> S+T  o----o----o----o----o----o----o----o----o----o----o----o----o----o\̶--(b)
> >>     /                                       /                           \
> >> ---o----o----o----o----o----o----o----o----o----o----o----o----o----o----o---(m)
> >>
> >> So (t) is common ancestor for (a) and (b) that merge-base reports but it is
> >> only ancestor for files in set T, and does not have files from set S at all.
> >> The common ancestor I am insterested in is (s) which is merge base for both
> >> sets of files.
> >
> > From git-merge-base(1):
> >
> > "When the history involves criss-cross merges, there can be more than
> > one best common ancestor for two commits...When the --all option is
> > not given, it is unspecified which best one is output."
> >
> > Perhaps you want to specify --all to git merge-base, and then perform
> > additional checks on the output to select one yourself?
>
> Ignore me, as it is likely I am just confused, but if we are merging
> (a) and (b), I do not think (s) could be usable as a merge base; it
> may be an ancestor of (a) but is not an ancestor of (b), no?

No, I think you're totally right; I was looking at (t) and (a) rather
than (a) and (b) for some reason.  As you point out, (s) isn't a
merge-base of (a) and (b), so it wouldn't be printed by `git
merge-base --all` either.

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

* Re: Getting an actuallt useful merge base?
  2021-02-25 20:03       ` Junio C Hamano
  2021-02-25 20:16         ` Elijah Newren
@ 2021-02-25 20:26         ` Michal Suchánek
  1 sibling, 0 replies; 7+ messages in thread
From: Michal Suchánek @ 2021-02-25 20:26 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Elijah Newren, brian m. carlson, Git Mailing List

On Thu, Feb 25, 2021 at 12:03:58PM -0800, Junio C Hamano wrote:
> Elijah Newren <newren@gmail.com> writes:
> 
> >> It's like this
> >>
> >> T
> >> ----o----o----o----o----o----o----o----o----o----o----o----o---(t)---o----o----
> >>      \             \     \                                      \\\
> >>       \             \     \                                      \\\
> >>        \             \     \                                      \\\
> >>         \        o----o----o\̶---o---(s)---o----o----o----o----o----o\̶\̶-(a)
> >>          \      /            \      /                                \\
> >> S+T  o----o----o----o----o----o---(u)---o----o----o----o----o----o----o\̶--(b)
> >>     /                                       /                           \
> >> ---o----o----o----o----o----o----o----o----o----o----o----o----o----o----o---(m)
> >>
> >> So (t) is common ancestor for (a) and (b) that merge-base reports but it is
> >> only ancestor for files in set T, and does not have files from set S at all.
> >> The common ancestor I am insterested in is (s) which is merge base for both
> >> sets of files.
> >
> > From git-merge-base(1):
> >
> > "When the history involves criss-cross merges, there can be more than
> > one best common ancestor for two commits...When the --all option is
> > not given, it is unspecified which best one is output."
> >
> > Perhaps you want to specify --all to git merge-base, and then perform
> > additional checks on the output to select one yourself?

The description does not inspire much confidence but it indeed gives
something reasonable (ie what looks like would be (t) (u) in this
situation).

Nonetheless, (t) is clearly inferior and is reported by default when
--all is not given.

> 
> Ignore me, as it is likely I am just confused, but if we are merging
> (a) and (b), I do not think (s) could be usable as a merge base; it
> may be an ancestor of (a) but is not an ancestor of (b), no?

Indeed, it should be the parent of (s) on the (b) branch - (u).

Thanks

Michal

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

end of thread, other threads:[~2021-02-25 20:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-24 17:58 Getting an actuallt useful merge base? Michal Suchánek
2021-02-25  2:40 ` brian m. carlson
2021-02-25 18:29   ` Michal Suchánek
2021-02-25 19:52     ` Elijah Newren
2021-02-25 20:03       ` Junio C Hamano
2021-02-25 20:16         ` Elijah Newren
2021-02-25 20:26         ` Michal Suchánek

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).