Subject: Re: [BUG] git-rebase unnecessarily change mtime of files

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Wed, 25 Aug 2021 14:45:30 +0200

On Wed, Aug 25 2021, Konstantin Kharlamov wrote:

> Suppose your branch has *one* commit that modified file `myfile`. When you
> interactively-rebase to that commit, mtime of that file will change even if
> though you did not change the file (i.e. commit you are on has changed the file,
> but since you're *at* this commit, not before this, there shouldn't have been
> any change to the file).
>
> This might be bad for performance; however what concerns me personally the most
> is that my editor keeps asking me "file was changed on the disk, are you sure
> you wanna modify the file?", which is confusing and annoying.
>
> I am also not completely sure, but it might be a regression, because I don't
> seem to remember having that before.
>
> # Steps to reproduce
>
>  λ mkdir foo
>  λ cd foo
>  λ git init
> hint: Using 'master' as the name for the initial branch. This default branch
> name
> hint: is subject to change. To configure the initial branch name to use in all
> hint: of your new repositories, which will suppress this warning, call:
> hint:
> hint:   git config --global init.defaultBranch <name>
> hint:
> hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
> hint: 'development'. The just-created branch can be renamed via this command:
> hint:
> hint:   git branch -m <name>
> Initialized empty Git repository in /tmp/foo/.git/
>  λ echo hello1 > file1 && git add file1 && git commit -m "1st commit"
> [master (root-commit) f1cc312] 1st commit
>  1 file changed, 1 insertion(+)
>  create mode 100644 file1
>  λ echo hello2 > file2 && git add file2 && git commit -m "2nd commit"
> [master 8bed9e1] 2nd commit
>  1 file changed, 1 insertion(+)
>  create mode 100644 file2
>  λ echo hello3 > file3 && git add file3 && git commit -m "3rd commit"
> [master e6d5aab] 3rd commit
>  1 file changed, 1 insertion(+)
>  create mode 100644 file3
>  λ stat -c %y file2
> 2021-08-25 12:37:19.008378563 +0300
>  λ rebase-at e HEAD~2     # that is `git rebase -i HEAD~2`, then [e]dit the
> commit
> Stopped at 8bed9e1...  2nd commit
> You can amend the commit now, with
>
>   git commit --amend
>
> Once you are satisfied with your changes, run
>
>   git rebase --continue
>  λ stat -c %y file2
> 2021-08-25 12:37:37.375537063 +0300
>
>
> ## Expected
>
> The mtime of the file did not change
>
> ## Actual
>
> The mtime of the file changed by 18 seconds

I don't know if this is a bug or feature, I suspect the latter.

I think you'll find that if you use a TODO list like:

    pick X <commit changes 'foo'>
    break
    pick Y <commit changes 'bar'>

You'll find that if your "foo" won't be changed, but it would with:

    edit X <commit changes 'foo'>
    pick Y <commit changes 'bar'>

This is because, as you'll see with GIT_TRACE=1 we actually check out X~
and then apply it with "edit", but with "break" we'll check out X
itself.

I didn't dig further than that, maybe it's a bug, maybe not. The code in
d87d48b2e03 (sequencer: learn about the special "fake root commit"
handling, 2018-05-04) may or may not be involved, I didn't dig much.