[dev] Fwd: Rebase vs. Merge
Ben Klang
ben at alkaloid.net
Fri Jan 8 12:56:29 UTC 2010
This is the conversation Mike Rubinsky and I had regarding how to do Git rebases.
For what it's worth, Mike made good arguments against my suggestion, but I don't know where to go from here.
/BAK/
Begin forwarded message:
> From: Michael Rubinsky <mike at theupstairsroom.com>
> Date: January 5, 2010 4:59:46 PM EST
> To: Ben Klang <ben at alkaloid.net>
> Subject: Re: Rebase vs. Merge
>
>
> Quoting Ben Klang <ben at alkaloid.net>:
>
>> I guess we haven't figured this out yet. I saw what you wrote in the channel about doing a "git pull" to make your rebase/push work. But it looks like that caused duplicate histories again (as seen via GitX).
>
> Yes, there will be duplicate entries, because they are on different branches. When you merge the branches together and then rebase against the remote master:
>
> git checkout master
> git merge [topic branch]
> git pull --rebase
>
> it reorders the commits in the correct order and removes the duplicates. I tried this out on a clone of hatchery and after merging, gitx did indeed show duplicate commits, but once I rebased, it flattened the history out perfectly.
>
> From what I read a "pull" is a "fetch + merge", which copies
>> the changesets from master into your topic branch,
>
> yup. `git pull` is a fetch + merge. `git pull --rebase` is a fetch then rebase
>
> where they get
>> re-added the next time you merge from your branch into master. Then I found this site regarding rebasing:
>>
>> https://wincent.com/wiki/Git_rebase_explained
>>
>> He explains that rebasing is only good on local branches. Well, that at least explains why we can't push to a remote branch after a rebase.
>
> I don't think that is true. Rebasing basically removes your local commits, applies the changesets from upstream, and then re-applies your local commits, so that your un-pushed changes are always the most recent changes in the history. I'm not totally sure what the author did to screw himself up, but being able to push your local changes upstream without a `merge` after the upstream has changed is one of the use cases for rebase. See http://www.eecs.harvard.edu/~cduan/technical/git/git-5.shtml under the "Common Rebase Use Practices" section.
>
>>
>> So here's what I'm thinking:
>>
>> 1) When working on major code changes, we should create a topic branch and push it to a remote branch that we track locally. The motivator behind this is to have a place where our changesets are backed up.
>
> Sure, agreed. Though I usually wait until my code is at least somewhat pretty before sharing it with everyone ;)
>
>>
>> 2) If possible, complete the work and merge it back into master without ever rebasing or merging *from* master. That keeps the history clean.
>
> I don't agree here. Well, partially. We should *never* merge from master onto a topic branch...that caused me hours and hours having to resolve conflicts for every singe commit that occured on master since I branched. We should rather rebase. I think the point of a topic branch is to contain _only_ the changes that are different from master. If we don't keep an _active_ topic branch up to date, that's no longer true. Obviously the impact of not having it up to date would be less for branches that are probably going to be short lived, for branches that are not actively being worked on, or (obviously) for branches that will never be pushed to git.horde.org, but in general, I feel that if share our branches with others, it should be kept up to date when feasible.
>
>> But that's only an ideal case, where no (or few) conflicts are generated and the topic branch doesn't rely on changesets from master after the branch creation.
>
> Hopefully, if you don't merge, but rebase, there shouldn't be any conflicts with master.
>
>> To handle this non-ideal case, I propose this:
>>
>> 1.5) When changes from master are necessary in a topic branch, delete the remote branch. Next rebase your local topic branch. Finally, push the local branch to the origin and set it up to track again.
>
> I'd be fairly strongly against this. What happens if someone has it checked out, and also has local changes they intend to share? The remote should only be deleted once it's no longer relevant, or has been merged into master.
>
>
>> Deleting a remote branch can be done like this:
>> git push origin :some-branch
>>
>> Now, I don't think deleting branches all the time is ideal. The main drawback to this is when multiple developers are working in/tracking the remote branch. They would all have to fetch down the changes and check out the new branch. But hopefully, this won't happen frequently.
>>
>> What do you think?
>
> I think that:
>
> git rebase origin/master
> git pull --rebase
> git push
>
> should work for remote branches, then when it's time to merge into master:
>
> git checkout master
> git merge [topic]
> git pull --rebase
> git push
>
> should work.
>
> Of course, this is all based on *my* understanding of how git works, so could obviously be flawed ;)
>
> --
> Thanks
> Mike
>
> "Time just hates me, that's why it made me an adult." - Josh Joplin
--
Ben Klang
Alkaloid Networks LLC
ben at alkaloid.net
404.475.4850
http://projects.alkaloid.net
More information about the dev
mailing list