By default, GitHub’s pull request (or GitLab’s merge request) will merge with a merge commit. That means your feature branch will be merged into the master by creating a new commit, and both the feature and master branch will be kept.
Let’s illustrate with an example:
Let’s assume we branch out a feature branch called “new-feature” from the master branch, and pushed a commit called “Finished my new feature”. At the same time someone pushed another commit called “Other’s feature” onto the master branch.
If we now create a pull request for our branch, and get merged, we’ll see a new merge commit called “Merge branch ‘new-feature’”
If you look at GitHub’s commit history, you’ll notice that the UI shows a linear history, and the commits are ordered by the time they were pushed. So if multiple people merged multiple branches, all of them will be mixed up. The commits on your branch might interlace with other people’s commits. More importantly, some development teams don’t use pull request or merge requests at all. Everyone is suppose to push directly to master, and maintain a linear history. How can you develop in branches but merge them back to master without a merge commit?
Under the hood, GitHub and GitLab’s “merge” button uses the —no-ff option, which will force create a merge commit. What you are looking for is the opposite: —ff-only ( ff stands for fast-forward). This option will cleanly append your commits to master, without creating a merge commit. But it only works if there is not new commits in master but not in your feature branch, otherwise it will fail with a warning. So if someone pushes to master and you d >git pull on your local master, you need to do a rebase on your feature branch before using —ff-only merge. Let’s see how to do this with an example:
After these commands, your master branch should contain the commits from the feature branch, as if they are cherry-pick ed from the feature branch. You can then push directly remote.
If unfortunately someone pushed more code to the remote master while you are doing this, your push might fail. You can pull, rebase and push again like so:
GitHub’s documentation has some nice illustrations about the two different kind of merges.
Here is a script that does the above for you. To run it you have to checkout to the feature branch you want to merge back to master, then execute it. It will also pull and rebase both your feature and master branch to the most up-to-date remote master during the operation.
It’s worth mentioning that both GitHub and GitLab allows you to do the fast-forward (and squash) merge on it’s UI. But it’s configured on a per-repository basis, so if you don’t control the repository, you might have to ask your development team’s administrator to turn on the feature. You can read more about this feature in GitHub’s documentation and GitLab’s documentation. If you are interested in squashing the commits manually, but don’t know how, check out my previous post about squashing.
Having questions or want to learn more?
Book a private mentoring session with me using the button below:
I’m sure you’ve all come across merge commits when using Git, those pesky commits with a message reading something like Merge branch ‘master’ of github.com:kernow/Project-X . We’ve all been guilty of creating git merge commits, but don’t worry there’s a way to stop being a “Git Tit” and make everyone in your team happy which will no doubt lead to them buying you cake! But first, how do these commits get into the repository in the first place? You start out being a good gitizen, git checkout master , git pull , feverishly code away, commit, commit, commit. Woo I’m done, everyone will love my wicked new code! git push rejection!! what! Other people have been working too, jerks. git pull , git push , and there we have it, a merge commit. So how do we stop this madness?
Rebase to the rescue
When running git pull we need to rebase, and so to the first way to avoid merge commits…
git pull —rebase What’s happening here? Git will rewind (undo) all of your local commits, pull down the remote commits then replay your local commits on top of the newly pulled remote commits. If any conflicts arise that git can’t handle you’ll be given the opportunity to manually merge the commits then simply run git rebase —continue to carry on replaying your local commits.
Tell git to always rebase when pulling, to do this on a project level add this to your .git/config file:
Add a global config option to always rebase when pulling
And the final way, which is what I personally use, in
Of course you could use the 3rd solution and run the command git pull —no-rebase but that involves more typing, and I’m a lazy typer!
Posted by Jamie Dyer Jun 20 th , 2012
If you’d like to hire me to work on your project please get in touch.
and I get merge conflicts. I resolve the merge conflicts manually and issues a pull again but Git refuses to do it as Git is still thinking that there are merge conflicts.
Is there any way to force Git to perform a pull again and make it look for “diffs” (if any ) from the head(without committing the changes I made) ?
4 Answers 4
Why are you issuing a second git pull after fixing the merge conflicts from the first? That makes no sense. Once you fix the merge conflicts, you want to git commit instead, which will create the merge commit that merges the remote branch with your local one (and includes your conflict resolutions).
You have to commit your changes after you resolve the conflicts and push them back. Usually instead of using git pull I do a git fetch followed by a git merge and then git commit . This will only fetch the upstream changes, allow you manually merge and resolve conflicts, then commit them locally. When you’re ready push the changes back to upstream.
If you use this workflow you could:
The process here is:
You get a notice of conflicts. You use whatever you use (though hopefully you’ve hooked up everything you need to use git difftool locally.
Once the conflicts are resolved, you now have a working directory that contains the merged of the remote changes and your local changes. The ONLY thing that’s different is, git couldn’t do the merge on its own and needed your help.
to create a new commit in your local repo that is the sum of the pulled-in remote changes and your local changes. Then you
to publish your changes, nicely merged up, with the remote head.