Cover image for Git file renaming issues (deleting/adding instead of renaming)

Git file renaming issues (deleting/adding instead of renaming)

nickytonline profile image Nick Taylor (he/him) Updated on ・2 min read

Photo by Markus Spiske on Unsplash

Hey folks, I need a little help as I've kind of reached the extend of my gitfu.

I'm working on a PR and I didn't realise at the time, but some files were committed as a deleted file (the original file) and a new file (the rename of the old file) when I renamed some of them. I was asked to ensure it's renamed in Git so as to preserve the history. Fair enough.

So if you look at the comments in the PR (I link to the first one about renaming in there), you'll see that I've done the following in a few different was but here is the gist of it:

  • Recovered the deleted file, source/libs/icons.js
  • Deleted the new file, source/libs/icons.tsx
  • Commit those changes
  • Run a git mv source/libs/icons.js source/libs/icons.tsx
  • Push to the remote, and the PR shows it as a file rename with no file changes.
  • The next commit is putting back the changes I had in source/libs/icons.tsx.
  • Push to the remote, and the PR shows that source/libs/icons.js has been deleted and source/libs/icons.tsx has been added.

I've even had one of the maintainers of the repo try to give me a hand, but he ends up in the same predicament as I do.

Any suggestions gitfolk?

Posted on by:

nickytonline profile

Nick Taylor (he/him)


Senior software engineer at DEV/Forem. Caught the live coding bug on Twitch at livecoding.ca


Editor guide

Git has no rename, just like in Linux. Git facilities a rename through heuristics of a delete and add in the same commit. The file can be modify on the other end, but if it differs to much it will consider it a new file.


See, history does know it is the same, github.com/sindresorhus/refined-gi...

But it seems the review tool or the git diff command used is recalculating the heuristics, which makes sense because git prefer to ignore individual Commits when diffing


Yeah I see that in the history. But the next commit changes the content and that's when it thinks it's an add/delete. That's what's confusing me. So as you say, it is keeping the history, it's just the diffing tool confusing me.


So one thing I noticed in the past is, both with GitHub and gitlab, it can sometimes have issues with this. I don’t know if it’s cache or what but it would be confused. It could be github/gitlab. Can you have someone else do a pull and check locally?


Sounds like this could be the case and yes, I did have someone else pull and check locally. They tried as well. Good to know that it might just be on the GitHub end.


So two things. Give it time and check later. Second is create a new repo on the same service and see what it shows. That should prove the theory.


Hey have you already found a solution of the problem? I ran to something similar in my past and solved it with reseting the branch before the renaming. Just do the renaming in one commit, and all the changes in the next one.

If you need I could showcase it for you.


In the initial post, there is a link to the PR. It's already merged now. We did it in two steps if you look at the commit history. I'm still not sure why we couldn't get it to work properly. Any insight would be great as I'd be curious for future PRs.


Hey I tinkered a little example:


GitHub only shows the rename properly if you review the specific commit. ( In the feature/rename )

But the important thing in git to follow the history of a file is the log command:
git log --oneline --follow -- new-name.txt

If you clone the repository and try this command out once in feature/rename and feature feature/delete-add you see that in the branch where the rename is lost only the last commit represents the history of the file.

I hope this explanation is detailed enough.

P.s.: You can use rebase -i to split up the commits if it is not in recent history. But keep in mind that this is a rewrite history and you can produce even more complex issue. I recommend to apply such a thing only in feature branches where so one else did build on the changed history.

If anyone is interested how the rebase approach works, I can make something up and document it as a little blog post.

P.s. (2): GitHub uses a heuristic to determine, if a file is just renamed or delted+new. I try to have a single commit to rename the files to keep the history.


A rather wild guess here, but could it be because you've changed the file type instead of the file path? I've recently made some changes to the file path and Github was able to show proper diff.


We ended doing it two PRs as they really wanted to get the PR in, but I'm definitely going to go over all the advice from @jessekphillips , @dechamp and @mgh87 . Thanks so much for chiming in to lend a hand.

And the good news is, my PR is merged!

I'm really happy about this contribution as I used the Refined GitHub extension all the time.

sindresorhus / refined-github

Browser extension that simplifies the GitHub interface and adds useful features

Refined GitHub

Browser extension that simplifies the GitHub interface and adds useful features

We use GitHub a lot and notice many annoyances we'd like to fix. So here be dragons.

Our hope is that GitHub will notice and implement some of these much needed improvements. So if you like any of these improvements, please email GitHub support about doing it.

GitHub Enterprise is also supported. More info in the options.



Mark issues and pull requests as unread
(They will reappear in Notifications)
No more jumps caused by recently pushed branches
(They are moved to the side)
Reaction avatars showing who reacted to a comment The option to wait for checks when merging a PR
Clickable references to

If you don't follow @sindresorhus yet, consider it. He's created so many amazing projects.


Happy to hear you got it fixed and merged. Glad I could help.


@nickytonline i find solution and create gist

step for fix it

  1. git filter-branch -f --tree-filter 'if [ -f old_file ]; then mkdir -p new_dir && mv old_file new_file; fi'
  2. mv old_file new_file
  3. gaa && gcmsg 'perfect'

Awesome. Thanks for sharing. 😎