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

Re: git mv after the fact

From
Junio C Hamano <gitster@pobox.com>
Date
May 28, 2026, 20:36 UTC
Message-ID
<xmqq5x47jmpm.fsf@gitster.g>
In-Reply-To
<1FEDBC47-5DDB-4C42-A7C7-695630D330BF@gmail.com>
Ben Knoble <ben.knoble@gmail.com> writes:
Show 27 quoted lines
>> Le 27 mai 2026 à 19:24, Junio C Hamano <gitster@pobox.com> a écrit :
>> 
>> Chris Torek <chris.torek@gmail.com> writes:
>> 
>>>> Chris Torek <chris.torek@gmail.com> writes:
>>>>> A flag for "git mv" would be convenient (and slightly moreefficient ...
>>>> 
>>> 
>>> On Tue, May 26, 2026 at 8:09 PM Junio C Hamano <gitster@pobox.com> wrote:
>>>> May be convenient, but I do not get the "efficient" part.
>>> 
>>> A normal `git mv` renames the index entry and the file in the working
>>> tree without running `git add` on the *contents*, so there's no new hash
>>> computation.  Presumably a `git mv --after foo bar` would do the same: verify
>>> that there is no existing `bar` in the index, that there is an existing `foo` in
>>> the index, and that there is no `foo` but there is a `bar` in the working tree,
>>> and then it would rename (add-and-remove, really, because of sorting)
>>> the index entry, without scanning the working tree contents.
>>> 
>>> In other words, we skip reading the 3 terabyte file, or whatever.
>> 
>> Yup, that matches what I wrote.  We do not rehash and we only write
>> the index just once.
>
> One thing I wondered: if we don’t have an exact move but assume (by not hashing), doesn’t that mean the index would differ from what’s on disk? I originally thought that might be a problem, but the more I thought the more I realized that’s a fairly typical state anyway.
>
> Just seemed like a potential footgun to me, but perhaps not worth worrying about. 

Good point. Actually with or without --after/--cached, we do not have to rehash, and more importantly, we should not rehash.

As you can do this already
    $ date >old.txt
    $ git add old.txt
    $ date >>old.txt
    ... now old.txt is _dirty_
    $ git mv old.txt new.txt

I do not think it is unusual to have the contents you have in your working tree files diverge from the contents you last 'git add'ed to the index. You do *not* want to rehash. The index entry for new.txt must be left not-up-to-date, which is achieved in the above sequence by retaining the file timestamp of old.txt at the "git add" time even after "git mv" (i.e. new.txt has the timestamp and size of the old.txt after it got the second "date" output, the index entry records one generation old one, and would not match). If we do the "index-entry only" move, i.e.

    $ date >old.txt
    $ git add old.txt
    $ date >>old.txt
    ... now old.txt is _dirty_
    $ mv old.txt new.txt
    ... oops, we forgot to tell git
    $ git mv --cached old.txt new.txt

we need to make sure that we leave the cache entry dirty for new.txt in the index.

Previous: Ben KnobleNext: Tim Tassonis
Message 9 of 10 in “git mv after the fact”
  1. Frieder HannenheimMay 26, 2026
  2. Chris TorekMay 26, 2026
  3. Frieder HannenheimMay 26, 2026
  4. Ben KnobleMay 26, 2026
  5. Junio C HamanoMay 27, 2026
  6. Chris TorekMay 27, 2026
  7. Junio C HamanoMay 27, 2026
  8. Ben KnobleMay 28, 2026
  9. Junio C HamanoMay 28, 2026
  10. Tim TassonisMay 27, 2026

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.