As I clarify code, I rename and edit a file *so much* that git doesn't recognize it as a rename.

A fix: commit rename of old file; then, commit the new file.

How can I do this nicely with git, *after* all the editing?

---

`git stash` doesn't recognize the new filename.

Currently I do this:

* move the new file elsewhere
-`git reset oldfile` to get the old file
* rename it
* commit it
* now, get the new file back, overwriting the above
* commit that

I've described that as one file, but usually it's many files, in different directories. I don't know about you, but for me it's so easy to accidently overwrite and lose the new versions... which aren't commited yet, so no `reflog` rescue.

This seems *just* the kind of thing git could help me with... 

*EDIT* I could commit it to a temp branch, for `reflog` safety.
['https://Stackoverflow.com/questions/56877001', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4930344/']
Git doesn't provide a really nice way to do this, but this works. Assumptions:

* `foo` is the old name of the file, and the name the modified file still has on disk
* `bar` is the new name you want it to have
* There are no changes staged in the index

Then do:

```
git update-index --add --cacheinfo "$(git ls-files --full-name -s foo \
    | awk '{print $1 "," $2 ",bar"}')"
git rm --cached foo
git commit -m "rename foo to bar"
mv foo bar
git add bar
git commit -m "make changes to bar"

```

The `git update-index` tells git to stage a new file in the index with the same hash and mode as the indexed version `foo`, but a new name `bar`. It doesn't consult the disk, it just assumes an object exists with that hash (which it does). The `git rm --cached` tells git to stage a removal of `foo` without touching the disk. Together, they make up a rename, which we can commit. Then we move the file for real, use `git add` to inform git about its new contents, and commit again. Naturally you can also add other changes to this commit.

in between the `git update-index` and the `mv`, `git status` will show an un-staged change of `deleted: bar` because the file exists in the index but not on disk (at least not yet under that name), but this isn't a problem.

Note that the name `bar` has to be a path relative to the root of the repository, even if you're operating from a sub-directory. For simplicity, operate from the repo root and use the full path for both `foo` and `bar`.

None of this is really *simpler* than what you're doing, but it does avoid the need to revert changes from your working tree.
I guess it will sound simplistic, but the simplest solution is: When you're editing a file, and have a bunch of pending edits, and you decide the file needs to be renamed, 

(1) make a note that you need to rename it
(2) get the file to a state where you can commit the changes you have
(3) commit it
(4) rename it
(5) commit the rename
(6) if necessary, continue editing

That is - if you don't want to commit a rename at the same time as you commit changes to the affected file... then don't.

In a very few cases, there may be a reason to commit a rename with a change. For example, a public class name in Java should match its filename. But that's fine - the rename detection change threshold isn't (by default) 100% match anyway. Small changes will rarely hurt anything. But that's not really the issue, because you've already decided you want to do separate commits.

So the issue is just a little bit of planning ahead. At the moment you're going to rename a significantly edited file (or significantly edit a renamed file), that's the moment to decide "oh, I'll want to separate this next step into a different commit from what I've already done".

If you really can't do that, then stash is actually fine. Stash your edits, rename the file, commit, pop the stash. Yes, the popped file will be at the wrong path, so rename it again (overwriting the original).

By the way, depending on your workflow this may all be for naught. A merge will not look at the individual commits and will see exactly the same situation as if you had done everything in one commit. If you use a rebase-driven workflow you might find that it really does help (though that has other costs). But overall I'd say there are other strategies that do more to reduce this problem - such as making sure divergent branches are short lived so taht any conflict resolution is kept to a minimum even when rename detection is not successful.