Git Questions – How and When do I Merge or Rebase?

Ever since Gary and I started the Git Questions video series, we’ve been asked to talk about merging.  We’re also frequently asked about rebasing – what is it, and when should I do it?

In this week’s video, we take a look at how to use IntelliJ IDEA to merge a branch back into the “main” development branch.  We also talk about rebasing – not only showing how to do it in the IDE, but what it means and when you should do it.

We don’t show how to deal with merge conflicts in this video, but they are discussed, and a more complete conflict-resolution video is definitely high on the TODO list.

This entry was posted in Tips & Tricks and tagged , . Bookmark the permalink.

12 Responses to Git Questions – How and When do I Merge or Rebase?

  1. Brian says:

    Good topic to cover. Thank you for doing it.

    While I understand that it is more clear to use the dialog from the VCS menu and it’s good to be reminded of that option, I would have appreciated an authoritative explanation of which direction the merge and rebase happen. If people from JetBrains are confused about it then either they need to learn it and help educate the user community or the menu language needs to change to make it more clear.

    One important topic that I don’t think you mentioned is the pitfall of rebasing a shared branch. Because the commits are replayed, they are new commits and therefore different from the commits in anyone else’s clone of the repo. Git does very confusing things if you try to pull changes to a branch that someone else has rebased. Therefore, if you’re sharing a branch and you are rebasing for any reason other than to immediately fast-forward merge and delete the branch, always coordinate with your fellow developers to make sure they are in a state where they can delete their local branch and pull a fresh copy after the rebase.

    • Trisha Gee says:

      Hi Brian,

      You raise a really good point about the shared branches – I made an assumption that you would never rebase a shared branch for exactly that reason! But it’s worth being explicit about it.

      I’d actually love to cover the other merge/rebase options in more detail to clarify them too, but the video was already an enormous 15 minutes as it was! We’re in the process of updating our documentation (and tutorial videos) on this topic so we’ll definitely be clarifying these other options in the near future.

    • WearyTraveller says:

      The direction of a merge or a rebase is actually always the same: you always take over changes from another branch onto the currently checked out branch. Merge and rebase just do it differently. Merge is simple to fix conflicts in one go, but can be complex if there are a lot of conflicts and you’re unsure which way to resolve them. If you rebase, conflicts are resolved per commit, which hopefully has a useful commit message to guide you how to resolve a conflict.
      One way to understand rebase is to understand that it basically linearizes commits in that it pretends nobody ever worked concurrently. If you rebase your feature branch onto development, you update your feature branch to incorporate all changes that happened on development in the meantime. Git does this by temporarilly setting the commits on the feature branch aside and resetting the branch to development and then replaying your commits as if you’d be committing them very quickly, pausing when conflicts occur. The resetting part can also be seen as if you’d branch of development right now. Thus whatever your co-workers did, they did so before you and you adopt your commits to work with them. HTH

  2. Tom Eugelink says:

    I’ve been using GIT for a number of years and it stays somewhat confusing, so I can’t really blame the people from JetBrains for feeling the same way. In the end you end with a list of “if then ” which happen to work for the style of using GIT your current project is using.

    As an IDE vendor, if you decide to just wrap GIT, you will never get working with GIT really clear to the end user, because IMHO GIT simply is not clear. The basics are, but it’s a swiss army knife allowing you to do all kinds of funky stuff. But I do wonder that if you adopted certain git workflows (like the mentioned feature branches, or the one invented by GitLab or any of the other flows) if it would be possible to have a more understandable GIT interaction.

    • Michal says:

      I love git and its branching model. I never was in to svn, which force people to use trunk because branching and merging are not cheap and straightforward as in git.

  3. Oleksii Vynnychenko says:

    Come on guys, 720p with compression level like it’s 480p or less… you’re better than that. Nice video though

    • Trisha Gee says:

      Sorry the standard wasn’t up to what you expect – we did have a LOT of problems with this particular video, largely because recording while both of us are remote and then editing is challenging. We decided in the end it was more beneficial to our users to release it as it is than delay this topic another month.

      We do hear your feedback though, and will be improving the quality for future videos.

  4. Thanks, Trisha

    I guess re-base is quite self explanatory: we pick again (thus re in rebase) base for our feature branch commits. But I accept you are visual person :) . Intellij anyway offers freedom to use tooling the way we feel natural with.

    After rebasing – each feature branch commit gets new SHA, and if branch was already pushed to upstream, the only thing that can be done to sync with server is – force pushing changes to back.

    My rule of thumb is that I use rebasing all the time until I’m feeling confident my branch is ‘good enough’ to be pushed to upstream.

    On the other hand, if I work too long in ‘local’ mode – I risk losing my work.

    All in all – merging is lot safer than rebasing, requires no communication between developers working on the same remote branch, having downside of ugly merge commits in git history, which I never care much about.

    Cheers,
    Dusan

  5. Michal says:

    I just follow one simple rule of rebaseing (form Git Pro Book: https://git-scm.com/book/en/v2/Git-Branching-Rebasing):

    “In general the way to get the best of both worlds is to rebase local changes you’ve made but haven’t shared yet before you push them in order to clean up your story, but never rebase anything you’ve pushed somewhere.”

    And then you are save!

    • Trisha Gee says:

      That works for sure, but by not pushing your changes you’re losing one of the most important features of a source control system, which is remote backup. And it doesn’t address workflows like developers who work on more than one physical machine – you may not be sharing your branch with other developers, but you may still need to share it with yourself.

  6. Mike Wilkes says:

    Thank you for the video. @Trisha. Did I hear correctly that you said rebase is more dangerous because you can lose stuff? That’s the biggest misconception about rebase/git, and I ensure I clear that up fast with my team.

    I also say there are 3 things to remember with Git.
    1. Don’t do anything with changes in your workspace
    2. Don’t do anything with changes in your workspace
    3. Git never modifies anything. It only creates new things and changes pointer.

    A rebase is an extremely convoluted merge in the background. It does the merges etc, stop s on conflicts, and as with most commands in Git, gives you an –abort if you feel you’ve messed it up somewhere.

    At the end, your old commit/branch is still there, it’s merely that nothing points to it anymore. If you know the SHA for the commit, you can check it out, and create a new branch.

    If you don’t know the SHA, you can use reflog to retrieve it. Git does cleanup unreferenced commits periodically, but generally speaking, something will be around for a couple months (unless you delete the directory on your machine)

    That’s one thing Git does extremely well. I tell my team that because of this, they should feel free to experiment with Git. Just remember the first 2 of my 3 ‘rules’.

    Keep up the great work! I’m a huge fan of Intellij and Kotlin. I just joined a new team, and converted them to both.

    • Trisha Gee says:

      Thanks for this, it’s really useful information for people to know.

      I don’t think I said you can lose stuff, but it does change your history and if you do something you didn’t mean to when addressing merge conflicts, you can end up with different code to what you expect. And while it’s possible to go back to the original branch if you know the SHA, I’m not sure how many people commit that to memory!

      A trick I’ve been using while I experiment (and I agree, people should experiment with Git) is make extra branches – if you’re trying to rebase a branch called “feature-123”, for example, I would make a branch called “feature-123-before-rebase” to keep as a backup in case I get do rebase wrong. You can do the same for any or all of the branches in an operation, then hard reset your messed-up branch to its backup. I’m sure there are more Git-like ways to do this, but this approach can be really useful for those who don’t think in Git. I really want to do a video on this too.

      And we love users like you :) Keep up the conversions!

Leave a Reply

Your email address will not be published. Required fields are marked *