Search code examples
gitbitbucketgit-pull

Control Freak: Commit rejected. Foxtrot merges not allowed in Bitbucket


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


Solution

  • 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.


    clav adds in the comments:

    This doesn't really provide a simple solution to fix the foxtrot merge rejection by BitBucket.
    For those seeking an answer to that situation, one simple solution is to back out the committed changes on your local branch using git reset --hard <latest commit_id on origin/master>. This will unstage the previously committed changes on your local branch.

    Now you can do git pull to pull and merge the latest changes from origin into your local branch. And you can commit & push local changes.