git - Why do I get git merge conflicts?
问题描述
I've encountered a situation related to git and Bitbucket which I don't understand.
I created a branch branchB
that originated from master
. I made some commits and created a pull request to master
. While this pull request was being reviewed, I started to work on another feature which was an extension of the feature from branchB
. So I created another branch (branchC
) that originated from branchB
. When my extended feature was ready, I created a pull request to branchB
. See the Picture I. I didn't have any merge conflicts at the time.
I wanted to allow the reviewers to have a look at both pull requests separately and have separate pull requests with smaller changes.
My plan was the following:
- merge the pull request 1 (
PR1
) to master using the--squash
option - change the target branch in the pull request 2 (
PR2
) to master (See the Picture 2) - merge the pull request 2 (
PR2
) to master
However, when I merge the pull request 1 (PR1
) to master using the --squash
option, Bitbucket automatically changed the target branch of the pull request 2 (PR2
) to master
and I got some conflicts in the pull request 2 (PR2
).
So I resolved the conflicts:
git checkout master
git pull
git checkout branchC
git rebase master
git mergetool
I resolved all conflicts here.
git rebase --continue
Actually, the described problem happened to me twice, since I also had branchD
originating from branchC
. When I merged branchB
into master
, I had to resolve some conflicts in the step 6. However, when I merged branchC
into master
, I didn't have to resolve any conflicts manually in the step 6 (even though Bitbucket showed me merge conflicts, so I had to rebase branchC
).
Mu questions are the following:
- Why did Bitbucket show me any merge conflicts for
PR2
when I mergedPR1
to master using the--squash
option? I'd expect it to figure out that the change between picturesI
andII
is only in commit ids - the code is hasn't changed. Git/Butbucket should be able to figure out which changes I want to make. - Why didn't I get any conflicts that should be resolved manually when I was rebasing
branchD
intomaster
(after I mergedbranch C
intomaster
)? Since Bitbucket couldn't merge my pull request, I'd expect that I'd need to resolve some conflicts manually. Can it be related to git version on my desktop and on Bitbucket? - Did I have any better option than creating these three pull requests in my case? Could I have avoided these merge conflicts?
Additional information:
- git version on my desktop:
2.17.1.windows.2
- Bitbucket version:
v5.12.2
- git version on the Bitbucket server:
2.14.5
- I looked for similar questions (1, 2, 3). None of them deals with my problem.
I'd appreciate any explanation of this phenomena.
Edit:
1. I merged all my pull requests using the --squash
option.
2. I updated the picture to show that branchB
and branchC
do not start with commits B1
and C1
, respectively.
解决方案
If I understand You situation correctly. The problem was this --squash
. Here is the topic that explains how are the merges done in GIT How does git know which version of a line to keep?.
When You merged with --squash
, since git commits are actually immutable, You have created a new squashed commit with new ID. When You wanted to merge PR2
back to master, the file contents were changed in both places. For branchB
there was a number of commits with some IDs and for master
there was only one commit that had a different ID and some files were changed on both branches, so basically git has no idea which version is correct. This is why there were no conflicts in case of branchC
, because the history of commits was the same for branchB
and branchC
(no --squash
done here).
推荐阅读
- ruby-on-rails - 如何在 ruby on rails 中链接到 /.well-known/assetlinks.json
- php - 如何在 Laravel 的服务容器中使用标签?
- google-apps-script - GoogleSheets股票价格电子邮件警报的实施
- python - 为什么我的 if 语句没有停止这个索引错误?
- javascript - 如何在两个年龄之间的表格中搜索
- jquery - 如何更新某些特定列的数据数据表
- reactjs - 如何自定义material-ui TextField Input underline:after?
- cypress - 获取 Cypress 中的 Children 元素之一
- python - 如何修复“'查询'对象没有属性'contains_column_references'”
- php - 如何在PHP中不使用字符串函数和数组函数的情况下查找字符串的前两个和最后两个字符