Hacker News new | ask | show | jobs
by silverlake 5001 days ago
I'm still new-ish to git and don't get why rebase is popular. If I do my work on a branch B, I can merge this branch into the master M. The merge point will have a succinct message "Bug Fix #1". You can print the history so it only shows these merge messages and not the messy history in the branches. Isn't this the same as rebase? That is, rebase removes the messy branch history. But I'd prefer to keep that history, but rarely use or display it. bisect can also ignore those branches and only use the merge points. Saving the branch history shouldn't be problem. What am I missing?
4 comments

There are two major things I really gain out of rebasing frequently.

Firstly and most importantly, Thanks to rebase I'm constantly working against the most recent mainline, merge pains are reduced by frequently dealing with smaller rebase merges instead of trying to do one massive merge at the end when I'm finished with a longer life task that might last a week or two. The more often you merge the less painful it is.

Secondly there's the cleaning part of history involving squashing. I believe the issue with your viewing the merge history of the main line will miss out on changes that were able to be introduced fastforward without a merge. And frankly no one else on the team cares that I committed 6 times in the process of one task, they want to see all the code relevant to that task, and ideally it's all in one change set.

There's a pretty reasonable summary over here http://blog.sourcetreeapp.com/2012/08/21/merge-or-rebase/

For certain teams rebase just makes a lot of sense.

> merge pains are reduced by frequently dealing with smaller rebase merges instead of trying to do one massive merge at the end when I'm finished with a longer life task that might last a week or two. The more often you merge the less painful it is.

You can take care of that just by doing frequent regular merges, no need to do rebase ever, and rebase doesn't make this part any easier, does it?

I think the 'cleaning part of history', and trying to avoid those annoying merge commits in the logs, is in fact the only reason to do rebases, no? It's obviously an important one to many people.

Let's compare git to SVN.

With SVN your only real option is to commit something that is working, right? If you commit something broken to SVN then you will likely get yelled at.

With git, you can make a few changes, then think "hmm that might not be the best way to fix it" do a commit and then rip out everything you just did and do it a different way.

Or maybe you Added some instrumentation for debugging the problem, committed, then fixed the problem, committed, then removed the instrumentation.

In both cases git has let you save off information that you might need during the bugfix process, but ultimately isn't needed in the final history. With SVN, you likely wouldn't check in those intermediate steps so the final history in SVN would be a single commit of "Fix bug foo"

Is there any need for everyone to have these intermediate commits in their history? I guess that's a matter of taste. I think the main thought is that rebases improve the signal-to-noise ratio of the changelog.

Does using rebase or squash leave the history in my local repo and "squash" the commits to a single one in the master?

Sorry for basic questions but I'm new to git.

No and yes (respectively). Rebase rewrites the history of whatever branch you are on. Squash converts a merge into a single commit on another branch.

Say you are working on a feature in a branch and have made several commits. Now it's time to clean them up in preparation for a merge. You can either squash the entire branch into one revision into master and create a new commit message (git merge --squash) or you can rebase.

If you rebase, you can use interactive mode (git rebase -i) and rewrite your local history however you see fit. You can reorder commits, remove commits, merge commits, edit commits, edit commit messages, anything. It's extremely powerful and lets you make the history of your current branch into whatever you want it to be. I use rebase -i quite a bit to merge "typo" commits into the original commit. Used sparingly rebasing really helps to keep your timeline clean.

You can also rebase while in master but you should not go older than the newest shared commit (origin's HEAD) nor should you edit other people's code during a rebase.

Linus doesn't want all of your personal history. So he's okay with you rebasing your 15 commits that fixed bug X into one "fix for bug X," but never should anyone rebase someone else's history.
> But I'd prefer to keep that history, but rarely use or display it.

So why have it?

> I'm still new-ish to git and don't get why rebase is popular.

My most common use case for rebase is actually to keep my private branches up to date with master. `git rebase master` or `git fetch origin && git rebase origin/master` are common tools for me when I'm doing private work for an extended period of time. This way, I don't have a point where my private branch diverges from master; my changes are always fresh and based off the latest and greatest.

Because rarely != never?
If you're in the position of rebasing a branch down to a single commit, but many of those commits contain messages that are useful, then keep those messages in the final commit message.

When running an interactive rebase (git rebase -i my_branch~5), you have many options available to you. Fixup squashes and discards the commit message. I'll use this on commits I made that are literally just tags in a commit stream where I'm about to do a destructive action to my code (like during refactoring, you know the ones: 'git commit -m "update"') and I want to ensure I have a point to reset my branch to if I start screwing everything up. Squash just literally combines the commit with the next one, but preserves both commit messages. Use this for commits that are relevant to the named branch you're working on and are descriptive of what the branch was trying to accomplish.

Create a summary as the first sentence of the new commit message. It will show on any pretty-print log message output. Then literally combine all your commit messages into a paragraph (or more) for a detailed description. The information is still there, and it's still in the same place.