[git-users] Re: Forward-porting commits - merge or rebase?

2012-05-11 Thread Thomas Ferris Nicolaisen
I've wondered about this as well.. Here are my thoughts:


   - I think it is healthy to keep features that are going to multiple 
   branches developed in features branches. Upon completion, the feature can 
   be merged to any branch where it is needed
   - The feature branches should be based on the common ancestor of the 
   branches it will be merged to (you can find this with git merge-base 
   master exp). I think this makes for the least possible friction when 
   merging to the various branches.

Aside from that, if we have some fixes that have gone directly into master 
branch, and we need these in the exp branch, I think the right thing to do 
is to merge master into the exp branch. It does feel a bit weird, but I 
asked around on the #git IRC channel, and they said there's no reason not 
to do so when needed.

I don't think it should be done too often though, as it does clutter the 
history a bit. Merged latest changes from master doesn't tell the reader 
much about what this commit was for.



On Friday, May 11, 2012 1:24:07 PM UTC+2, Nikos Chantziaras wrote:

 Hello.

 I'm a bit puzzled on how to best forward-port commits from a stable branch 
 (master in this case), to my experimental branch (let's call it exp).  
 Both branches are pushed to a public repo.  Work that goes on in master 
 should be forward-ported to exp (I prefer forward-porting rather than 
 back-porting; that is, working on master and porting the commits to exp is 
 preferable to working on exp and porting the commits back to master.)

 What's the best way to deal with that?  Should I use rebase to apply the 
 commits from master to exp, or should I merge them?  I tried rebase in my 
 local repo (I pushed nothing to the public repo yet), but I'm not sure I 
 understand what's going on :-P  Yes, I've read Scott Chacon's awesome Git 
 tutorial, but it talks about rebasing local branches, that were never 
 pushed to a public repo, back to master.  My case is different; both 
 branches are on the public repo, while the commits made to master are not 
 yet pushed anywhere, and it's with those unpushed commits where I'm not 
 sure whether to merge or rebase to exp.


-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/git-users/-/M-gtkqW5tfMJ.
To post to this group, send email to git-users@googlegroups.com.
To unsubscribe from this group, send email to 
git-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/git-users?hl=en.



Re: [git-users] Forward-porting commits - merge or rebase?

2012-05-11 Thread Nikos Chantziaras

On 11/05/12 16:36, Konstantin Khomoutov wrote:

On Fri, 11 May 2012 04:24:07 -0700 (PDT)
Nikos Chantziarasrea...@gmail.com  wrote:


I'm a bit puzzled on how to best forward-port commits from a stable
branch (master in this case), to my experimental branch (let's call
it exp). Both branches are pushed to a public repo.  Work that goes
on in master should be forward-ported to exp [...]

What's the best way to deal with that?  Should I use rebase to apply
the commits from master to exp, or should I merge them? [...]


[...]
The consequence is that if you push a branch containing commits
...-A-B-C
(with C being the tip commit) to a public repo, then rebase these three
commits to produce
...-A'-B'-C'
and push it again (this would require a forced push), everyone who
happened to fetch the original state of your branch and base their work
on it (on the commit C, that is) will have pain in the neck when their
next fetch from your repo will suddenly replace a series of tip commits
on that branch.  Everyone will be required to rebase their work in
turn, to follow your rebase.


I don't want to push something that would require others to rebase.  But 
from the Pro Git book, in the 3.6 Rebasing section, I had this in mind:


  Do not rebase commits that you have pushed to a public repository.
  If you follow that guideline, you’ll be fine.

And indeed the commits I'm talking about have *not* been pushed to a 
public repository; I just made those commits in master.  So my first 
impression was that there would be no problem.  But it seems I didn't 
understand what rebase really means.  I now understand that when the 
book says do not rebase pushed commits, it does not mean the commits I 
just made in master and want to rebase them to exp.  It means all the 
commits in exp.  Did I get that right now?


Btw, in case you're also using Mercurial, my workflow there is:

  * make a commit in master
  * hg export that commit
  * switch to the exp branch
  * hg import the commit

This would be merge in Git rather than rebase, right?

--
You received this message because you are subscribed to the Google Groups Git for 
human beings group.
To post to this group, send email to git-users@googlegroups.com.
To unsubscribe from this group, send email to 
git-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/git-users?hl=en.



Re: [git-users] Forward-porting commits - merge or rebase?

2012-05-11 Thread Konstantin Khomoutov
On Fri, 11 May 2012 18:35:03 +0300
Nikos Chantziaras rea...@gmail.com wrote:

[...]
  The consequence is that if you push a branch containing commits
  ...-A-B-C
  (with C being the tip commit) to a public repo, then rebase these
  three commits to produce
  ...-A'-B'-C'
  and push it again (this would require a forced push), everyone who
  happened to fetch the original state of your branch and base their
  work on it (on the commit C, that is) will have pain in the neck
  when their next fetch from your repo will suddenly replace a series
  of tip commits on that branch.  Everyone will be required to rebase
  their work in turn, to follow your rebase.
 
 I don't want to push something that would require others to rebase.
 But from the Pro Git book, in the 3.6 Rebasing section, I had this
 in mind:
 
Do not rebase commits that you have pushed to a public repository.
If you follow that guideline, you’ll be fine.
 
 And indeed the commits I'm talking about have *not* been pushed to a 
 public repository; I just made those commits in master.  So my first 
 impression was that there would be no problem.  But it seems I didn't 
 understand what rebase really means.  I now understand that when
 the book says do not rebase pushed commits, it does not mean the
 commits I just made in master and want to rebase them to exp.  It
 means all the commits in exp.  Did I get that right now?
No, you got it right the first time, that is, your first impression
was correct. :-)

