问题
I've the following scenario:
- Deleted a file called src/GetData.cs in commit 1.
- Created a file called src/Get/GetDataNew.cs in commit 5.
- Renamed file in 2 to src/Get/GetData.cs in commit 7.
The files in 1 and 3 are pretty much the same with minor changes but due to several iterations, I ended up creating an entirely new file and deleting the old one. Is there any way to preserve/move git history of file 1 in file 3?
One approach that I can think of is reverting back to the commit where I deleted the old file and then using
git mv src/GetData.cs src/Get/GetData.cs
to move it to new folder but there have been a lot of other commits and changes in between so I'd like to avoid this.
Thanks in advance.
回答1:
Git does not have file history. There is nothing to preserve or restore.
Git has commits and commits are history. That's it—that's all you have. Add commits to add more history.
Now, it's true that commits contain files, and you can ask Git to walk through commit history but list only some specific commits, namely those commits that touch a particular file by name. When you do that, you immediately run into an issue with files whose names have changed over time.
This gets into what it means for some file to be "the same" file. This is a philosophical issue, which means it does not have a good answer. :-) For extreme examples of this, consider the paradox of my grandfather's axe: my father replaced the head and I replaced the handle, but this is my grandfather's axe; or more generally, the Ship of Theseus.
Git's answer is: if you add --follow
to a git log
command in which you have told it skip (for listing on output purpose) any commit that does not change the file I name, Git will look at commits where the file seems to have been deleted, and find out whether, in the parent commit, there is a file with some other name that has similar-enough content to call it "the same file". Git will always find this file (and quite quickly) if the content is 100% identical, across a single commit hop, that is not a merge commit. In other cases, you take your chances. If Git finds that the name changed, Git continues doing git log
looking for commits that changed one file, but now it is looking for commits that changed the file as stored under the previous name.
Git's other answer is: Why do you care? Each snapshot completely preserves the entire state. If you check out commit 1 or commit 7, why do you care whether src/GetData.cs
is "the same" file as src/Get/GetData.cs
? You will have the correct file contents under the correct name as preserved forever (or at least as long as the commit exists in the history) in the snapshot.
(There are sometimes reasons to care, having to do with the operating system's notions of file identity. Git does not care about those.)
来源:https://stackoverflow.com/questions/51660660/preserve-git-history-of-file-after-deleting-and-recreating-in-another-folder