user16316067
user16316067

Reputation: 179

How do I move files to a new location in my Git repository without losing their history?

Last week I created a new Git repository, and got to work. Now I noticed that all files I've created are in the root and not in a src folder. I've been searching since last night for a way to move the files without losing its history.

Manually moving them means Git will consider them to be new files without any history.

Using git mv means the files at the new location will still be considered new files. The only difference is the history still exists, but is associated to the file in the old location.

I figured Git must store an index of where files are stored somewhere. I found the aptly named file index in the .git folder contained the file names. After adding a test file in a subfolder, I saw that the path is stored along with the file name. So I manually edited index and moved the file.

In my Git client, I saw that the moved file is not considered a change. So far, so good. However, if I look at the commit history, the file is still considered to be located in the root.

Next, I read that there's such a thing as a Git cache. Supposedly, you can clear it using git rm --cache. However, this doesn't work on Windows, returning a cryptic error: fatal: No pathspec was given. Which files should I remove?.

At this point, I'm out of ideas. How do I solve this problem?

Upvotes: 1

Views: 624

Answers (3)

user16316067
user16316067

Reputation: 179

To do this, you can use a tool called git-filter-repo. It's hosted at https://github.com/newren/git-filter-repo

Upvotes: 0

matt
matt

Reputation: 535139

Files don't have "history". The history is something that Git constructs in real time by following the parent chain (from one commit to its parent to its parent to its parent...) and calculating a diff between them.

If you simply drag the files into their new folder and do an add-and-commit, you will have done everything you can do in this regard. With luck, the fact that you didn't change the actual filenames, and that the files' contents were not changed as part of this commit, will mean that when you do a git log --follow -- my-file-path, the history of the file will be constructed in the way you desire.

Upvotes: 2

Marcus Müller
Marcus Müller

Reputation: 36346

Using git mv means the files at the new location will still be considered new files

Yes, technically, you add a new file and delete an old one in the same commit, but that is transparent to most git utilities, for example

git log --follow src/filename.c

will still show all the history. It does make inherent sense to consider changing the place of a file a change to be committed just as much as a change of content.

So, there's really no need to solve any problems arising from that: git mv is a very usual occurrence, and it's what you do when you change the place of a file, and it's what you should be using.


All the things you do within the .git directory: Don't. Things you can't do with the git command line are very likely to be bad ideas. In your case, you broke the index's compatibility with the actual work tree (and potentially changed hashes). Not once in my time as developer would have that been the right thing to do.

Upvotes: 4

Related Questions