threads / discuss / 53657

git log --name-only improvement: show old file name in rename

Subject: git log --name-only improvement: show old file name in rename

## tl;dr

9 messages between Jun 11, 2020 and May 18, 2024.

replies: 8people: 4as markdown or json

Ed Avis· Jun 11, 2020, 11:19 UTC · lore
The git-log manual page says
       --name-only
           Show only names of changed files.

But when a file has been renamed, only the new name is printed, not the old.  I think it would be more useful and more correct to print both names.

For example
% git init
Initialized empty Git repository in /home/eda/test/.git/
% touch a
% git add a
% git commit -mx
[master (root-commit) ca81aa7] x
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a
% git mv a b
% git commit -my
[master 7b3925c] y
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename a => b (100%)
% git log --name-only -n 1
commit 7b3925c1ece26d08d79cf9f06bfcb0b38fea611f (HEAD -> master)
Author: Ed Avis <eda@waniasset.com>
Date:   2020-06-11 11:59:34 +0100
    y
b

I would expect that last log message to show the old filename a as well as the new filename b.  If you give --no-renames then both filenames are shown, of course, but I think it should be possible to detect the rename and print out both old and new names.  There is --name-status which will print more info including renames, but again I believe --name-only should also show both.  Thank you for considering this improvement request.

% git --version git version 2.26.0

-- 
Ed Avis <ed.avis@qmaw.com>
Junio C Hamano· Jun 11, 2020, 23:16 UTC · re: Ed Avis · lore

Re: git log --name-only improvement: show old file name in rename

Ed Avis <ed.avis@qmaw.com> writes:
Show 8 quoted lines
> The git-log manual page says
>
>        --name-only
>            Show only names of changed files.
>
> But when a file has been renamed, only the new name is printed, not the 
> old.  I think it would be more useful and more correct to print both 
> names. 
It is just you who thinks it would be more useful.

Scripts written by people over the last 10 years that expect to see new name would certainly hate to see two names start appearing there.

Perhaps you can use --summary at the same time?
Philip Oakley· Jun 12, 2020, 14:18 UTC · re: Junio C Hamano · lore

Re: git log --name-only improvement: show old file name in rename

@Ed On 12/06/2020 00:16, Junio C Hamano wrote:

Show 10 quoted lines
> Ed Avis <ed.avis@qmaw.com> writes:
>
>> The git-log manual page says
>>
>>        --name-only
>>            Show only names of changed files.
>>
>> But when a file has been renamed, only the new name is printed, not the 
>> old.  I think it would be more useful and more correct to print both 
>> names. 

Was this a concern that the manual did not clarify which name (old or new) was being reported? Philip

Show 7 quoted lines
> It is just you who thinks it would be more useful.
>
> Scripts written by people over the last 10 years that expect to see
> new name would certainly hate to see two names start appearing
> there.
>
> Perhaps you can use --summary at the same time?
Junio C Hamano· Jun 12, 2020, 17:03 UTC · re: Philip Oakley · lore

Re: git log --name-only improvement: show old file name in rename

Philip Oakley <philipoakley@iee.email> writes:
Show 14 quoted lines
> @Ed
> On 12/06/2020 00:16, Junio C Hamano wrote:
>> Ed Avis <ed.avis@qmaw.com> writes:
>>
>>> The git-log manual page says
>>>
>>>        --name-only
>>>            Show only names of changed files.
>>>
>>> But when a file has been renamed, only the new name is printed, not the 
>>> old.  I think it would be more useful and more correct to print both 
>>> names. 
> Was this a concern that the manual did not clarify which name (old or
> new) was being reported?
Good point.  

I am not Ed so I cannot give an answer to that question, but if we do not document what name is listed in the output, we definitely should.

Thanks.
Ed Avis· Jun 15, 2020, 07:36 UTC · re: Junio C Hamano · lore

Re: git log --name-only improvement: show old file name in rename

Thanks all for your replies to this.  I hoped that --name-only could show when a filename was removed, as well as when it was added.  If you delete a file in one commit then add it with a new name in the next, both filenames appear in the log.  If these happen in a single commit, only one does.  And in fact it's not predictable whether you will get one filename or two: it depends on rename detection.  Sometimes if a file is changed and moved to a new name, git log --name-only will show only the new name in the log, but at other times, if git doesn't detect it as a rename, both filenames appear.  This feels more like an implementation detail than a deliberate choice.

I accept that scripts may rely on the current behaviour, though I would be surprised to find a script that depended on *not* seeing the old filename printed.

Anyway, if it shouldn't change, or if it cannot change because of backwards compatibility, the manual page could be improved:
           --name-only
           Show only names of changed or added files.
           If a file is removed, its name is also printed, unless this is detected
           as a rename, in which case only the new name is printed.
That would be enough to direct users towards something more suitable like --compact-summary.
Nathan Faulkner· May 16, 2024, 23:13 UTC · re: Ed Avis · lore

Re: git log --name-only improvement: show old file name in rename

The documentation for --name-only says "Show only names of changed files." I would interpret this to mean "output the names of all files that changed", not "output the names of all files that changed, unless git detected it as renamed". --no-renames makes it behave as expected, but having to specify it isn't obvious. A warning in the documentation could help, but --no-renames should probably be included by default when --name-only is specified.

