# Stash does not save rename information

6 messages from 2019-12-14 to 2019-12-16. Participants: Chrissy Wainwright, Kyle Meyer, Bryan Turner, Jeff King.
Thread: https://gitlist.dev/t/52460

## Chrissy Wainwright, 2019-12-14 19:41

Subject: Stash does not save rename information
Message-ID: <296B296B-EBA0-4F1E-AFEA-ADC232E84656@sixfeetup.com>
URL: https://gitlist.dev/e/296B296B-EBA0-4F1E-AFEA-ADC232E84656%40sixfeetup.com

```
This seems to be a bug:
 
	1	Use `git mv` to rename a file
	2	`git status` shows the file was renamed
	3	Stash the changes
	4	Pop the stash
	5	`git status` shows the file change as deleted/new file instead of a rename


Thanks
Chrissy Wainwright
 
-- 
Six Feet Up, Inc.
Python & Cloud Expert Consulting 
Direct Line: +1 (317) 861-5948 x(604)
Email: chrissy@sixfeetup.com
https://sixfeetup.com
 


```

## Kyle Meyer, 2019-12-14 23:00

Subject: Re: Stash does not save rename information
Message-ID: <87immizf55.fsf@kyleam.com>
URL: https://gitlist.dev/e/87immizf55.fsf%40kyleam.com
In-Reply-To: <296B296B-EBA0-4F1E-AFEA-ADC232E84656@sixfeetup.com>

```
Chrissy Wainwright <chrissy@sixfeetup.com> writes:

> This seems to be a bug:
>  
> 	1	Use `git mv` to rename a file
> 	2	`git status` shows the file was renamed
> 	3	Stash the changes
> 	4	Pop the stash
> 	5	`git status` shows the file change as deleted/new file instead of a rename

You can see very similar behavior with just a deleted file rather than a
deleted/new file pair (which is displayed as a rename depending on your
configuration):

    $ git init
    $ touch foo && git add foo && git commit -mfoo
    $ git stash
    $ git stash apply
    Removing foo
    On branch master
    Changes not staged for commit:
    	    deleted:    foo

    no changes added to commit

I believe the key thing is that by default 'git stash {apply,pop}' will
apply your change to the working tree but not the index [*].  If you
pass the --index flag, you should see the behavior you're after:

    $ git reset --hard
    HEAD is now at c023af6 foo
    $ git stash apply --index
    Removing foo
    On branch master
    Changes to be committed:
    	    deleted:    foo


[*] When I initially tried your example, I was confused that the new
    file was added to the index by default, but it seems new files
    receive special treatment, as Jeff King mentions at
    https://lore.kernel.org/git/20161206142446.5ba3wc625p5o6nct@sigill.intra.peff.net/

```

## Kyle Meyer, 2019-12-14 23:05

Subject: Re: Stash does not save rename information
Message-ID: <87fthmzewl.fsf@kyleam.com>
URL: https://gitlist.dev/e/87fthmzewl.fsf%40kyleam.com
In-Reply-To: <87immizf55.fsf@kyleam.com>

```
Kyle Meyer <kyle@kyleam.com> writes:
>
>     $ git init
>     $ touch foo && git add foo && git commit -mfoo

Sorry, I forgot to paste in the `git rm foo` step here.

>     $ git stash
>     $ git stash apply
>     Removing foo
>     On branch master
>     Changes not staged for commit:
>     	    deleted:    foo
>
>     no changes added to commit

```

## Chrissy Wainwright, 2019-12-16 14:32

Subject: Re: Stash does not save rename information
Message-ID: <EF4FE28C-1111-46C7-9EDE-24940E8A5727@sixfeetup.com>
URL: https://gitlist.dev/e/EF4FE28C-1111-46C7-9EDE-24940E8A5727%40sixfeetup.com
In-Reply-To: <87fthmzewl.fsf@kyleam.com>

```
Thank you, using --index does work! Now the trick is to actually remember to use it in this case, since it doesn't seem the change can be restored if you forget to use it the first time you pop/apply.

Then the fix is to `git mv` the files back to the original name, and to the new name again.

Thanks
Chrissy Wainwright
 
-- 
Six Feet Up, Inc.
Python & Cloud Expert Consulting 
Direct Line: +1 (317) 861-5948 x(604)
Email: chrissy@sixfeetup.com
https://sixfeetup.com
 

﻿On 12/14/19, 5:05 PM, "Kyle Meyer" <kyle@kyleam.com> wrote:

    Kyle Meyer <kyle@kyleam.com> writes:
    >
    >     $ git init
    >     $ touch foo && git add foo && git commit -mfoo
    
    Sorry, I forgot to paste in the `git rm foo` step here.
    
    >     $ git stash
    >     $ git stash apply
    >     Removing foo
    >     On branch master
    >     Changes not staged for commit:
    >     	    deleted:    foo
    >
    >     no changes added to commit
    


```

