On 2022-07-28 at 08:23:24, Laďa Tesařík wrote: > Dear all, > > recently we experienced strange behavior of git merge after deleting file in two branches and introducing it again in one of them (revision graph: https://i.stack.imgur.com/jNUZB.png): > > 1. I added a file called 'new_file' to a master branch. > 2. Then I created branch feature/2 and deleted the file in master > 3. Then I deleted the file in branch feature/2 as well. > 4. I created 'new_file' on branch feature/2 again. > 5. I merged feature/2 into master, merge introduced no changes, file 'new_file' is not present in master. > > This could cause problems to our team in the future, fortunately we noticed it this time. > Please, does anybody have any explanation for this behavior? > > Or is anybody aware of any Git or Source option that changes this behaviour? I think this is covered in the Git FAQ: If I make a change on two branches but revert it on one, why does the merge of those branches include the change? By default, when Git does a merge, it uses a strategy called the `ort` strategy, which does a fancy three-way merge. In such a case, when Git performs the merge, it considers exactly three points: the two heads and a third point, called the _merge base_, which is usually the common ancestor of those commits. Git does not consider the history or the individual commits that have happened on those branches at all. As a result, if both sides have a change and one side has reverted that change, the result is to include the change. This is because the code has changed on one side and there is no net change on the other, and in this scenario, Git adopts the change. If this is a problem for you, you can do a rebase instead, rebasing the branch with the revert onto the other branch. A rebase in this scenario will revert the change, because a rebase applies each individual commit, including the revert. Note that rebases rewrite history, so you should avoid rebasing published branches unless you're sure you're comfortable with that. See the NOTES section in git-rebase(1) for more details. In this case, your change is to delete the file and the revert is to re-add it, which is why this is happening. I realize this is tricky, which is why I added this FAQ entry, and, before that, the mention in git-merge(1) in the sentence starting with "With the strategies". It is, however, the correct behaviour, since a three-way merge must necessarily adopt a change, whatever that is, when the other side is unchanged, and as a result, there's no configuration option for this. -- brian m. carlson (he/him or they/them) Toronto, Ontario, CA
Attachment:
signature.asc
Description: PGP signature