git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Lost file after git merge

From
brian m. carlson <sandals@crustytoothpaste.net>
Date
Jul 28, 2022, 21:23 UTC
Message-ID
<YuL+btk2MYmnphRs@tapette.crustytoothpaste.net>
In-Reply-To
<HE1PR0501MB24096E2FBDB66318A2FDADAAF8969@HE1PR0501MB2409.eurprd05.prod.outlook.com>
On 2022-07-28 at 08:23:24, Laďa Tesařík wrote:
Show 14 quoted lines
> 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
Previous: Elijah Newren
Message 9 of 9 in “Lost file after git merge”
  1. Laďa TesaříkJul 28, 2022
  2. Ævar Arnfjörð BjarmasonJul 28, 2022
  3. Junio C HamanoJul 28, 2022
  4. René ScharfeJul 29, 2022
  5. Junio C HamanoJul 29, 2022
  6. Elijah NewrenJul 30, 2022
  7. René ScharfeJul 30, 2022
  8. Elijah NewrenJul 31, 2022
  9. brian m. carlsonJul 28, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.