## Bryan Turner, 2019-12-16 18:42

Subject: Re: Stash does not save rename information
Message-ID: <CAGyf7-G7yFpGwwv2E72pGW_WjeYkLRh4sFdP+6E-dn2Gm+T8ow@mail.gmail.com>
URL: https://gitlist.dev/e/CAGyf7-G7yFpGwwv2E72pGW_WjeYkLRh4sFdP%2B6E-dn2Gm%2BT8ow%40mail.gmail.com
In-Reply-To: <EF4FE28C-1111-46C7-9EDE-24940E8A5727@sixfeetup.com>

```
On Mon, Dec 16, 2019 at 6:32 AM Chrissy Wainwright
<chrissy@sixfeetup.com> wrote:
>
> Thank you, using --index does work! Now the trick is to actually remember to use it in this case, since it doesn't seem the change can be restored if you forget to use it the first time you pop/apply.

You could create a Git alias for it, if that helps.

>
> Then the fix is to `git mv` the files back to the original name, and to the new name again.

That shouldn't be necessary. Really all you need to do is stage the
parts of the change that "git stash apply" didn't automatically stage
as part of restoring them. "git add -a" would likely do it, but may
also stage other things. A simple "git add foo" (based on the names
from your example) should also do it:

$ git init foo
Initialized empty Git repository in /.../foo/.git/
$ cd foo
$ touch foo && git add foo && git commit -m "Initial commit"
[master (root-commit) 934d270] Initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo
$ git mv foo bar
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    foo -> bar

$ git stash
Saved working directory and index state WIP on master: 934d270 Initial commit
$ git stash apply
Removing foo
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   bar

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    deleted:    foo

$ git add foo
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    foo -> bar

On some older versions of Git you may need to use "git add -f foo" to
add the deleted file, but at least on 2.20.1, what I happen to be
running locally, it's not necessary.

With or without "-f", all you really need to do is update what parts
of the change are staged; you don't need to (essentially) revert and
reapply the change.

One other thing I think may be worth clarifying, just in case it's not
know, is in relation to the subject: "Stash does not save rename
information." Git itself does not track renames, at all, in any
commands. git mv does not somehow record renames; it's just a
simplification for:
mv foo bar
git rm foo # or git add foo to stage the deletion
git add bar

You can confirm that easily:
$ git reset --hard HEAD
HEAD is now at 934d270 Initial commit
$ mv foo bar
$ git rm foo
rm 'foo'
$ git add bar
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    foo -> bar

$ git reset --hard HEAD
HEAD is now at 934d270 Initial commit
Lafiel:foo bturner$ mv foo bar
Lafiel:foo bturner$ git add foo bar
Lafiel:foo bturner$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    foo -> bar

Git uses heuristics to "pair up" deletions and adds into probable
renames. If you rename a file and change it significantly as part of
the same commit, Git will not consider it a rename. Similarly, if you
rename multiple similar files in a single commit, paired with some
changes to those files, Git may pair up the "wrong" combinations (i.e.
if you rename A to X and B to Y, "git diff" may show renaming A to Y
and B to X).

Hope this helps,
Bryan Turner

>
> Thanks
> Chrissy Wainwright

```

## Jeff King, 2019-12-16 19:25

Subject: Re: Stash does not save rename information
Message-ID: <20191216192554.GB2678964@coredump.intra.peff.net>
URL: https://gitlist.dev/e/20191216192554.GB2678964%40coredump.intra.peff.net
In-Reply-To: <EF4FE28C-1111-46C7-9EDE-24940E8A5727@sixfeetup.com>

```
On Mon, Dec 16, 2019 at 02:32:31PM +0000, Chrissy Wainwright wrote:

> Thank you, using --index does work! Now the trick is to actually
> remember to use it in this case, since it doesn't seem the change can
> be restored if you forget to use it the first time you pop/apply.

I think this is a spot where git-stash could be a little friendlier. If
you've stashed index changes and "git stash pop", then those index
changes are not applied but get thrown away, losing information.

It would be nicer if "stash pop" noticed that there are entries in the
stashed index that do not match HEAD or the stashed working tree, and
applied as requested but _didn't_ remove the stash (with a message that
you can get your index changes out with "--keep-index").

Maybe a good small project for somebody looking to get their feet wet
with contributing to Git (you, or anybody else reading this).

-Peff

```
