How do I verify that my feature branch doesn't contain merge commits before submitting a PR

I’m fairly new to git, and from time to time I stumble and embarrasingly submit pull requests containing merge commits to Ansible.

Is there an easy way to double-check that my branch doesn’t contain any merge commits before submitting?
I have set up my fork repo with a remote to ansible/ansible called “source” can I simply do a

git checkout feature_branch
git reset --hard
git rebase source/devel

and be relatively certain that all is good?

Any pointers appreciated!

Try
git log --merges
or
git hist --merges

Those don’t limit though, so they go back a ways in time.

Hist is a popular alias for log, that pretties up the output.

git log --merges --first-parent will limit it, but I’m not sure it will have what you want.

Check out this page:
https://www.kernel.org/pub/software/scm/git/docs/git-log.html

I'm fairly new to git, and from time to time I stumble and embarrasingly
submit pull requests containing merge commits to Ansible.

Is there an easy way to double-check that my branch doesn't contain any
merge commits before submitting?

`git log --graph`

will give you a pretty reasonable way to visually check if there are
merges in your history. I'm a big fan of `tig`, and will usually do
something like
`tig origin/develop feature_branch`

before pushing to see if I have to rebase. Any git gui will have a
similar visual mode for looking at your history.

I have set up my fork repo with a remote to ansible/ansible called "source"
can I simply do a

git checkout feature_branch
git reset --hard

this seems a little scary- what are you trying to do?

Your proposed workflow looks reasonable. This is my typical approach (ansible/ansible is upstream, willthames/ansible is origin for me)

git checkout feature_branch
git fetch upstream devel
git rebase upstream/devel
git rebase -i upstream/devel
git push -f origin feature_branch

The first rebase just makes sure all of your changes are on top of upstream/devel, and the second allows the squashing of commits into a single commit.

I never merge when working with ansible (all the merges happen into upstream), only ever fetch or rebase
https://github.com/ansible/ansible/blob/devel/CONTRIBUTING.md#contributing-code-features-or-bugfixes

It’s worth noting beware using git pull when in your feature branch
e.g.
git pull upstream devel
is really
git fetch upstream devel
git merge upstream/devel

which could explain where your merge commits originate.

Will

Hi

I see a number of answers which are more confusing about this. It is really simple not having merge commits. Do not merge! Do rebase. This is my workflow, there are maybe others.

I assume you “forked” ansible on github and then cloned the forked to your local machine.

So one important thing is to not doing any commits in long term branches of the project. e.g. in ansible this would be devel. You only need to use this branch to sync with so called upstream. So how do we sync with upstream? Add the remote to your git repo.

git remote add upstream git@github.com:ansible/ansible.git

Now, you can sync with it:

git checkout devel
git pull upstream devel

So your devel branch is only there to pull from the latest changes, nothing more. So now, we want to create a new feature:

git checkout -b feature/new
edit
git commit -m “add new feature”

while we worked on that for 3 months… there were likely commits in the upstream project. So you project may be a bit “out of sync” and maybe it can not be merged because of conflicts. So how we do get in sync now? Sync again the devel branch.

git checkout devel
git pull upstream devel

Switch to your feature branch

git checkout feature/new
git rebase devel

Now, your changes were put no top (see git log) in line. Now you can create a pull request using your origin.

git push origin feature/new

Leave this branch like it is until your featrue has been merged. maybe you have to add more thing to it.

One important thing to note, rebase does change your history. if your pull request has been merged in, you should not rebase it from devel branch again and push it for another pull request. Removed this branch, when it has been merged.

But as long as it has not merged, you can rebase it from devel branch again. This would be very nice for the Ansible guys to see your changes in line.
After you rebase your feature branch again, you will not be able to do push it again

git push origin master

without -f alias force. As the history has changed (as I wrote before). Be careful with -f as it will overwrite without ask.

Hope this helps.

Regards
René

But as long as it is not merged you can rebase it with devel.

​A shortcut to enforce this would be:

  ​git config branch.autosetuprebase always

Advanced disclaimer: beware, while this is a sane default for projects
where you don't have commit access, be sure not to rebase branches you
publish or others are working on!

Yep, main trick here is to get in the habit of not using “git pull” but instead doing “git pull --rebase”, or “git rebase” vs “git merge”.

This combines fetching from origin and rebasing.

Whatever happens, avoiding a raw “git pull” or raw “git merge” is the ticket.

Also, starting a new branch for each pull request is highly recommended and will lead to problems if not done so, and can in particular result in pushing different commits to another pull request and complicating review (because we might want to approve one thing but not the other feature)

Git’s a bit of a power-tool compared to some other SCMs, but really really really useful for stuff like this.

It has made life managing a really really large project ginormous tons easier.

Thanks to everyone that has helped to keep commits orderly so we can get more in faster!

–Michael

Also Rene’s post

+1000