16

What exactly is the reason for Control Freak: Commit rejected. Foxtrot merges not allowed

We keep receiving this error quite often, is this is caused due to a combination of pull, rebase and amend by users while committing?

Need clarity to get rid of this permanently. I know and understand the branch has diverged and it has lost the trace but what exactly has caused that to happen in simple language is highly appreciable

It's a time killer for us to rebase every time when we see this error. We are manually cherry-picking the change to get rid of this.

How to identify the committed type like was that a right commit after rebase or pull or amended and which exactly is the commit that and by whom?

We want to educate developers to come out of similar commit mistakes henceforth. Would love to hear about the best practices.

Also, want to understand is there any reason for combination tools like git-bash/source-tree?

Can we turn off this cause by any chance?

enter image description here

halfer
  • 19,824
  • 17
  • 99
  • 186
Mithun Shreevatsa
  • 3,588
  • 9
  • 50
  • 95
  • I have to say I have never heard of "foxtrot" merges before. [Here is a blog post](https://developer.atlassian.com/blog/2016/04/stop-foxtrots-now/) which seems to do a good job of explaining. The solution here is to fix your Git workflow, and stop using foxtrot merges. – Tim Biegeleisen Mar 14 '19 at 05:40

2 Answers2

19

That is related to Foxtrot merges, specifcally prohibited on BitBucket:

A foxtrot merge is a specific sequence of git commits. A particularly nefarious sequence. Out in the open, in lush open grasslands, the sequence looks like this:

https://developer.atlassian.com/blog/2016/04/stop-foxtrots-now/02-foxtrot.png

But foxtrots are rarely seen in the open. They hide up in the canopy, in-between the branches. I call them foxtrots because, when caught mid-pounce, they look like the foot sequence for the eponymous ballroom dance:

https://developer.atlassian.com/blog/2016/04/stop-foxtrots-now/foxtrot-redrawn.png

Foxtrot merges are bad because they change origin/master’s first-parent history.

The parents of a merge commit are ordered. The first parent is HEAD. The second parent is the commit you reference with the git merge command.

You can think of it like this:

git checkout 1st-parent
git merge 2nd-parent

If pushed:

https://developer.atlassian.com/blog/2016/04/stop-foxtrots-now/05-foxtrot-pushed.png

As explained in "GIT: How can I prevent foxtrot merges in my 'master' branch?", commit 'D' is a foxtrot merge because 'origin/master' is its 2nd parent.
This is the result of a pull (fetch + merge)
Once that fox-trot merge D is pushed... the first-parent history of 'origin/master' no longer contains commit 'B'!

As explained by torek in "how to avoid foxtrot merge in git", this is the result of working directly on master (new commit C), and doing a git pull (instead of a pull --rebase, as I always advice)

That will merge B and C into D (the foxtrot merge), which, once pushed, means the origin/master no longer has B as direct ancestor, but C.
Your work 'C' now becomes the main published branch history (origin/master), instead of B, relegated to something that was merged.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thank you @VonC, but how to track the commit in detail – Mithun Shreevatsa Mar 14 '19 at 05:42
  • @Mithun the commit, it is a history of commits that would show a foxtrot merge, not just a commit": `git log --all --decorate --oneline --decorate --branches` is a start to see what is going on. – VonC Mar 14 '19 at 05:43
  • I can see the complete history, but will there be any indication of term: `Foxtrot`? – Mithun Shreevatsa Mar 14 '19 at 05:46
  • @Mithun No: it is a merge pattern, not a Git "term" that would appear in the logs. – VonC Mar 14 '19 at 05:49
  • will git squash all commits in branch help to resolve this foxtrot issue? – Mithun Shreevatsa Mar 14 '19 at 05:58
  • @Mithun No: this is more about rebasing C branch on top of B branch, instead of merging B branch into C branch. – VonC Mar 14 '19 at 05:59
  • I usually do it with pull, and never faced such issues but from some days we are facing this – Mithun Shreevatsa Mar 14 '19 at 06:12
  • @Mithun Can you try with https://stackoverflow.com/a/30209750/6309? With `pull.rebase` and `rebase.autoStash`, you should minimize/avoid any spurious merge entirely, hence avoiding any Foxtrox merge occurrence. – VonC Mar 14 '19 at 07:09
  • @Mithun I mean: what torek said in https://stackoverflow.com/a/55156429/6309, but my setting is a practical answer to your second question. I am at work right now. I will reopen your question and put an answer later today. – VonC Mar 14 '19 at 07:13
  • Many developers tag major versions then squash all the commits in-between. In this case blocking foxtrot commits holds no value. – Tim Apr 24 '20 at 15:43
  • @Tim I suppose BitBucket did not intially had the same kind of squash and merge process as GitHub (https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges#squash-and-merge-your-pull-request-commits), which might explain why they are blocking this kind of merge. BitBucket does have the same now (https://www.atlassian.com/blog/bitbucket/new-features-bitbucket-4-9) – VonC Apr 24 '20 at 15:49
  • 1
    Even though this pretends to explain the situation... for me it fails. I do not get it. Might be just me. But the examples, the explanation, everything here is weak and inconsistent. Why is there a "git checktout 1st-parent" and "git merge 2nd parent" and in the picture the commits are named A B C? What is the relation between the text and the pictures? Please. More explanation. – Zordid Jul 13 '20 at 13:08
  • @Zordid I understand. I have edited the answer accordingly. – VonC Jul 13 '20 at 16:17
10

The easiest way to avoid this problem is to always run "git pull --rebase" and to never run default "git pull". Here's a deep dive blog post on that: Too much fun with "git pull --rebase"

The reason you're encountering this problem is because your company has installed the free Control Freak plugin for Bitbucket and they have left its default Foxtrot Prevention control enabled for all branches.

If you're on Bitbucket Server 5.5 or newer you can rebase pull-requests directly from the pull request screen. Click on the "..." button on the far right of the pull-request screen and a "Rebase" menu item should be available.

Alternatively you can ask an admin to disable the foxtrot prevention. Even repo admins can do this (does not require global admins). But I don't recommend disabling this control since it prevents messy commit history.

Full disclosure: I wrote and maintain the free "Control Freak" plugin for Bitbucket Server.

Note: rebases and amends should never cause foxtrots. Typically only default "git pull" causes foxtrot merges, and "git pull -r" is a great remedy. The "git merge" command can also cause it, but it's rare for people to accidentally create a foxtrot merge when using "git merge" in typical scenarios that call for "git merge". I suspect 99% of the time it's "git pull" that is causing the problem.

G. Sylvie Davies
  • 5,049
  • 3
  • 21
  • 30
  • 2
    We're frequently running into foxtrot merges when trying to make sure that the current `feature` branch is compatible with `master` by merging `master` into `feature`. This is preferred over `rebasing` on `master` since the latter often requires tedious resolving of merge conflicts in many commits of the `feature` branch instead of resolving them all in one go in a merge commit. Is there a way of keeping the simplicity of a single commit to resolve all issues but avoiding foxtrot merges? – nitzel Dec 12 '19 at 11:39
  • When is the foxtrot warning happening? When you finally try to merge into 'master'? Or at a different time? – G. Sylvie Davies Dec 13 '19 at 05:14
  • When merging to master (via a PR). Shall we move this to a [chat](https://chat.stackoverflow.com/rooms/204176/g-sylvie-davies-and-nitzel)? – nitzel Dec 13 '19 at 08:36