I ran into an issue today with code that expected git diff --name-only to output all changed files. A file was created and an unrelated file was deleted in the same commit, but they happened to be similar enough that git detected it as rename, and thus git diff --name-only indicated only one file changed when two files were actually changed.

Junio C Hamano· May 17, 2024, 16:00 UTC · re: Nathan Faulkner · lore

Re*: git log --name-only improvement: show old file name in rename

Nathan Faulkner <natedogith1@gmail.com> writes:
> The documentation for --name-only says "Show only names of changed
> files." I would interpret this to mean "output the names of all files
> that changed", not "output the names of all files that changed, unless
> git detected it as renamed".

Interesting observation, but we do show renamed files no? Even when there is no content changes? A quick experiment tells me it does, so "unless" is not quite correct.

    $ git mv COPYING RENAMING
    $ git diff --name-only -M HEAD
    RENAMING
    $ git diff --name-status -M HEAD
    R100	COPYING	RENAMING

I think that the source of the confusion is actually not renames or copies but that the explanation does not say in which commit the phrase "only names of changed files" applies to.

The answer to that question is: Show names of the changed paths in the post-image tree, i.e. if comparing 'diff A B' (or when 'show B' is comparing 'diff B^ B'), the names in tree B are shown.

But because that is not explicitly said, a reader can easily mislead into thinking that we are showing the union of names of files in both pre-image and post-image trees that were modified.

We'd need something like this, probably.
------- >8 ------------- >8 ------------- >8 -------
Subject: diff: document what --name-only shows

The "--name-only" option is about showing the name of each file in the post-image tree that got changed and nothing else (like "was it created?"). Unlike the "--name-status" option that tells how the change happened (e.g., renamed with similarity), it does not give anything else, like the name of the corresponding file in the old tree.

Lack of the description of this fact has confused readers in the past. Even back when dda2d79a ([PATCH] Clean up diff option descriptions., 2005-07-13) documented "--name-only", "git diff" already supported the renames, so in a sense, from day one, this should have been documented more clearly but it wasn't.

Belatedly clarify it.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/diff-options.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git c/Documentation/diff-options.txt w/Documentation/diff-options.txt
index 0e9456957e..b9eaea32d9 100644
--- c/Documentation/diff-options.txt
+++ w/Documentation/diff-options.txt
@@ -329,7 +329,8 @@ explained for the configuration variable `core.quotePath` (see
 linkgit:git-config[1]).
 
 --name-only::
-	Show only names of changed files. The file names are often encoded in UTF-8.
+	Show only the name in the before-tree of changed files.
+	The file names are often encoded in UTF-8.
 	For more information see the discussion about encoding in the linkgit:git-log[1]
 	manual page.
 
Nathan Faulkner· May 18, 2024, 00:24 UTC · re: Junio C Hamano · lore

Re: Re*: git log --name-only improvement: show old file name in rename

On 5/17/2024 12:00 PM, Junio C Hamano wrote:
Show 10 quoted lines
> Nathan Faulkner <natedogith1@gmail.com> writes:
> 
>> The documentation for --name-only says "Show only names of changed
>> files." I would interpret this to mean "output the names of all files
>> that changed", not "output the names of all files that changed, unless
>> git detected it as renamed".
> 
> Interesting observation, but we do show renamed files no?  Even when
> there is no content changes?  A quick experiment tells me it does,
> so "unless" is not quite correct.

It seems to me it's not showing the names of all files. If a file was created and a separate file was deleted, but git happens to detect it as a rename, it will only show the created file even though from my perspective both files changed.

Though even for a true rename, I'd have expected --name-only to show all paths that changed (what you want if you're trying to find code owners or determine what needs to be rebuilt).

Show 14 quoted lines
> diff --git c/Documentation/diff-options.txt w/Documentation/diff-options.txt
> index 0e9456957e..b9eaea32d9 100644
> --- c/Documentation/diff-options.txt
> +++ w/Documentation/diff-options.txt
> @@ -329,7 +329,8 @@ explained for the configuration variable `core.quotePath` (see
>   linkgit:git-config[1]).
>   
>   --name-only::
> -	Show only names of changed files. The file names are often encoded in UTF-8.
> +	Show only the name in the before-tree of changed files.
> +	The file names are often encoded in UTF-8.
>   	For more information see the discussion about encoding in the linkgit:git-log[1]
>   	manual page.
>   

That description sounds to me like it only shows files that existed in the from-commit, not any files that were created in the to-commit.

If the description is updated, it'd probably be a good idea to explicitly call out that --no-renames can be used to get the expected behavior of showing all files that changed.

This behavior can also lead to a situation where git diff --name-only stops reporting a file as changed when including a newer commit that doesn't involve the file.

$ echo '{}' > foo.json; git add .; git commit -m foo $ rm foo.json; git add .; git commit -m delete $ echo '{}' > bar.json; git add .; git commit -m bar

$ git diff --name-only HEAD~2 HEAD~1 foo.json $ git diff --name-only HEAD~1 HEAD bar.json $ git diff --name-only HEAD~2 HEAD bar.json

Junio C Hamano· May 18, 2024, 02:05 UTC · re: Nathan Faulkner · lore

Re: Re*: git log --name-only improvement: show old file name in rename

Nathan Faulkner <natedogith1@gmail.com> writes:
> That description sounds to me like it only shows files that existed in
> the from-commit, not any files that were created in the to-commit.

Sorry, this was a typo/thinko. An updated version was posted on the list after the message you are responding to.

← back to recent threads