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

Re: Different behaviour for --find-renames between git diff and git merge?

From
Elijah Newren <newren@gmail.com>
Date
Dec 16, 2025, 19:44 UTC
Message-ID
<CABPp-BHTnP-3erFTJ23goreg=UJGWPwCwdN9LNKsVbB3Omjt9w@mail.gmail.com>
In-Reply-To
<61700785-5421-4fa8-8277-c0837b09a737@gmail.com>
Hi,

On Tue, Dec 16, 2025 at 5:15 AM Luca Balsanelli <lucabalsanelli@gmail.com> wrote:

>
[...]
Show 23 quoted lines
> In the following example, I start from an empty file and I modify it on
> one side of the history and move (rename) it on the other side. The
> rename between `branch` and the merge base is detected. So, can you tell
> me why in the following case the rename is not detected during the merge?
>
>     git switch -c master root
>
>     touch aaa
>     git add aaa
>     git commit -m 'aaa'
>
>     git switch -c branch
>     echo -ne 'A\nB\nC\n' > aaa
>     git add aaa
>     git commit -m 'A\nB\nC\n > aaa'
>
>     git switch master
>     mkdir dir
>     mv aaa dir/
>     git add aaa dir/
>     git commit -m 'aaa -> dir/'
>
>     git merge --no-edit branch

This is an interesting case where --[no-]rename-empty option applies (the same option you found a related commit for in a previous email in this thread):

$ git diff master~1 master
diff --git a/aaa b/dir/aaa
similarity index 100%
rename from aaa
rename to dir/aaa

$ git diff --no-rename-empty master~1 master
diff --git a/aaa b/aaa
deleted file mode 100644
index e69de29..0000000
diff --git a/dir/aaa b/dir/aaa
new file mode 100644
index 0000000..e69de29

The merge machinery runs with the equivalent of --no-rename-empty:

$ git -C ~/floss/git grep rename_empty merge-ort.c
merge-ort.c:    diff_opts.flags.rename_empty = 0;

This comes from commit 4f7cb99ada26 (merge-recursive: don't detect
renames of empty files, 2012-03-22), and the commit message there
explains the rationale.  (The name of the option and how it is set has
changed since 2012, due to commit 0d1e0e7801bb (diff: make struct
diff_flags members lowercase, 2017-10-31)).  merge-ort copied that
behavior from merge-recursive.

So, although the merge machinery calls the same diff machinery that
`git diff` uses, it does pass slightly different defaults.  (There's a
couple others too; I believe the differences include rename_empty,
rename_limit, histogram vs myers, basename-guided similarity, and the
possibility of cached renames in a sequence of commits being
reapplied.  Users are unlikely to see any of these typically, though
you certainly did here.)
Previous: Luca Balsanelli
Message 6 of 6 in “Different behaviour for --find-renames between git diff and git merge?”
  1. Luca BalsanelliDec 12, 2025
  2. Elijah NewrenDec 13, 2025
  3. Luca BalsanelliDec 15, 2025
  4. Elijah NewrenDec 16, 2025
  5. Luca BalsanelliDec 16, 2025
  6. Elijah NewrenDec 16, 2025

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.