The diff in pull requests is showing unrelated files after upgrade of Bitbucket Server or Data Center to 7.x or 2-way diff change.

お困りですか?

アトラシアン コミュニティをご利用ください。

コミュニティに質問


プラットフォームについて: Server および Data Center のみ。この記事は、Server および Data Center プラットフォームのアトラシアン製品にのみ適用されます。

Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.

*Fisheye および Crucible は除く

要約

After upgrading to Bitbucket Server or Data Center version 7.x all pull requests that were open before the upgrade show a completely different diff on the diff tab. The differences are usually the following:

  • The diff is showing way more files than before the upgrade. Some of those files were already updated in the target branch.
  • A message about conflict detection is shown. However, the conflict itself is not shown in the Diff view.
  • The message "Bitbucket Server could not check this pull request for conflicts." is displayed
  • The diff in the pull request is different from the output of git diff  when executed locally.

環境

Bitbucket Server or Data Center version 7.x or newer after upgrading from version 6.x or older.

原因

To better understand this use case, we need to consider the state of both files at 3 different points:

  1. The common ancestor of both branches
  2. The tip of the source branch
  3. The tip of the target branch

Previously, in version 6.x Bitbucket Server used a 3-way diff for Pull Requests and a 2-way diff for the compare view. This has changed starting with Bitbucket version 7.0, where a 2-way diff is performed in both contexts, so the compare view diffs and pull request diffs are now identical.

Based on this comment from our developer:

A 2-way diff compares 2 versions of a file (either from the common ancestor and one branch tip, or from both branch tips), and a 3-way diff compares 3 versions of a file (from the common ancestor and both branch tips).

Git diff is only capable of 2-way diffs, and it can do them in a couple of different ways. Those ways are controlled by how many dots are used, with a 3-dot (but still 2-way) diff using a comparison between the common ancestor and the tip of the branch, and a 2-dot (but still 2-way) diff comparing the tips of both branches (no dots is the same as 2 dots).

The 3-way diff performed for pull requests by earlier Bitbucket Server versions relies on merging the source branch into the target and then diffing the merge (so really it was the 2-way diff of a 3-way merge, and we called it a 3-way diff).

So what has changed from Bitbucket version 6.x to 7.x is the Pull Request view, which moved from a "3-dot, 3-way diff" to a "3-dot, 2-way diff".

Here's an illustration:

  • "A" is the common ancestor between the destination and source branches/tags.
  • "B" is the tip of the source branch
  • "C" is the tip of the destination branch, which includes newer commits made after "A."

Bitbucket 7.x performs a three-dot diff, which compares "A" and "B" (red arrow). However, it does not show the other commits highlighted by the red dashed box.
In terms of the git diff command, this would be:

git diff <commit id for "C">...<commit id for "B">

which is equivalent to:

 git diff $(git merge-base <commit for "C"> <commit for "B">) <commit for "B">

Reference: git merge-base - finds the best common ancestor between two commits.

On the other hand, the git diff  performed by a user on the command line performs a "two-dot" diff, which is the default when no dots are passed. A two-dot diff compares the tips of the source and destination branches (in the illustration above, this would be comparing "B" and "C"). Reference: git diff.

ソリューション

The example above is the expected behavior in Bitbucket from version 7.0 onwards. Please make sure that your developers are aware of the change and adjust the internal processes accordingly.

In case of the conflict not shown in the UI, you need to clone the repository locally and with the usage of git diff identify the conflict. And then take the steps to resolve the conflict.

Conflict resolution

Any conflicting changes made to the target branch after opening the pull request will require the Rebase in order to change the common ancestor.

Alternatively, the conflict can be resolved manually in a local copy and pushed to the upstream.



最終更新日: 2022 年 1 月 27 日

この内容はお役に立ちましたか?

はい
いいえ
この記事についてのフィードバックを送信する
Powered by Confluence and Scroll Viewport.