* Preserving branches after merging on ancestor
@ 2009-11-05 18:30 Richard Lee
2009-11-05 18:38 ` Eric Raible
2009-11-05 22:30 ` Jonathan Nieder
0 siblings, 2 replies; 12+ messages in thread
From: Richard Lee @ 2009-11-05 18:30 UTC (permalink / raw)
To: git
Hello gits,
I've been using various version control systems for several years now before
coming to git two months ago. So far I've been just doing linear commits
without any branches on my source code so that I end up with a linear
history. This makes it very hard to see where you started and stopped
working on something on the git graph.
So I tried using branches for features today. Most of the time I'm the only
person working on a project. So when I've finished working on a feature
branch and ready to merge it back into the master branch, the master head IS
the common ancestor of the two branches. As shown below
* b6d75f1 [feature] stuff on feature branch
* 43dba08 stuff on feature branch
* ab7efdd [master] init
When I merge the graph looks likes this:
* b6d75f1 [master] [feature] stuff on feature branch
* 43dba08 stuff on feature branch
* ab7efdd init
Now I lose the start point of where I satrted on the feature branch. And if
I decided to reuse the name of the branch 'feature' to work on it again by
resetting it to somewhere else, I loose to finish point. (Should I be using
git-reset like this?)
One way of getting round this problem is to use empty commits on the master
branch, as shown below.
* 6fc04b5 Merge branch 'feature2'
|\
| * 07a117b stuff on feature2
* | 52f5ba1 Empty commit
|/
* 5deaa93 Merge branch 'feature1'
|\
| * b163b17 stuff on feature1
| * 53bb820 stuff on feature1
| * c9ef14c stuff on feature1
* | 34227a3 Empty commit
|/
* e88d332 Init
But is this correct? It seems rather hackish to create empty commits on the
master branch just to historically preserve commits on a seperate branch.
Should I be using feature branches in git like this or another way? For
example more informative commit messages.
I cannot imagine using this empty commits fix in other VCS if they don't
allow empty commits like svn or hg.
Cheers,
Richard
--
View this message in context: http://old.nabble.com/Preserving-branches-after-merging-on-ancestor-tp26217077p26217077.html
Sent from the git mailing list archive at Nabble.com.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-05 18:30 Preserving branches after merging on ancestor Richard Lee
@ 2009-11-05 18:38 ` Eric Raible
2009-11-05 22:30 ` Jonathan Nieder
1 sibling, 0 replies; 12+ messages in thread
From: Eric Raible @ 2009-11-05 18:38 UTC (permalink / raw)
To: git
Richard Lee <richard <at> webdezign.co.uk> writes:
> So I tried using branches for features today. Most of the time I'm the only
> person working on a project. So when I've finished working on a feature
> branch and ready to merge it back into the master branch, the master head IS
> the common ancestor of the two branches. As shown below
>
> * b6d75f1 [feature] stuff on feature branch
> * 43dba08 stuff on feature branch
> * ab7efdd [master] init
>
> When I merge the graph looks likes this:
>
> * b6d75f1 [master] [feature] stuff on feature branch
> * 43dba08 stuff on feature branch
> * ab7efdd init
You're getting a so-called "fast-forward" merge,
which is the default. Turn it off with:
git merge --no-ff
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-05 18:30 Preserving branches after merging on ancestor Richard Lee
2009-11-05 18:38 ` Eric Raible
@ 2009-11-05 22:30 ` Jonathan Nieder
2009-11-05 23:28 ` Björn Steinbrink
1 sibling, 1 reply; 12+ messages in thread
From: Jonathan Nieder @ 2009-11-05 22:30 UTC (permalink / raw)
To: Richard Lee; +Cc: git
Hi Richard,
Richard Lee wrote:
> One way of getting round this problem is to use empty commits on the master
> branch, as shown below.
>
> * 6fc04b5 Merge branch 'feature2'
> |\
> | * 07a117b stuff on feature2
> * | 52f5ba1 Empty commit
> |/
> * 5deaa93 Merge branch 'feature1'
> |\
> | * b163b17 stuff on feature1
> | * 53bb820 stuff on feature1
> | * c9ef14c stuff on feature1
> * | 34227a3 Empty commit
> |/
> * e88d332 Init
>
> But is this correct? It seems rather hackish to create empty commits on the
> master branch just to historically preserve commits on a seperate branch.
> Should I be using feature branches in git like this or another way? For
> example more informative commit messages.
As Eric said, you can avoid the empty commits by passing 'git merge'
the --no-ff option, which would give the history I think you intend:
* 26749ab Merge branch 'feature2'
|\
| * b9cd8ff stuff on feature2
|/
* 829ba2c Merge branch 'feature1'
|\
| * b163b17 stuff on feature1
| * 53bb820 stuff on feature1
| * c9ef14c stuff on feature1
|/
* e88d332 Init
But doing this misses some of the main benefits of feature branches
imho.
If you base each feature branch on the stable release or features it
depends on instead, this gives you the freedom to merge one feature without
the others to another branch. For example:
# wouldn’t feature1 be neat? let me try it.
git checkout -b feature1 v1.0
hack hack hack
# looks good.
git commit -a
# how about an unrelated feature2?
git checkout -b feature2 v1.0
hack hack hack
# looks good.
git commit -a
# but do they work?
git checkout v1.0; # detach head for testing [1]
git merge feature1 feature2
make check
# hmm, these don’t seem to work well together
... (investigating some more)
# looks like feature1 is not ready for prime time
# so let’s just use feature2 for now.
git checkout master
git merge feature2
git branch -d feature2
make check
# looks good; better publish it.
git push origin master
v1.0 --- feature1
\
\-- feature2 [master]
As a nice side-effect, if you work this way then you can develop
feature2 without being distracted by new bugs introduced by feature1.
With many features built this way, the revision graph starts to give
some hints about relationships between features developed around the
same time. For example, with the history
v1.0 --- feature1 --- feature2 -- feature4 -- feature6 - v1.1
\ /
-- feature5 ------------
feature4 and feature5 are not likely to be closely related, but
feature4 and feature6 might be. The exact history of merges is less
important than the general "shape" of the graph.
Thanks for the food for thought.
Hope that helps,
Jonathan
[1] See <http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html#_detached_head>.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-05 22:30 ` Jonathan Nieder
@ 2009-11-05 23:28 ` Björn Steinbrink
2009-11-06 1:09 ` Jonathan Nieder
0 siblings, 1 reply; 12+ messages in thread
From: Björn Steinbrink @ 2009-11-05 23:28 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Richard Lee, git
On 2009.11.05 16:30:04 -0600, Jonathan Nieder wrote:
> But doing this misses some of the main benefits of feature branches
> imho.
>
> If you base each feature branch on the stable release or features it
> depends on instead, this gives you the freedom to merge one feature without
> the others to another branch.
I guess Richard took the "branch topic1, merge topic1, branch topic2,
merge topic2" thing just as an example because that ends up with two
fast-forwards. And your example _still_ has such a fast-forward.
> For example:
>
> # wouldn’t feature1 be neat? let me try it.
> git checkout -b feature1 v1.0
> hack hack hack
> # looks good.
> git commit -a
>
> # how about an unrelated feature2?
> git checkout -b feature2 v1.0
> hack hack hack
> # looks good.
> git commit -a
>
> # but do they work?
> git checkout v1.0; # detach head for testing [1]
> git merge feature1 feature2
> make check
> # hmm, these don’t seem to work well together
> ... (investigating some more)
>
> # looks like feature1 is not ready for prime time
> # so let’s just use feature2 for now.
> git checkout master
> git merge feature2
> git branch -d feature2
> make check
> # looks good; better publish it.
> git push origin master
>
> v1.0 --- feature1
> \
> \-- feature2 [master]
And here you got a fast-forward of master to feature2, i.e. linear
history, which is what Richard was trying to avoid.
Instead of:
A---B---C---D---E (topic2) (master)
\
F---G---H (topic1)
He wants:
F---G---H (topic1)
/
A---B-----------M (master)
\ /
C---D---E (topic2)
So he can see at which point topic2 got merged. This allows to ask "which
commits got merged here" (and for a merge-once topic branch this means:
Which commits are related to that topic), by using for example:
git log M^1..M^2 # Will show C, D and E
In the fast-forward case, there's no way to get that without manually
figuring out where the topic branch started.
Björn
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-05 23:28 ` Björn Steinbrink
@ 2009-11-06 1:09 ` Jonathan Nieder
2009-11-06 2:10 ` Björn Steinbrink
0 siblings, 1 reply; 12+ messages in thread
From: Jonathan Nieder @ 2009-11-06 1:09 UTC (permalink / raw)
To: Björn Steinbrink; +Cc: Richard Lee, git
Björn Steinbrink wrote:
> I guess Richard took the "branch topic1, merge topic1, branch topic2,
> merge topic2" thing just as an example because that ends up with two
> fast-forwards.
Hmm, I found Richard’s example pretty realistic. I used to work like
that, and I don’t think I am the only one.
> And your example _still_ has such a fast-forward.
Yep, if you really want to avoid fast-forwards, please use "--no-ff"!
But what I was trying to make clear was that in some workflows, the
fast-forwards are not so harmful. They even make the history a little
cleaner (easier to read and understand).
> Instead of:
>
> A---B---C---D---E (topic2) (master)
> \
> F---G---H (topic1)
>
> He wants:
>
> F---G---H (topic1)
> /
> A---B-----------M (master)
> \ /
> C---D---E (topic2)
>
> So he can see at which point topic2 got merged. This allows to ask "which
> commits got merged here" (and for a merge-once topic branch this means:
> Which commits are related to that topic), by using for example:
>
> git log M^1..M^2 # Will show C, D and E
You can get the same information locally even with a fast-forward:
git log master@{1}..master
But to someone reading the published history, it is not available.
Depending on your way of working, this may or may not be reasonable.
Perhaps your merge commit messages contain important information about
the branch’s overall purpose and provenance, which would be impossible
if there is no merge commit.
On the other hand, if the goal is just to present the fact of a merge,
to explain where a patch falls in the larger scheme of things, then
how large a chunk of changes I decided to call a feature does not seem
too important.
Imagine a patch series, cleaning up some ugly code that has been
bothering me for a while:
base [master] --- A --- B --- C [cleanup]
It looks good, so I merge to master with --no-ff.
base --------- D [master]
\ /
A---B---C [cleanup]
Looking at that code inspires me to build a new feature that is much
easier with the cleaned up version. So I fork a branch from cleanup
(Or master? Their content is the same, but somehow I choose one) and
write some patches for the new feature.
base --------- D [master]
\ /
A---B---C [cleanup] --- E --- F --- G
It looks good, so I merge.
base --------- D --------- H [master]
\ / /
A---B---C---E---F---G
Is this really any easier to read than base---A---B---C---E---F---G?
In hindsight, was this logically really two series, or is the D commit
extra cruft?
Almost always, a fast-forward comes from a continuation of this kind,
since that is what it means for a commit to be the logical commit to
fork from.
Of course, these things are a matter of taste. I just wanted to
explain why a fast-forward could at least sometimes be the right
result from merging a topic branch (and why, in practice, some people
never end up needing to use --no-ff).
Regards,
Jonathan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-06 1:09 ` Jonathan Nieder
@ 2009-11-06 2:10 ` Björn Steinbrink
2009-11-06 5:03 ` Jonathan Nieder
0 siblings, 1 reply; 12+ messages in thread
From: Björn Steinbrink @ 2009-11-06 2:10 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Richard Lee, git
On 2009.11.05 19:09:48 -0600, Jonathan Nieder wrote:
> Björn Steinbrink wrote:
>
> > I guess Richard took the "branch topic1, merge topic1, branch topic2,
> > merge topic2" thing just as an example because that ends up with two
> > fast-forwards.
>
> Hmm, I found Richard’s example pretty realistic. I used to work like
> that, and I don’t think I am the only one.
>
> > And your example _still_ has such a fast-forward.
>
> Yep, if you really want to avoid fast-forwards, please use "--no-ff"!
>
> But what I was trying to make clear was that in some workflows, the
> fast-forwards are not so harmful. They even make the history a little
> cleaner (easier to read and understand).
>
> > Instead of:
> >
> > A---B---C---D---E (topic2) (master)
> > \
> > F---G---H (topic1)
> >
> > He wants:
> >
> > F---G---H (topic1)
> > /
> > A---B-----------M (master)
> > \ /
> > C---D---E (topic2)
> >
> > So he can see at which point topic2 got merged. This allows to ask "which
> > commits got merged here" (and for a merge-once topic branch this means:
> > Which commits are related to that topic), by using for example:
> >
> > git log M^1..M^2 # Will show C, D and E
>
> You can get the same information locally even with a fast-forward:
>
> git log master@{1}..master
And after two weeks, you'll dig through the reflog to find the right
entries? Come on... And (as you said yourself below) everyone else
(including yourself in a different clone of that repo) doesn't have that
reflog entry anyway.
> But to someone reading the published history, it is not available.
> Depending on your way of working, this may or may not be reasonable.
>
> Perhaps your merge commit messages contain important information about
> the branch’s overall purpose and provenance, which would be impossible
> if there is no merge commit.
The actual commits that make up the topic should have descriptive enough
commit messages to make extra "why merge this" messages shouldn't be
required. But merge commits provide a way of giving a high-level
overview of the history of a project.
> On the other hand, if the goal is just to present the fact of a merge,
> to explain where a patch falls in the larger scheme of things, then
> how large a chunk of changes I decided to call a feature does not seem
> too important.
For example in git.git, I can do "git log --first-parent
..origin/master" to get a high-level log of what happened. And then I
might see commit b7eb912b0, which is "Merge branch ja/fetch-doc". So I
know "OK, there were some doc updates", without having to crawl through
the individual commits.
And if I decide that for _this_ topic, I care to see what got merged, I
can do: git log b7eb912b0^1..b7eb912b0^2
Had this been a fast-forward, even the --first-parent history would
throw the individual commits at me, giving me less of a high-level
overview.
> Imagine a patch series, cleaning up some ugly code that has been
> bothering me for a while:
>
> base [master] --- A --- B --- C [cleanup]
>
> It looks good, so I merge to master with --no-ff.
>
> base --------- D [master]
> \ /
> A---B---C [cleanup]
>
> Looking at that code inspires me to build a new feature that is much
> easier with the cleaned up version. So I fork a branch from cleanup
> (Or master? Their content is the same, but somehow I choose one) and
> write some patches for the new feature.
>
> base --------- D [master]
> \ /
> A---B---C [cleanup] --- E --- F --- G
>
> It looks good, so I merge.
>
> base --------- D --------- H [master]
> \ / /
> A---B---C---E---F---G
>
> Is this really any easier to read than base---A---B---C---E---F---G?
> In hindsight, was this logically really two series, or is the D commit
> extra cruft?
Choosing "cleanup" as the starting point for an unrelated topic branch
(after all "cleanup" was already merged, so there's absolutely no reason
to base a new topic on it) is wrong. That history looks as if E,F,G was
a second part of the same topic branch.
I'd have done:
E---F---G (topic2)
/ \
0-----------D-----------H (master)
\ /
A---B---C (cleanup)
And then I could do "git log --first-parent master" to see H and D
(high-level view), and "git log H^1..H^2" or "git log D^1..D^2" to get a
low-level view at the merged topics.
Neither of which I could do with "0---A---B---C---E---F---G". With that,
I'd have to manually looking up the start/end points of each topic.
> Almost always, a fast-forward comes from a continuation of this kind,
> since that is what it means for a commit to be the logical commit to
> fork from.
Hm? I don't get that one. The "continuation" would be that you started
the second topic branch from the first topic branch, right? And that
caused the merge to "master" _not_ to be a fast-forward. So I'm somewhat
confused there.
> Of course, these things are a matter of taste. I just wanted to
> explain why a fast-forward could at least sometimes be the right
> result from merging a topic branch (and why, in practice, some people
> never end up needing to use --no-ff).
Sure, fast-forwards can be the right thing, e.g. when you have a
(possibly useless) branch head "master" that you update by pulling. In
such a case merge commits would only lead to useless clutter. But
Richard wants to see where topic branches got merged (to be still able
to see what got merged in the future), and yeah, that's a matter of
taste. But you argued that using --no-ff would "[miss] some of the main
benefits of feature branches", which is simply not true.
Björn
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-06 2:10 ` Björn Steinbrink
@ 2009-11-06 5:03 ` Jonathan Nieder
2009-11-06 15:21 ` rhlee
0 siblings, 1 reply; 12+ messages in thread
From: Jonathan Nieder @ 2009-11-06 5:03 UTC (permalink / raw)
To: Björn Steinbrink; +Cc: Richard Lee, git
Björn Steinbrink wrote:
> For example in git.git, I can do "git log --first-parent
> ..origin/master" to get a high-level log of what happened. And then I
> might see commit b7eb912b0, which is "Merge branch ja/fetch-doc". So I
> know "OK, there were some doc updates", without having to crawl through
> the individual commits.
Yep, fast-forward merges do ruin the --first-parent log. Thanks for
the reminder.
>> Of course, these things are a matter of taste. I just wanted to
>> explain why a fast-forward could at least sometimes be the right
>> result from merging a topic branch (and why, in practice, some people
>> never end up needing to use --no-ff).
>
> Sure, fast-forwards can be the right thing, e.g. when you have a
> (possibly useless) branch head "master" that you update by pulling. In
> such a case merge commits would only lead to useless clutter.
I hope this use case becomes less important as git’s UI improves. To
track unmodified upstream sources, a simple 'git checkout' to get
up-to-date is much simpler, except that "git branch" does not display
the current branch any more. Using 'git pull' for the daily update
makes for a distractingly merge-heavy history once one has commits of
one’s own.
A similar use case won’t disappear: asking someone else to resolve a
merge for you and pulling the result.
For both these tasks, --ff-only might give better behavior.
In other cases, I would guess some people would always want --no-ff
and others never. Apparently, there is a configuration option to
support this: add a line "mergeoptions = --no-ff" (or "mergeoptions =
--ff") to a [branch "master"] section in .git/config or ~/.gitconfig.
> But
> Richard wants to see where topic branches got merged (to be still able
> to see what got merged in the future), and yeah, that's a matter of
> taste. But you argued that using --no-ff would "[miss] some of the main
> benefits of feature branches", which is simply not true.
I spoke imprecisely; I should have said that if most merges are
candidates for fast-forwarding, this suggests feature branches are not
being used in the best way, and --no-ff just makes that situation more
tolerable.
Then your response pushed me towards the question of whether --no-ff
is a good idea in general, and I got distracted. :) Sorry for the
confusion, and thanks for the insights.
Regards,
Jonathan
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-06 5:03 ` Jonathan Nieder
@ 2009-11-06 15:21 ` rhlee
2009-11-06 22:52 ` Jonathan Nieder
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: rhlee @ 2009-11-06 15:21 UTC (permalink / raw)
To: git
Hi John, Björn and Eric,
Thank you very much for your replies from which I gained a lot insight about
git merging and different workflows.
Yes, I have tried out --no-ff and it does the job for me. (Incidentally,
doing that take it look neater in git gui as all the master nodes appear on
top of each other. Using empty commits, the merged branches appear on top
the master nodes in the graph.)
Jonathan Nieder-2 wrote:
>
> Then your response pushed me towards the question of whether --no-ff is a
> good idea in general
>
John, I get the feeling from what you say in general that fast forwards are
default behaviour for merges for a reason and by using the --no-ff option I
am making my workflow and git history uncessesarily awkward and working
against best practices?
Jonathan Nieder-2 wrote:
>
>> I guess Richard took the "branch topic1, merge topic1, branch topic2,
>> merge topic2" thing just as an example because that ends up with two
>> fast-forwards.
>
> Hmm, I found Richard’s example pretty realistic. I used to work like
> that, and I don’t think I am the only one.
>
I'm not saying there is any one "right" workflow. But is there a more
suitable workflow than than "branch topic1, merge topic1, branch topic2,
merge topic2"?
Thanks,
Richard
--
View this message in context: http://n2.nabble.com/Preserving-branches-after-merging-on-ancestor-tp3954131p3959325.html
Sent from the git mailing list archive at Nabble.com.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-06 15:21 ` rhlee
@ 2009-11-06 22:52 ` Jonathan Nieder
2009-11-07 3:41 ` Dilip M
2009-11-07 13:28 ` Björn Steinbrink
2 siblings, 0 replies; 12+ messages in thread
From: Jonathan Nieder @ 2009-11-06 22:52 UTC (permalink / raw)
To: Richard Lee; +Cc: Björn Steinbrink, Eric Raible, git
Richard Lee wrote:
> Jonathan Nieder wrote:
>> Then your response pushed me towards the question of whether --no-ff is a
>> good idea in general
>>
>
> John, I get the feeling from what you say in general that fast forwards are
> default behaviour for merges for a reason and by using the --no-ff option I
> am making my workflow and git history uncessesarily awkward and working
> against best practices?
Well, no. Some of us (read: I) just haven’t figured out yet how to fit the
--no-ff option into a broader workflow yet. It is only two years old. :)
There are pros and cons to using --no-ff to merge topic branches. Pros:
* 'git log --first-parent' will give the list of topics now.
* The beginning and end of each topic is not forgotten by a clone any
more.
Cons:
* The perceived beginning and end of a topic might be irrelevant or
misleading.
* Every topic needs a good name. :)
* More commits for a person looking through the history to deal with.
A merge commit from a would-be fast-forward records content identical
to its second parent, and it is not necessary as glue to tie the
content-changing commits together any more.
After thinking about it a little, the pros seem to far outweight the cons.
>> Björn Steinbrink wrote:
>>
>>> I guess Richard took the "branch topic1, merge topic1, branch topic2,
>>> merge topic2" thing just as an example because that ends up with two
>>> fast-forwards.
>>
>> Hmm, I found Richard’s example pretty realistic. I used to work like
>> that, and I don’t think I am the only one.
>>
>
> I'm not saying there is any one "right" workflow. But is there a more
> suitable workflow than than "branch topic1, merge topic1, branch topic2,
> merge topic2"?
Yes, in my opinion. I prefer to branch topic1, branch topic2, ...
and only later (after some time to reflect) decide which topics to
merge. For this to work, each topic should not have all previous
topics as ancestors, or there is no way to postpone merging any one.
This is especially nice when a topic turns into a long-term project.
By not merging in the partial work, I keep the code in the master
branch a little cleaner, but more importantly, bugs in the partial
work do not interfere with work on other topics. Once it is finally
time to merge the topic back to master, it is in one clean merge, and
all the commits are together for someone looking at the history.
“What about testing?” one might ask. “How can I tell when it is safe
to merge the topic to master, when the topic and other features since
then might work well separately but not together?” The “Throw-away
integration” section in gitworkflows(7) [1] discusses how to deal with
this.
Taking the idea of forking from the oldest relevant commit to an
extreme in a single-person project, you can end up with history like
this:
initial---------------final
\ /|
\---A-------/ |
\ / /|
\---B---/ / |
\ / |
\---C-- |
\ /
\--D---
\
-E- ...
i.e., full of octopus merges and basically unreadable in gitk.
Arguably, this is at least partially a gitk bug. [Aside: a dream
feature for gitk would be to give the --first-parent history at first
and then fill in topics when the user requests them. That is, in this
example, it would show
initial---final
but after a click on the parent A, it would show
initial---final
\ /
A
and so on.] To avoid this, it is best not defer merging topics into
the mainline for too long, and to base each topic branch not on the
oldest relevant commit but on the tip of the oldest branch it might be
merged to (which in the simplest case is usually the mainline).
A single person has a lot of control over the shape of the history,
so that it is easy to make it totally linear or sequence of enormous
octopuses. The nicest history for others to read, I think, is that
most like one created by many people in a healthy project. But that’s
a hard ideal to achieve, and more important than crafting well shaped
history is to write good code, so it is not worth obsessing over.
I hope that is a little clearer.
Regards,
Jonathan
[1] http://www.kernel.org/pub/software/scm/git/docs/gitworkflows.html#_throw_away_integration
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-06 15:21 ` rhlee
2009-11-06 22:52 ` Jonathan Nieder
@ 2009-11-07 3:41 ` Dilip M
2009-11-07 13:31 ` Björn Steinbrink
2009-11-07 13:28 ` Björn Steinbrink
2 siblings, 1 reply; 12+ messages in thread
From: Dilip M @ 2009-11-07 3:41 UTC (permalink / raw)
To: rhlee; +Cc: git
On Fri, Nov 6, 2009 at 8:51 PM, rhlee <richard@webdezign.co.uk> wrote:
> Hi John, Björn and Eric,
>
> Thank you very much for your replies from which I gained a lot insight about
> git merging and different workflows.
>
> Yes, I have tried out --no-ff and it does the job for me. (Incidentally, doing
> that take it look neater in git gui as all the master nodes appear on top of
> each other. Using empty commits, the merged branches appear on top the master
> nodes in the graph.)
Thanks to Richard, John, Björn, and Eric.
I had a similar _confusion_ looking looking at graph. I always use "log --graph
--pretty=oneline". Now I have _opted_ to pull/merge with '--no-ff', to keep the
graph plain and simple for non-power users :)
-- Dilip
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-06 15:21 ` rhlee
2009-11-06 22:52 ` Jonathan Nieder
2009-11-07 3:41 ` Dilip M
@ 2009-11-07 13:28 ` Björn Steinbrink
2 siblings, 0 replies; 12+ messages in thread
From: Björn Steinbrink @ 2009-11-07 13:28 UTC (permalink / raw)
To: rhlee; +Cc: git
On 2009.11.06 07:21:17 -0800, rhlee wrote:
> Jonathan Nieder-2 wrote:
> >
> > Then your response pushed me towards the question of whether --no-ff is a
> > good idea in general
> >
>
> John, I get the feeling from what you say in general that fast forwards are
> default behaviour for merges for a reason and by using the --no-ff option I
> am making my workflow and git history uncessesarily awkward and working
> against best practices?
As Jonathan already said, there are pros and cons when the merge is
about merging topic branches to some "main" branch. In addition to that,
working with git often also involves other merges. For example, you
might have your private topic branch, on which you work on two different
boxes. So you push your topic branch to some private bare repo, fetch it
from the other box, work there, and push the result back to the bare
repo. And then, in the "original" repo, you of course want to update
your local branch head to reflect the new changes. So you fetch and
merge, but you really don't want a merge commit in that case, but the
default fast-forward behaviour. In some sense, that kind of "merge", is
more like an "update", for which the fast-forward behaviour is simply
better.
> Jonathan Nieder-2 wrote:
> >
> >> I guess Richard took the "branch topic1, merge topic1, branch topic2,
> >> merge topic2" thing just as an example because that ends up with two
> >> fast-forwards.
> >
> > Hmm, I found Richard’s example pretty realistic. I used to work like
> > that, and I don’t think I am the only one.
> >
>
> I'm not saying there is any one "right" workflow. But is there a more
> suitable workflow than than "branch topic1, merge topic1, branch topic2,
> merge topic2"?
That order of commands looks like a strict "Start a topic, finish a
topic, merge it, start next topic, ..." workflow. And that severely
limits what you can do, as you're forced to work on only one thing and
to finish it first before starting something else. Such a strict
workflow basically makes branching pointless. I often do things like:
git checkout -b new_feature master
*work & commit*
*get a bug report about the stable version*
git checkout -b bug_fix_foo maint
*work & commit*
*get a report about a trivial bug on master*
git checkout master
*fix bug & commit* # Yes, directly on master
git push
git checkout bug_fix_foo
*finish the bug_fix*
git checkout maint
git merge bug_fix_foo # Merge the bugfix to the oldest branch it applies to
git checkout master
git merge maint # Merge bugfixes forward to the more recent branches
git push
git checkout new_feature
*finish feature*
git checkout master
git merge new_feature
git push
So I could work on multiple things at the same time, and even merged
them in reverse order, compared to the order in which I started the
branches. It's just the strict "start, finish, merge, start next, ..."
order that looks suspicious, but that's totally unrelated to the --no-ff
thing. Even when working on multiple branches and merging them in a
random order, you can hit a fast-forward for the "first" merge.
Björn
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Preserving branches after merging on ancestor
2009-11-07 3:41 ` Dilip M
@ 2009-11-07 13:31 ` Björn Steinbrink
0 siblings, 0 replies; 12+ messages in thread
From: Björn Steinbrink @ 2009-11-07 13:31 UTC (permalink / raw)
To: Dilip M; +Cc: rhlee, git
On 2009.11.07 09:11:11 +0530, Dilip M wrote:
> On Fri, Nov 6, 2009 at 8:51 PM, rhlee <richard@webdezign.co.uk> wrote:
>
> > Hi John, Björn and Eric,
> >
> > Thank you very much for your replies from which I gained a lot
> > insight about git merging and different workflows.
> >
> > Yes, I have tried out --no-ff and it does the job for me.
> > (Incidentally, doing that take it look neater in git gui as all the
> > master nodes appear on top of each other. Using empty commits, the
> > merged branches appear on top the master nodes in the graph.)
>
> Thanks to Richard, John, Björn, and Eric.
>
> I had a similar _confusion_ looking looking at graph. I always use
> "log --graph --pretty=oneline". Now I have _opted_ to pull/merge with
> '--no-ff', to keep the graph plain and simple for non-power users :)
Just be careful with that. There are situations in which you clearly
don't want --no-ff, see the "working on a topic branch on multiple
boxes" example I gave in the mail I sent a minute ago. ;-)
Björn
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2009-11-07 13:31 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-05 18:30 Preserving branches after merging on ancestor Richard Lee
2009-11-05 18:38 ` Eric Raible
2009-11-05 22:30 ` Jonathan Nieder
2009-11-05 23:28 ` Björn Steinbrink
2009-11-06 1:09 ` Jonathan Nieder
2009-11-06 2:10 ` Björn Steinbrink
2009-11-06 5:03 ` Jonathan Nieder
2009-11-06 15:21 ` rhlee
2009-11-06 22:52 ` Jonathan Nieder
2009-11-07 3:41 ` Dilip M
2009-11-07 13:31 ` Björn Steinbrink
2009-11-07 13:28 ` Björn Steinbrink
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox