Moving Files in Git Repository

怎甘沉沦 提交于 2021-02-07 10:56:31

问题


I want to restructure my files and folders in Git repo without losing the Histories.

The current Git repo has been migrated from SVN and it has got the SVN histories in it.

Now, when I try to move the files around the Git repo, I am losing the current Git history, but I have the old SVN histories which got migrated from SVN. But, I want to have all the histories when I move the files and folders.

I have tried git mv, log --follow, just cut and paste, etc... but nothing keeps track of the new Git histories.

I am confused from various answers around the internet. Nothing works for me unfortunately. :(

Any suggestion?

Thanks, Vashni


回答1:


Git does not track file history.

Git does track content, and keeps commit history.

What this means is that if you have some existing commits, and then you move files around and make new commits with existing commits as their history, the new commits have the old commits as their commit history.

The moved-around files have no history, but the old files had no history either. When you use git log you are looking at commit history, starting with whichever commit you name—if you do not specify a starting commit, git log starts with HEAD—and working back from there, to older commits.

This is true even if you use git log -- path: you are still looking at commit history. You have simply instructed git to show you just a subset of commit history, namely, commits where path has changed between that commit and its predecessor commit. That is, if you see commit 1234567 in the log, this means that git diff --name-status 1234567^ 1234567 would show you a change in the status of the file named by path (among any other name-and-status changes).

(The syntax commit^, which is any valid name for a commit followed by a single ^ character, means to find the commit's parent, i.e., the commit that was current just before commit was made. You can also write this as commit~1.)

When you add --follow (and name a single path), this tells git log one more thing: if the status change for the given path is a rename, git log can change the way it looks at previous commits. We already know that, since git log is showing you this commit, the git diff will show a name-and-status for that file. In most cases the status for the file will just be M, indicating that the file existed before and was modified. But if the status is R, this indicates that git diff calculated that between the parent commit and this commit, the file was renamed.

Without --follow, git log will probably no longer see the named path (because the diff computed it as having been renamed), and will stop showing commits. (It may pick up again with even-earlier commits if some other content has the same path in those earlier commits, but this depends on the earlier commits, and is not all that common.) With --follow, however, git log takes note of the fact that git diff decided, when it made the diff just now, that the file had been renamed. It then stops looking for path under that name, and starts looking instead for the path that git diff decided the content had been renamed from.

That is, suppose that git log compares older (parent) commit ab93513 to newer (child) commit 0cea944. Suppose further that git diff decides that the contents of dir1/dir2/old.txt in commit ab93513 became instead the contents of file dir8/dir9/new.txt. And, finally, suppose that you asked git log to show you dir8/dir9/new.txt with the --follow option. Then, since the change git diff computes at this point is "contents similar, rename occurred", git log switches from looking for dir8/dir9/new.txt to looking for dir1/dir2/old.txt.

The key to this process is rename detection. Since git does not track file history, it must detect the rename. Rename detection is pretty reliable, but not perfect—and it depends on how you configure git, and whether the contents of files match exactly or merely "sufficiently similarly". And --follow, in git log, only follows one path at a time (and only backwards through history—this really should work when using --reverse, but the code is that implements --follow is a horrible hack and only works in one time direction).



来源:https://stackoverflow.com/questions/36563500/moving-files-in-git-repository

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!