Re: [git-users] Forward-porting commits - merge or rebase?
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] Forward-porting commits - merge or rebase?
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?
On 11/05/12 19:38, Konstantin Khomoutov wrote: On Fri, 11 May 2012 18:35:03 +0300 Nikos Chantziaras 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?
On Fri, 11 May 2012 18:35:03 +0300 Nikos Chantziaras 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?
On 11/05/12 16:36, Konstantin Khomoutov wrote: On Fri, 11 May 2012 04:24:07 -0700 (PDT) Nikos Chantziaras 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?
On Fri, 11 May 2012 04:24:07 -0700 (PDT) Nikos Chantziaras 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 (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 Rebasing it no magic: when you rebase your "exp" branch on top of your "master" branch, what happens is basically this: 1) Git chops off all the commits your "exp" branch currently has on top of your "master"'s tip commit. 2) Then it takes each removed commit one by one in the chronological order and applies them as if they were patches (.diff files if that feels more familiar), recording a new commit each time (this is very important, see below). That's why it's called "rebasing": your series of commits in "exp" was originally based on some old "master"'s tip, and you make it be based on the new "master"'s tip. And so are the logical consequences: the rebased series of commits contains *different* commits while containing logically the same changes. This appears to be weird at first sight but it's not: * Each commit records the time that commit was created at; obviously this will be the time of the rebasing for each rebased commit in the series. * The content of the branch you're rebasing onto is usually changed as well, and so will be the content referenced by your rebased commits. 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. That's why rebasing a public branch in most cases should be a properly documented decision. See how Git developers implement such a policy with their "next" branch [1]. > 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. Considered you understood the implications of rebasing a public branch, you should make a decision yourself. I'm inclined to think most people prefer more conservative approach as there's nothing wrong with merges; some even think that there should be no fast-forward merges except for trivial cases, see [1]. To make merge commit messages be more sensible ("merged feature X") `git merge` supports the --editor command-line option which allows to edit the commit message before actually committing a merge, and with older versions you can either use --no-commit to commit the merge manually or -m to provide the commit message directly. 1. http://git-blame.blogspot.com/p/note-from-maintainer.html 2. http://nvie.com/posts/a-successful-git-branching-model/ -- 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.