{"thread":{"id":"52460","subject":"Stash does not save rename information","startedAt":"2019-12-14T19:41:30Z","lastAt":"2019-12-16T19:25:56Z","messageCount":6,"participants":["Chrissy Wainwright","Kyle Meyer","Bryan Turner","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"388213","messageId":"296B296B-EBA0-4F1E-AFEA-ADC232E84656@sixfeetup.com","threadId":"52460","inReplyTo":null,"subject":"Stash does not save rename information","fromName":"Chrissy Wainwright","fromEmail":"chrissy@sixfeetup.com","sentAt":"2019-12-14T19:41:22Z","receivedAt":"2019-12-14T19:41:30Z","isPatch":false,"sender":{"key":"chrissy@sixfeetup.com","avatar":null},"body":"This seems to be a bug:\n \n\t1\tUse `git mv` to rename a file\n\t2\t`git status` shows the file was renamed\n\t3\tStash the changes\n\t4\tPop the stash\n\t5\t`git status` shows the file change as deleted/new file instead of a rename\n\n\nThanks\nChrissy Wainwright\n \n-- \nSix Feet Up, Inc.\nPython & Cloud Expert Consulting \nDirect Line: +1 (317) 861-5948 x(604)\nEmail: chrissy@sixfeetup.com\nhttps://sixfeetup.com\n \n\n"},{"id":"388216","messageId":"87immizf55.fsf@kyleam.com","threadId":"52460","inReplyTo":"296B296B-EBA0-4F1E-AFEA-ADC232E84656@sixfeetup.com","subject":"Re: Stash does not save rename information","fromName":"Kyle Meyer","fromEmail":"kyle@kyleam.com","sentAt":"2019-12-14T23:00:38Z","receivedAt":"2019-12-14T23:00:45Z","isPatch":false,"sender":{"key":"kyle@kyleam.com","avatar":"https://avatars.githubusercontent.com/u/1297788?v=4"},"body":"Chrissy Wainwright <chrissy@sixfeetup.com> writes:\n\n> This seems to be a bug:\n>  \n> \t1\tUse `git mv` to rename a file\n> \t2\t`git status` shows the file was renamed\n> \t3\tStash the changes\n> \t4\tPop the stash\n> \t5\t`git status` shows the file change as deleted/new file instead of a rename\n\nYou can see very similar behavior with just a deleted file rather than a\ndeleted/new file pair (which is displayed as a rename depending on your\nconfiguration):\n\n    $ git init\n    $ touch foo && git add foo && git commit -mfoo\n    $ git stash\n    $ git stash apply\n    Removing foo\n    On branch master\n    Changes not staged for commit:\n    \t    deleted:    foo\n\n    no changes added to commit\n\nI believe the key thing is that by default 'git stash {apply,pop}' will\napply your change to the working tree but not the index [*].  If you\npass the --index flag, you should see the behavior you're after:\n\n    $ git reset --hard\n    HEAD is now at c023af6 foo\n    $ git stash apply --index\n    Removing foo\n    On branch master\n    Changes to be committed:\n    \t    deleted:    foo\n\n\n[*] When I initially tried your example, I was confused that the new\n    file was added to the index by default, but it seems new files\n    receive special treatment, as Jeff King mentions at\n    https://lore.kernel.org/git/20161206142446.5ba3wc625p5o6nct@sigill.intra.peff.net/\n"},{"id":"388217","messageId":"87fthmzewl.fsf@kyleam.com","threadId":"52460","inReplyTo":"87immizf55.fsf@kyleam.com","subject":"Re: Stash does not save rename information","fromName":"Kyle Meyer","fromEmail":"kyle@kyleam.com","sentAt":"2019-12-14T23:05:46Z","receivedAt":"2019-12-14T23:05:52Z","isPatch":false,"sender":{"key":"kyle@kyleam.com","avatar":"https://avatars.githubusercontent.com/u/1297788?v=4"},"body":"Kyle Meyer <kyle@kyleam.com> writes:\n>\n>     $ git init\n>     $ touch foo && git add foo && git commit -mfoo\n\nSorry, I forgot to paste in the `git rm foo` step here.\n\n>     $ git stash\n>     $ git stash apply\n>     Removing foo\n>     On branch master\n>     Changes not staged for commit:\n>     \t    deleted:    foo\n>\n>     no changes added to commit\n"},{"id":"388258","messageId":"EF4FE28C-1111-46C7-9EDE-24940E8A5727@sixfeetup.com","threadId":"52460","inReplyTo":"87fthmzewl.fsf@kyleam.com","subject":"Re: Stash does not save rename information","fromName":"Chrissy Wainwright","fromEmail":"chrissy@sixfeetup.com","sentAt":"2019-12-16T14:32:31Z","receivedAt":"2019-12-16T14:32:36Z","isPatch":false,"sender":{"key":"chrissy@sixfeetup.com","avatar":null},"body":"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.\n\nThen the fix is to `git mv` the files back to the original name, and to the new name again.\n\nThanks\nChrissy Wainwright\n \n-- \nSix Feet Up, Inc.\nPython & Cloud Expert Consulting \nDirect Line: +1 (317) 861-5948 x(604)\nEmail: chrissy@sixfeetup.com\nhttps://sixfeetup.com\n \n\n﻿On 12/14/19, 5:05 PM, \"Kyle Meyer\" <kyle@kyleam.com> wrote:\n\n    Kyle Meyer <kyle@kyleam.com> writes:\n    >\n    >     $ git init\n    >     $ touch foo && git add foo && git commit -mfoo\n    \n    Sorry, I forgot to paste in the `git rm foo` step here.\n    \n    >     $ git stash\n    >     $ git stash apply\n    >     Removing foo\n    >     On branch master\n    >     Changes not staged for commit:\n    >     \t    deleted:    foo\n    >\n    >     no changes added to commit\n    \n\n"},{"id":"388288","messageId":"CAGyf7-G7yFpGwwv2E72pGW_WjeYkLRh4sFdP+6E-dn2Gm+T8ow@mail.gmail.com","threadId":"52460","inReplyTo":"EF4FE28C-1111-46C7-9EDE-24940E8A5727@sixfeetup.com","subject":"Re: Stash does not save rename information","fromName":"Bryan Turner","fromEmail":"bturner@atlassian.com","sentAt":"2019-12-16T18:42:49Z","receivedAt":"2019-12-16T18:43:05Z","isPatch":false,"sender":{"key":"bturner@atlassian.com","avatar":"https://gravatar.com/avatar/16bcf3167981c1ef7c804e502642366d888a35b0d0b0a4ca01fdc442aa1acb1e?d=mp&s=160"},"body":"On Mon, Dec 16, 2019 at 6:32 AM Chrissy Wainwright\n<chrissy@sixfeetup.com> wrote:\n>\n> 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.\n\nYou could create a Git alias for it, if that helps.\n\n>\n> Then the fix is to `git mv` the files back to the original name, and to the new name again.\n\nThat shouldn't be necessary. Really all you need to do is stage the\nparts of the change that \"git stash apply\" didn't automatically stage\nas part of restoring them. \"git add -a\" would likely do it, but may\nalso stage other things. A simple \"git add foo\" (based on the names\nfrom your example) should also do it:\n\n$ git init foo\nInitialized empty Git repository in /.../foo/.git/\n$ cd foo\n$ touch foo && git add foo && git commit -m \"Initial commit\"\n[master (root-commit) 934d270] Initial commit\n 1 file changed, 0 insertions(+), 0 deletions(-)\n create mode 100644 foo\n$ git mv foo bar\n$ git status\nOn branch master\nChanges to be committed:\n  (use \"git reset HEAD <file>...\" to unstage)\n\n    renamed:    foo -> bar\n\n$ git stash\nSaved working directory and index state WIP on master: 934d270 Initial commit\n$ git stash apply\nRemoving foo\nOn branch master\nChanges to be committed:\n  (use \"git reset HEAD <file>...\" to unstage)\n\n    new file:   bar\n\nChanges not staged for commit:\n  (use \"git add/rm <file>...\" to update what will be committed)\n  (use \"git checkout -- <file>...\" to discard changes in working directory)\n\n    deleted:    foo\n\n$ git add foo\n$ git status\nOn branch master\nChanges to be committed:\n  (use \"git reset HEAD <file>...\" to unstage)\n\n    renamed:    foo -> bar\n\nOn some older versions of Git you may need to use \"git add -f foo\" to\nadd the deleted file, but at least on 2.20.1, what I happen to be\nrunning locally, it's not necessary.\n\nWith or without \"-f\", all you really need to do is update what parts\nof the change are staged; you don't need to (essentially) revert and\nreapply the change.\n\nOne other thing I think may be worth clarifying, just in case it's not\nknow, is in relation to the subject: \"Stash does not save rename\ninformation.\" Git itself does not track renames, at all, in any\ncommands. git mv does not somehow record renames; it's just a\nsimplification for:\nmv foo bar\ngit rm foo # or git add foo to stage the deletion\ngit add bar\n\nYou can confirm that easily:\n$ git reset --hard HEAD\nHEAD is now at 934d270 Initial commit\n$ mv foo bar\n$ git rm foo\nrm 'foo'\n$ git add bar\n$ git status\nOn branch master\nChanges to be committed:\n  (use \"git reset HEAD <file>...\" to unstage)\n\n    renamed:    foo -> bar\n\n$ git reset --hard HEAD\nHEAD is now at 934d270 Initial commit\nLafiel:foo bturner$ mv foo bar\nLafiel:foo bturner$ git add foo bar\nLafiel:foo bturner$ git status\nOn branch master\nChanges to be committed:\n  (use \"git reset HEAD <file>...\" to unstage)\n\n    renamed:    foo -> bar\n\nGit uses heuristics to \"pair up\" deletions and adds into probable\nrenames. If you rename a file and change it significantly as part of\nthe same commit, Git will not consider it a rename. Similarly, if you\nrename multiple similar files in a single commit, paired with some\nchanges to those files, Git may pair up the \"wrong\" combinations (i.e.\nif you rename A to X and B to Y, \"git diff\" may show renaming A to Y\nand B to X).\n\nHope this helps,\nBryan Turner\n\n>\n> Thanks\n> Chrissy Wainwright\n"},{"id":"388295","messageId":"20191216192554.GB2678964@coredump.intra.peff.net","threadId":"52460","inReplyTo":"EF4FE28C-1111-46C7-9EDE-24940E8A5727@sixfeetup.com","subject":"Re: Stash does not save rename information","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2019-12-16T19:25:54Z","receivedAt":"2019-12-16T19:25:56Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Dec 16, 2019 at 02:32:31PM +0000, Chrissy Wainwright wrote:\n\n> Thank you, using --index does work! Now the trick is to actually\n> remember to use it in this case, since it doesn't seem the change can\n> be restored if you forget to use it the first time you pop/apply.\n\nI think this is a spot where git-stash could be a little friendlier. If\nyou've stashed index changes and \"git stash pop\", then those index\nchanges are not applied but get thrown away, losing information.\n\nIt would be nicer if \"stash pop\" noticed that there are entries in the\nstashed index that do not match HEAD or the stashed working tree, and\napplied as requested but _didn't_ remove the stash (with a message that\nyou can get your index changes out with \"--keep-index\").\n\nMaybe a good small project for somebody looking to get their feet wet\nwith contributing to Git (you, or anybody else reading this).\n\n-Peff\n"}]}