How to find the commit that introduced an unexpected change in Bitbucket Server and Data Center
プラットフォームについて: Data Center のみ - この記事は、Data Center プラットフォームのアトラシアン製品にのみ適用されます。
この KB は Data Center バージョンの製品用に作成されています。Data Center 固有ではない機能の Data Center KB は、製品のサーバー バージョンでも動作する可能性はありますが、テストは行われていません。サーバー*製品のサポートは 2024 年 2 月 15 日に終了しました。サーバー製品を利用している場合は、アトラシアンのサーバー製品のサポート終了のお知らせページにて移行オプションをご確認ください。
*Fisheye および Crucible は除く
要約
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."
環境
Bitbucket Server および Data Center
ソリューション
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".
#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.
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
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.
# 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