Hacker News new | ask | show | jobs
by riperoni 891 days ago
Merging is a process that I like over rebasing exactly because it conserves the history.

With a repository server that supports merge requests and feedback from CI/CD tooling on commits/push you can motivate people to use merges rather cleanly.

If you add to that very simple rules like

- create branches for every feature

- commit often

- push often

- merge only via merge/pull requests

then even people new to Git can handle it just fine.

Merge conflicts happen when multiple people work on the same file and try to merge their different status. Imho, code bases where multiple people work on the same file at the same time have a more fundamental problem than Git.

Honestly, I still struggle to see the value in rebasing. Maybe because I haven't used it extensively. Superficially, to me at least, it does the same as a "git push -f".

I am curious to hear why it is supposed to be superior, especially with modern CI tools like Github and the likes.

4 comments

There is more than one way to do it. If that workflow works for you, fine.

> I still struggle to see the value in rebasing. Maybe because I haven't used it extensively. Superficially, to me at least, it does the same as a "git push -f".

Rebasing is completely different from pushing. Rebasing changes your history. You can do whatever you want with your history: rebasing, creating personal branches and moving them around, etc... and no one will know. Only your pushes matter to the rest of the world, or alternatively when others pull from your repository. "git push -f" means you don't want to play along with whatever is in the repository you are pushing into, it is usually bad as it may desynchronize it from everyone else's fork. You absolutely don't need to do a "git push -f" with rebase, in fact you really shouldn't.

And none of your rules prevent rebasing. The commit/push often rule make the need for rebasing less likely, but if a dev did a rebase, no one will notice, it didn't leave his own machine. He mostly did that to make the commit he pushed less awkward.

Merge isn't superior to rebase; they're both tools with different purposes.

Have you ever squashed down a branch before merging back into main? Then you've used rebase.

The purpose of source control (not just git) is to keep a useful version history of your project. If you don't need to know where/when a commit originally branched off from, rebase can keep a cleaner history than merge.

Even rebasing a branch off the latest commit just to merge back in can be useful.

I never use squashing, because the history would not be easily accessible afterwards.

In popular Git ecosystems like Github you have the option to add a merge commit. To me, this also helps understanding the history of the repo. Would the rebasing be equally visible?

Rebasing is usually (but not exclusively) useful before pushing to the shared repo, at a point when there's no proper history being added to it yet, so you can put your changes into shape before actually publishing them. Learning how to effectively use rebase and its all goodies is one of the most useful things that git has to offer and almost transforms the way you work with version control, as with it you're able to utilize its power in more areas than if you only ever commit and push. For me, git is not just a collaboration tool - it's also an "undo" log on steroids; something that extends my text editor and lets me manage the changes regardless of whether they're meant to ever leave my PC or not.

Git is a powerful data structure manipulation tool. Use it as such and harvest that power. After all, what you're working on is just a graph of repository states - and you can attach any meaning you find useful to those states.

Rebase can split commits as well as combine them. Rebase can be used to improve the commit messages of previous commits, etc.

If the history is important, as you assert, then a tool for rewriting and improving the history is also important.

Arguably, it is not the real history anymore if you make it prettier.

Do you put manual work into rebases? It sounds like a lot of effort and time when collaborating.

It's not the full history, you're right. But nothing in git will ever be the full history.
git merge doesn't conserve the history it pollutes it. any more than a few merges or a few developers and you are left with an impossible to read merge log with 10+ parallel paths.

Git rebase preserves a linear history . Keep a reflog on the server (github has one built in) for cases where someone has screwed up the history. and secure shared branches to avoid clobbering it.

Yes, securing branches is very important, much like git-hooks if you are serious about the Git flow.

How do you specifically investigate the history with rebase and 10+ developers? Do you manually look into commits on the branch, or go by a single file history, or look at merge/pull requests?

Personally, I prefer looking at the context of a file change within a merge/pull request. The specific merged/pull request can be read from the merge commits. And in case a specific file history is of interest, I can backtrack from that file's associated commits.

if master has a clean history, then use git-blame on the file to see where a change was introduced, and git show to see the entire change. then you can walk back through the git log to understand the context of the change.
Merge doesn't pollute the repository. Just like rebase, it's a valid tool to use when what you want to do with your repo structure calls for it. It's the fact that most people use git blindly and end up doing things that don't make sense that pollutes their histories.

There are tons of merge commits in the Linux repository, but no useless ones. Note how in its nature Linux process also does implicit rebasing of applied patches when they land in subtrees.