Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git stash and pop shows file no longer marked as moved?

Tags:

git

git-stash

git mv file1 file2  git status # On branch master # Changes to be committed: #   (use "git reset HEAD <file>..." to unstage) # #   renamed:    file1 -> file2  git stash git stash pop  # On branch master # Changes to be committed: #   (use "git reset HEAD <file>..." to unstage) # #   new file:   file2 # # 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:    file1 

As you can see, git loses the renamed relationship after a stash / pop. Is there any way to regain this relationship, or have stash know that files were moved? I often stash to see what my system state is like pre-changes, but having it lose the rename relationship is a problem for me. I don't know how to fix it other than deleting the new file, doing a git mv again, and replacing the new file's contents.

like image 216
Andy Ray Avatar asked Dec 13 '11 19:12

Andy Ray


People also ask

How do I resolve stash pop conflict?

But if a git stash pop conflict arises, then the problematic files won't be added to the index. Instead, Git populates the conflicted files with content from both the local working tree and the stash. The stash entry is kept in case you need it again. There's no magic remedy for such merge conflicts.

How do I restore untracked files from stash?

Retrieve the Stashed File Here, the “ls” command is used to show the list of files and folder of the repository folder, and the “git stash apply” command is used to restore the untracked files.

Can I git stash pop twice?

If you made two stashes, then just call git stash pop twice. As opposed to git stash apply , pop applies and removes the latest stash.

Does git stash pop remove?

When a developer uses the git stash apply command, the most recently saved stash overwrites files in the current working tree but leaves the stash history alone. In contrast, the pop command restores files but then deletes the applied stash.


2 Answers

If you haven't already popped your stash, do:

git stash pop --index 

This correctly preserves moved (but not committed) file relationships in a stash. According to git help stash:

If the --index option is used, then tries to reinstate not only the working tree's changes, but also the index's ones. However, this can fail, when you have conflicts (which are stored in the index, where you therefore can no longer apply the changes as they were originally).

If you've already popped your stash and want to re-create the moved relationship, do:

git rm --cached file1 

This removes the "old" unmoved file from the index:

Use this option to unstage and remove paths only from the index

like image 119
manojlds Avatar answered Sep 29 '22 01:09

manojlds


Short answer: git rm --cached file1

All git mv really does is rename the file (on the filesystem) and then add a file deletion and creation to the index (staging area). It's not specially marked. Other machinery subsequently realizes that it was a rename, by seeing that the content that was called file1 before is now called file2.

Since git stash commands modify the index, they can perturb things. Note that now you have the creation staged, but not the deletion! (Normally git-stash leaves everything unstaged after a pop, but in this case I think it doesn't have much choice but to put the new file in the index, to avoid you having no idea which one to keep. You can avoid this ever happening with git stash pop --index, but that bombs out if the stashed changes can't be cleanly applied, so it's not default.) git status can't possibly show it as a rename anymore, because the rename is effectively split between the index and the work tree, and neither section can fully claim it.

Simply run git rm --cached file1 to stage the deletion (i.e. remove file1 from the index) and it will show up as a rename again. You could also run git add -u to automatically add changes, as long as you have no other changes that you don't want to stage.

Note that this means that in practice you don't need to worry: when you properly stage everything in preparation to commit (e.g. with git add -u), the "problem" takes care of itself.

like image 43
Cascabel Avatar answered Sep 29 '22 01:09

Cascabel