Pull Request is automatically marked merged in Bitbucket Data Center and some of the code changes are lost on target branch after performing conflict resolution in a different branch
Platform Notice: Data Center Only - This article only applies to Atlassian products on the Data Center platform.
Note that this KB was created for the Data Center version of the product. Data Center KBs for non-Data-Center-specific features may also work for Server versions of the product, however they have not been tested. 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.
*Except Fisheye and Crucible
Summary
The user creates a Pull Request (PR1) from Source Branch (Feature) -> target Branch (master) which shows conflicts. Now to solve this sometimes users might create a new branch and a new PR2 to solve conflicts. If done incorrectly this can cause PR1 to automatically be marked merged with some of the feature code lost from the master.
Environment
Tested on Bitbucket Data Center 7.21.x
Applies to Bitbucket Data Center 7.x and 8.x
Diagnosis
- PR1 is automatically marked as merged even though it shows files having conflict.
- This merge is triggered by another Pull Request (PR2) that was created to resolve the conflicts.
- Even though PR1 (feature → master) is marked as merged, some of the feature code is not visible in the master branch.
Cause
This is usually caused due to improper conflict resolution methods. Ideally, conflict resolution should be performed on the same source branch by locally merging the target. However, in some cases, the source branch might be protected hence preventing local merges to it. In such cases, users will create a new branch to resolve conflicts. However, if the user only stages the conflicted files in the new branch and leaves out (unstage) other non-conflicted feature files, this will cause some of the feature code changes to be lost from the target.
Below is an example case study:
- User creates a PR1 from Feature → Master which shows conflict in one file.
- Ideally to resolve the conflict you can locally checkout to the source branch and merge the target to it. Then once the conflicted files are resolved commit and push all the changes to the remote source branch.
- However, in some situations, the source Branch (as well as the target) might be protected hence preventing local merges without a PR. In such cases, the user will need to create a new branch either from the source or target to resolve conflicts and then merge using a different PR.
In this case user creates a new branch from the master (conflict-resolve) and locally merges the feature branch with it.
git checkout conflict-resolve git pull origin feature/feature2
- However in the process of conflict resolution user now unstages the non-conflicted files and only stages the conflict-resolved files and pushes to remote.
- The User creates another Pull Request PR2 to merge conflict-resolve → master.
- This operation will mark PR1 (feature → master) automatically merged and many of the feature codes will now be lost from the master.
Explanation:
Below is a visual representation of the git workflow in this case study
- After merging Feature to the conflict-resolve branch all commits from Feature are now part of the conflict-resolve branch. Hence merging conflict-resolve to master automatically marks PR1 (Feature → master) as merged.
- However, it is important to keep in mind that any changes introduced during the conflict resolution process (including unstaging of any feature code) will be the current state of the master.
- Once the conflict-resolve branch is merged, the user cannot re-merge the Feature branch to master again since there will be no diff shown between the two. This is because as per git all the commits of Feature are already part of the master branch history and hence there are no more changes to be merged from the new common ancestor between the two.
Solution
If detected immediately, one possible solution is to create a new branch and manually copy the code left out to this branch and merge it again.