git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: "git merge" merges too much!

From
GWGreg A. Woods <woods@planix.com>
Date
Dec 1, 2009, 21:58 UTC
Message-ID
<m1NFak0-000kn2C@most.weird.com>
In-Reply-To
<20091201205057.GD11235@dpotapov.dyndns.org>
At Tue, 1 Dec 2009 23:50:57 +0300, Dmitry Potapov <dpotapov@gmail.com> wrote:
Subject: Re: "git merge" merges too much!
Show 20 quoted lines
> 
> > > 
> > > $ git branch new-foo foo
> > > 
> > > $ git rebase --onto newbase oldbase new-foo
> > 
> > Hmmm.... I'll have to think about that.  It makes some sense, but I
> > don't intuitively read the command-line parameters well enough to
> > predict the outcome in all of the scenarios I'm interested in.
> > 
> > what is "oldbase" there?  I'm guessing it means "base of foo" (and for
> > the moment, "new-foo" too)?
> 
> You have:
> 
>  o---o---o---o---o  newbase
>        \
>         o---o---o---o---o  oldbase
>                          \
>                           o---o---o  foo

Yes, sort of -- in the ideal situation, but not in my particular example where "oldbase" is just a tag, not a real branch.

So yes, "oldbase" is in fact "base of foo". Trickier still is when the "oldbase" branch has one or more commits newer then "base of foo". Does Git not have a symbolic name for the true base of a branch? I.e. is there not some form of symbolic name for "N" in the following?

   o---o---o---o---o---o---o---o  master
            \
             o---o---N---o---o  release-1
                      \
                       o---o---o  local-release-1

(now of course if it is discovered that "release-1" has progressed since the base of "foo" then "foo" should be rebased first, but perhaps there is not time to do this before the other release has to be supported)

Show 9 quoted lines
> and you want this:
> 
>  o---o---o---o---o  newbase
>      |            \
>      |             o'--o'--o'  new-foo
>       \
>        o---o---o---o---o  oldbase
>                          \
>                           o---o---o  foo
Yes, sort of I suppose, if you trim all the non-relevant branches.

What I really want, I think, is something like this where at least the non-relevant "master" branch is still shown:

                   1'--2'--3'  new-foo
                  /
         o---o---o  newbase
        /
   o---o---o---o---o---o---o---o  master
                \
                 o---o---o  oldbase
                          \
                           1---2---3  foo

Here's part of my confusion -- "newbase" as used above is actually older than "oldbase". :-) so ideally "oldbase" should always be described in terms of "foo", not just given an arbitrary unrelated name.

Of course that doesn't rule out the following scenario either where "newbase" really is newer than "oldbase" -- in my world a given project might become locally supported first on either a newer release, or an older release, so both above and below might happen:

                           1'--2'--3'  new-foo
                          /
                 o---o---o  newbase
                /
   o---o---o---o---o---o---o---o  master
        \
         o---o---o  oldbase
                  \
                   1---2---3  foo

And eventually I want to also merge whatever is still relevant from foo to a "local" branch off master so that those changes can be sent (usually as patches) upstream.

Sometimes I want to do development on a topic branch as close to the tip of "master" so that it can most easily be pushed upstream, and then back-port those changes to older release branches.

In fact the latter is exactly how I picture release branches to work in normal development, and this is how several of the big projects I'd like to get using Git are doing development (now usually with CVS).

Note too that in these kinds of projects "topic" branches are _always_ forked from the current tip of "master", long-running ones sometimes rebased to keep up with "master", small fixes and changes are made directly to the master branch; and small fixes, as well as relevant features, sometimes those developed on "topic" branches, are back-ported to release branches.

Note I'm not talking about ideals of best practises specific for Git here -- I'm talking about actual working operational practises that people are _very_ familiar with and which have been well proven using a vast wide variety of different VCS's in the past. For example I seriously doubt any of the developers of the projects I'm thinking of that I'd like to switch to using Git are ever going to want to fork their topic branches from the oldest release branch base that they intend to support, and many such projects will necessarily always have at least a few long-running topic branches that will have to be frequently rebased to keep up with the trunk so that their eventual merging will go as smoothly as possible, and yet once any of these topic branches is finally "closed" their changes may also have to be back-ported to release branches.

To me the natural way to do these kinds of back-porting "merges" is to restrict the merge to select only the commits on the branch, i.e. from its base to its tip, thus the motivation for the topic of my thread (and I think the motivation for the "What is the best way to backport a feature?" thread as well). I think if Git could do this kind of "partial" merging directly without having to "copy" deltas with "rebase" or "cherry-pick" or "am" or whatever, and thus create separate histories for them, then it would be much better at supporting this traditional practice of using branches to manage releases. Without such ability it truly does look as though some form of "patch" management tool is also a necessary thing(evil?), as "rebase" and "cherry-pick" could quickly get way out of control and be way too much work otherwise.

-- 
						Greg A. Woods
						Planix, Inc.

<woods@planix.com>       +1 416 218 0099        http://www.planix.com/
Previous: Dmitry PotapovNext: Dmitry Potapov
Message 7 of 33 in “"git merge" merges too much!”
  1. Greg A. WoodsNov 29, 2009
  2. Jeff KingNov 29, 2009
  3. Greg A. WoodsNov 30, 2009
  4. Dmitry PotapovNov 30, 2009
  5. Greg A. WoodsDec 1, 2009
  6. Dmitry PotapovDec 1, 2009
  7. Greg A. WoodsDec 1, 2009
  8. Dmitry PotapovDec 2, 2009
  9. Nanako ShiraishiDec 2, 2009
  10. Jeff KingDec 2, 2009
  11. Greg A. WoodsDec 3, 2009
  12. Junio C HamanoDec 3, 2009
  13. Greg A. WoodsDec 3, 2009
  14. Jeff KingDec 3, 2009
  15. Uri OkrentDec 3, 2009
  16. Marko KreenDec 3, 2009
  17. Greg A. WoodsDec 9, 2009
  18. Jeff KingDec 3, 2009
  19. Junio C HamanoNov 29, 2009
  20. Greg A. WoodsNov 30, 2009
  21. Junio C HamanoNov 30, 2009
  22. Dmitry PotapovNov 30, 2009
  23. Greg A. WoodsDec 1, 2009
  24. Dmitry PotapovDec 1, 2009
  25. Greg A. WoodsDec 1, 2009
  26. Dmitry PotapovDec 1, 2009
  27. Greg A. WoodsDec 1, 2009
  28. Dmitry PotapovDec 1, 2009
  29. Jeff EplerDec 1, 2009
  30. Greg A. WoodsDec 1, 2009
  31. Dmitry PotapovDec 2, 2009
  32. Greg A. WoodsDec 3, 2009
  33. Junio C HamanoDec 2, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.