Subject: Re: Rename detection fails on symlinked files

From: Michal Suchánek <[email-masked]>
Date: Thu, 25 Sep 2025 09:39:16 +0200

On Tue, Jun 17, 2025 at 10:44:23AM -0700, Elijah Newren wrote:
> Hi,
> 
> On Tue, Jun 17, 2025 at 4:16 AM Michal Suchánek <[email-masked]> wrote:
> 
> I think your subject might be slightly misleading, and that a more
> accurate subject might be: Rename detection is not performed for files
> still present in the target version.  Let me explain why and you can
> check if I'm understanding your problem setup correctly.
> 
> > commit 5d51b10d8b5206ef5eeb9d214237b2ec2e0b789e (HEAD -> master)
> > Author: Michal Suchanek <[email-masked]>
> > Date:   Tue Jun 17 13:08:51 2025 +0200
> >
> >     rename file
> >
> > diff --git a/somefile b/somefile-renamed
> > similarity index 100%
> > rename from somefile
> > rename to somefile-renamed
> 
> So you've renamed a file, detected at the time you run git log -p.
> 
> > ln -s somefile-renamed somefile
> > git add somefile
> > git commit --amend
> 
> Here, you reintroduce the original file, as a symlink, and amend the commit.

No, there is no original file:

diff --git a/some file b/some file
deleted file mode 100644
index b649a9b..0000000
--- a/some file 
+++ /dev/null
@@ -1 +0,0 @@
-some text
\ No newline at end of file
diff --git a/some file b/some file
new file mode 120000
index 0000000..b649a9b
--- /dev/null
+++ b/some file 
@@ -0,0 +1 @@
+some text
\ No newline at end of file

See, the plain file and symlink is so different that changing the mode
to symlink is represented as removing a file, and adding a symlink. Not
same file mode change, not even a rename. The symlink is so different
from the file that it's completely unrelated, even with exactly same
content. Mode change to/from symlink always breaks, regardless of content and
the break rewrites setting.

diff --git a/some file b/some file
deleted file mode 100644
index b649a9b..0000000
--- a/some file 
+++ /dev/null
@@ -1 +0,0 @@
-some text
\ No newline at end of file
diff --git a/some file b/some file
new file mode 120000
index 0000000..b649a9b
--- /dev/null
+++ b/some file 
@@ -0,0 +1 @@
+some text
\ No newline at end of file
diff --git a/some other file b/some other file
new file mode 100644
index 0000000..b649a9b
--- /dev/null
+++ b/some other file   
@@ -0,0 +1 @@
+some text
\ No newline at end of file

And here we now have one removal and two additions of the same content,
no rename detected.

So git cannot agree with itself if symlink and plain file is actually
the same file or not. They are presented as comletely unrelated to the
user yet rename detection fails to detect the rename of the plain file
that is completely unrelated to the added symlink. That is the
discrepancy, and the bug.

Thanks

Michal