The idea with rebasing is that you can rebase any series of commits
(ending with the branch's tip commit) on top of technically any other
series of commit.  You do not have to rebase the whole branch.  To
rebase a branch is just a popular way to spell it, but it's not
technically perfect: you usually rebase just some series of commits
near the tip of a branch, and usually this series starts right after
the commit which is a common ancestor of both branches.  Of course,
there's very little sense to rebase a series of commits onto something
completely irrelevant and so the typical case for rebasing is like this:

You have a branch, say, master, which looks like this:
...-A-B-C
that is, it ends with commit C.

You fork another branch, exp, off of it. Initially it looks exactly
the same:
...-A-B-C

Now you put commit X, and Y on exp, so it now looks this way:
...-A-B-C-X-Y

In the meantime you committed M an N on master, so it looks like this:
...-A-B-C-M-N

And now you want to pretend that X and Y on exp were made relative to
the *current* tip of master, which is now N (as opposed to it being C
at the time exp was forked off of it).
Observe that C is what's called the common ancestor for both the
involved branches here.
So you rebase the series X-Y in exp onto master, and exp starts to
look like this:
...-A-B-C-M-N-X'-Y'
(And the common ancestor is now N.)

Here, we changed the base of the series X-Y to be N instead of C.

The problem with rebasing and a public repo would only appear here if
you would have managed to push exp into that public repo after
committing X or Y.  If the exp branch ends in C in the remote repo,
it's fine to rebase X-Y in your local version of exp.

 Btw, in case you're also using Mercurial, my workflow there is:
 
* make a commit in master
* hg export that commit
* switch to the exp branch
* hg import the commit
 
 This would be merge in Git rather than rebase, right?
Uh, I don't quite follow.
Merge commits in Git happen only when you run `git merge` or something
which ultimately calls `git merge` (`git pull` might do this for
instance).
From what I read in `hg import` manual, the closest thing in Git would
be `git format-patch` + `git am`.  Also `git cherry-pick` is able to
pick arbitrary commit (or a series of them) and apply it/them to the
current branch.
Rebasing in Git is used for a bit different need as I tried to
explain above.

-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To post to this group, send email to git-users@googlegroups.com.
To unsubscribe from this group, send email to 
git-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/git-users?hl=en.



Re: [git-users] Forward-porting commits - merge or rebase?

2012-05-11 Thread Nikos Chantziaras

On 11/05/12 19:38, Konstantin Khomoutov wrote:

On Fri, 11 May 2012 18:35:03 +0300
Nikos Chantziarasrea...@gmail.com  wrote:

[...]

I don't want to push something that would require others to rebase.
But from the Pro Git book, in the 3.6 Rebasing section, I had this
in mind:

Do not rebase commits that you have pushed to a public repository.
If you follow that guideline, you’ll be fine.

And indeed the commits I'm talking about have *not* been pushed to a
public repository; I just made those commits in master.  So my first
impression was that there would be no problem.  But it seems I didn't
understand what rebase really means.  I now understand that when
the book says do not rebase pushed commits, it does not mean the
commits I just made in master and want to rebase them to exp.  It
means all the commits in exp.  Did I get that right now?


No, you got it right the first time, that is, your first impression
was correct. :-)


Now I'm confused.  See below.



