How to find the commit that introduced an unexpected change in Bitbucket Server and Data Center
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
There may be situations where a recently merged pull request causes one or more files to be modified unintentionally. This could be due to merge conflict resolution, in the scenario where the PR source branch has conflicts with the PR target branch. When the merge conflict resolution is not done properly, this may cause files to be rolled back to a previous state.
If files go back to a previous state due to an incorrect merge conflict resolution, this is expected behaviour from a Git perspective. Thus, developers are encouraged to be extra careful when fixing merge conflicts.
In some cases, the unexpected change may be realized a few days or weeks later, and teams need to find where the problem started to occur.
This article serves as a guide to help teams find which commit or pull request caused the problem, a.k.a. the "bad commit."
Environment
Bitbucket Server and Data Center
Solution
Use the git bisect command to find the commit that introduced a bug
Start a bisect session on a local copy of the repository with git bisect start
Check if the files in the repo are in a good state or run some tests. If good, enter git bisect good. Otherwise, enter git bisect bad
If you previously got a good state, locate a commit hash that you know has a bad state. Do a "git checkout <commit-hash>" on this hash.
If you previously got a bad state, locate a commit hash that you know has a good state. Do a "git checkout <commit-hash>" on this hash.
Check again if the commit is good or bad. If good, enter "git bisect good". Otherwise, enter "git bisect bad".
1 2 3 4 5 6 7 8 9 10 11 12 13
#starting point: master branch git bisect start status: waiting for both good and bad commits git bisect bad status: waiting for good commit(s), bad commit known git checkout daf9744854c6cf1b4578d899e4becc47d18d3a9b Note: switching to 'daf9744854c6cf1b4578d899e4becc47d18d3a9b'. git bisect good Bisecting: 1 revision left to test after this (roughly 1 step) [406ede5a61633d537fbcf443eef8d58b6bbcefd1] fourth change
The tool will mention what commit hash to be checked next. It will automatically shift the HEAD to that commit hash. Assess again if this is a good or bad commit.
1 2 3
git bisect good Bisecting: 0 revisions left to test after this (roughly 0 steps) [8a574e5842de7bc8e428e5b015d2de3f4474dab5] merge conflict resolution
Repeat until the problematic commit has been narrowed down
1
8a574e5842de7bc8e428e5b015d2de3f4474dab5 is the first bad commit
End the bisect session with a git bisect reset
Locate the first bad commit in the Bitbucket UI
This first bad commit may be a merge commit as a result of a pull request merge
A merge commit has two parents, one from the target branch and another from the source branch
Important: Sometimes, teams would miss to review the diff with the source branch. Make sure to check this diff as well as this is where the unintended change is displayed.
How do I prevent unexpected changes due to merge conflict resolution?
If the source branch of a pull request has diverged a lot from its target branch, it might be better to do a git rebase so that new changes are made on top of recent commits in the target branch.
With a git rebase, there is less likelihood that other files will be modified unintentionally.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Checkout your source branch
git checkout <source-branch>
# Set the starting point from where you want to put your commits
# This is a commit hash on the target branch. For example, from the latest merge commit/most recently merged PR.
git rebase --onto <commit-hash-on-target-branch>
# Now merge any changes from the source branch to the target commit hash
# Review the conflicts and address them carefully
git merge --no-ff
# After fixing the merge conflicts, add, commit and push the changes
git add .
git commit -m "Fix conflicts"
git push
# Last step: Merge the Pull Request in Bitbucket
Was this helpful?