The idea with rebasing is that you can rebase any series of commits
(ending with the branch's tip commit) on top of technically any other
series of commit.  You do not have to rebase the whole branch.  To
rebase a branch is just a popular way to spell it, but it's not
technically perfect: you usually rebase just some series of commits
near the tip of a branch, and usually this series starts right after
the commit which is a common ancestor of both branches.  Of course,
there's very little sense to rebase a series of commits onto something
completely irrelevant and so the typical case for rebasing is like this:

You have a branch, say, master, which looks like this:
...-A-B-C
that is, it ends with commit C.

You fork another branch, exp, off of it. Initially it looks exactly
the same:
...-A-B-C

Now you put commit X, and Y on exp, so it now looks this way:
...-A-B-C-X-Y

In the meantime you committed M an N on master, so it looks like this:
...-A-B-C-M-N

And now you want to pretend that X and Y on exp were made relative to
the *current* tip of master, which is now N (as opposed to it being C
at the time exp was forked off of it).
Observe that C is what's called the common ancestor for both the
involved branches here.
So you rebase the series X-Y in exp onto master, and exp starts to
look like this:
...-A-B-C-M-N-X'-Y'
(And the common ancestor is now N.)


This is why I'm confused now.  If I understood it right the first time, 
I am rebasing M and N.  But here you say that X and Y are getting rebased.




The problem with rebasing and a public repo would only appear here if
you would have managed to push exp into that public repo after
committing X or Y.  If the exp branch ends in C in the remote repo,
it's fine to rebase X-Y in your local version of exp.


exp contains pushed commits and has diverged from master.  master also 
contains commits made after exp was branched.  Most of the new commits 
in master need to also be applied to exp, but not all, since some of 
them touch code that has been replaced with a different implementation 
in exp.  (So in this case, exp doesn't add new features; it rewrites 
part of master using a better implementation.)


It seems I need to use cherry-pick (which looks like the equivalent of 
hg export/import.)  I suppose this won't break things for the future 
when exp will finally be merged back into master?


--
You received this message because you are subscribed to the Google Groups Git for 
human beings group.
To post to this group, send email to git-users@googlegroups.com.
To unsubscribe from this group, send email to 
git-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/git-users?hl=en.



Re: [git-users] Forward-porting commits - merge or rebase?

2012-05-11 Thread Konstantin Khomoutov
On Fri, May 11, 2012 at 09:50:18PM +0300, Nikos Chantziaras wrote:

[...]
 The idea with rebasing is that you can rebase any series of commits
 (ending with the branch's tip commit) on top of technically any other
 series of commit.  You do not have to rebase the whole branch.  To
 rebase a branch is just a popular way to spell it, but it's not
 technically perfect: you usually rebase just some series of commits
 near the tip of a branch, and usually this series starts right after
 the commit which is a common ancestor of both branches.  Of course,
 there's very little sense to rebase a series of commits onto something
 completely irrelevant and so the typical case for rebasing is like this:
 
 You have a branch, say, master, which looks like this:
 ...-A-B-C
 that is, it ends with commit C.
 
 You fork another branch, exp, off of it. Initially it looks exactly
 the same:
 ...-A-B-C
 
 Now you put commit X, and Y on exp, so it now looks this way:
 ...-A-B-C-X-Y
 
 In the meantime you committed M an N on master, so it looks like this:
 ...-A-B-C-M-N
 
 And now you want to pretend that X and Y on exp were made relative to
 the *current* tip of master, which is now N (as opposed to it being C
 at the time exp was forked off of it).
 Observe that C is what's called the common ancestor for both the
 involved branches here.
 So you rebase the series X-Y in exp onto master, and exp starts to
 look like this:
 ...-A-B-C-M-N-X'-Y'
 (And the common ancestor is now N.)
 
 This is why I'm confused now.  If I understood it right the first
 time, I am rebasing M and N.  But here you say that X and Y are
 getting rebased.
I fear this might be a point-of-view issue.
I tried to explain what happens when you rebase some commits present on
exp onto the new tip of master.  If you want to rebase some commits
on master onto the new tip of exp, just exchange branch names in the
above discussion.  Name them foo and bar after all.

Let's try to recap: rebasing, in essense, is changing the base (hence
why rebasing) of a series of commits (which end in the branch's tip).
If you're rebasing foo onto bar, you're changing the base of some
commits in foo to be the bar's tip, so that foo looks like bar with that
rebased series of commits applied onto its tip.

Technically, there are other cases for rebasing, but this one is the
simplest and most used (maybe with exception to squashing and fixups).

 The problem with rebasing and a public repo would only appear here if
 you would have managed to push exp into that public repo after
 committing X or Y.  If the exp branch ends in C in the remote repo,
 it's fine to rebase X-Y in your local version of exp.
 
 exp contains pushed commits and has diverged from master.  master
 also contains commits made after exp was branched.  Most of the new
 commits in master need to also be applied to exp, but not all, since
 some of them touch code that has been replaced with a different
 implementation in exp.  (So in this case, exp doesn't add new
 features; it rewrites part of master using a better implementation.)
 
 It seems I need to use cherry-pick (which looks like the equivalent
 of hg export/import.) 
Yes, to me it looks like a case for cherry-picking.

 I suppose this won't break things for the future when exp will finally
 be merged back into master?
It's hard to tell precisely.
Git is rather good at merging, but cherry-picked commits bear no meta
information about what they result from (contrary to merge commits) so
when merging exp back to master, it will be up to textual merging
machinery to detect equivalent text changes in both lines of history.

-- 
You received this message because you are subscribed to the Google Groups Git 
for human beings group.
To post to this group, send email to git-users@googlegroups.com.
To unsubscribe from this group, send email to 
git-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/git-users?hl=en.



Re: [git-users] Forward-porting commits - merge or rebase?

2012-05-11 Thread Nikos Chantziaras

On 12/05/12 01:09, Konstantin Khomoutov wrote:

On Fri, May 11, 2012 at 09:50:18PM +0300, Nikos Chantziaras wrote:
[...]

The problem with rebasing and a public repo would only appear here if
you would have managed to push exp into that public repo after
committing X or Y.  If the exp branch ends in C in the remote repo,
it's fine to rebase X-Y in your local version of exp.


exp contains pushed commits and has diverged from master.  master
also contains commits made after exp was branched.  Most of the new
commits in master need to also be applied to exp, but not all, since
some of them touch code that has been replaced with a different
implementation in exp.  (So in this case, exp doesn't add new
features; it rewrites part of master using a better implementation.)

It seems I need to use cherry-pick (which looks like the equivalent
of hg export/import.)


Yes, to me it looks like a case for cherry-picking.




I suppose this won't break things for the future when exp will finally
be merged back into master?

It's hard to tell precisely.
Git is rather good at merging, but cherry-picked commits bear no meta
information about what they result from (contrary to merge commits) so
when merging exp back to master, it will be up to textual merging
machinery to detect equivalent text changes in both lines of history.


Thanks for the helpful explanations, Konstantin.  I think cherry-picking 
is even better suited here than I originally thought.  It seems that it 
doesn't even make sense to merge exp into master.  The nature of exp 
pretty much suggests that master will be deleted and exp made the new 
master.  So merging is not even needed.  (Not sure if you can delete a 
branch in Git though, or if it's even advisable; will need to look this up.)


--
You received this message because you are subscribed to the Google Groups Git for 
human beings group.
To post to this group, send email to git-users@googlegroups.com.
To unsubscribe from this group, send email to 
git-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/git-users?hl=en.



Re: [git-users] Basic question: confusing messages with git merge

2012-05-11 Thread Antony Male

On 10/05/2012 12:49 am, Brad wrote:

Could 'Merge branch
master, remote-tracking branch origin' be what happens if I accidentally
typed git merge origin master? If I do this, what happens exactly?


Good guesswork!

One of git's merge algorithms is called an 'octopus merge', and merges 
more than two branches together. When you run 'git merge origin master', 
the fact that you named two branches (OK, 'origin' isn't a branch, but 
bear with me) causes the octopus merge algorithm to be invoked.


However, this algorithm is pretty old, no-one really uses it any more, 
and it's normally regarded as nothing more than a curiosity. Therefore 
it doesn't receive much love, and has some rather odd corner cases and bugs.


One such corner case is when one of the branches it's given to merge 
isn't a branch at all, and is instead the name of a remote. When this 
happens, you get the message you described, and some other stuff -- an 
empty merge commit I think? And I seem to recall there's another very 
strange oddness.


So, long story short, do not type 'git merge origin master'.
If you want an easier way to merge (with less typing) read on...

Do you know about git's branch tracking stuff? Basically, you can assign 
each branch an 'upstream' branch (defined in git's config). When you run 
'git pull', git will merge in this upstream branch by default. ('git 
push' follows a different set of rules by default, although this might 
change. Read push.default in man git-config for now).


When a branch has an upstream configured, '@{upstream}', or '@{u}' 
points to that upstream branch. You can also see whether a branch has an 
upstream by typing 'git branch -vv' -- the upstream appears in square 
brackets.


So, to configure an upstream (if you don't have one set already), use 
'git branch --set-upstream master origin/master', or 'git push -u origin 
master' if you want to push at the same time.
Having done this, you can type 'git merge @{u}' (with master checked 
out) to merge origin/master into master.


Hope that cleared up some confusion.

Antony

--
You received this message because you are subscribed to the Google Groups Git for 
human beings group.
To post to this group, send email to git-users@googlegroups.com.
To unsubscribe from this group, send email to 
git-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/git-users?hl=en.