|--.git
|-file1
git log file1 // it will show the git history of the file
commit 61892bb913db3e9815914e062439364a33366a78 (HEAD -> main, origin/main, origin/HEAD) Author: abc 29479669 [email protected] Date: Thu May 12 16:52:57 2022 0530
Update file1
commit a9015fbb8599f2f67da593f89634a728f04eb132 Author: abc 79279569 [email protected] Date: Thu May 12 16:49:20 2022 0530
Update file1
Now I want to move file1 to a folder -> folder/file1
|-.git
|-folder ->file1
and did -
git checkout -b dummygit
git mv file1 folder/file1
git commit
git log folder/file1
commit 2596c755466152cf2d29e70bf99cabe18863a9bd9a (HEAD -> dummygit, origin/dummygit) Author: abc [email protected] Date: Wed Jul 6 23:57:11 2022 0530
moving file1 to folder
old commit history of this file is not present
How can we move file in such way that after doing git log folder/file1 still can see the old history of the file
CodePudding user response:
Create a new folder, then clone the repository in the folder with git clone , then you can delete the old folder. The new repository with contain the git commit history.
You can check out this [1]: https://johno.com/move-directory-between-repos-with-git-history
CodePudding user response:
In Git, files do not have history. Commits are history, and you can filter the history down by selecting one or more particular commits of interest.
One way to do that is to say tell me about commits in which file X changed. That is, Git looks at each commit, one at a time, backwards through time, the way Git always does:
commit 61892bb913db3e9815914e062439364a33366a78
: did file X change in this commit? (Extract parent and commit and compare file X in the two copies)commit a9015fbb8599f2f67da593f89634a728f04eb132
: did file X change in this commit? (Extract parent and commit and compare file X is the two copies)
Whenever Git comes across a commit in which file X does change—that is, the parent's copy of X is different, or even missing entirely for instance—git log
will display that commit.
That's not "file history", that's "filtered commit history", just as this isn't the Mona Lisa, it's an image of the Mona Lisa. A distinction without a difference? Well, maybe not, because ...
git log --follow
Using git log --follow -- X
, you tell git log
that it should filter history, the way it does for git log -- X
, but this time, it should check to see if the change to the file file includes the possibility that the file was renamed. If the file was renamed, git log --follow
prints the commit, just as it did earlier—but then it stops looking for X
and starts looking for O
instead where O
is the old name of the file. In other words, each test in the sequence is now did file O change in this commit instead of did file X change in this commit.
There are limitations here. The two biggest are these:
This only works "backwards". You must know the new name of the file, and run
git log --follow -- new/path/to/file
for instance.This only works for one file at a time.
A smaller (but still pretty big) limitation is that the rename detection works best if the change to the file is just the renaming. As such, it's probably best to make sure that everything is committed, then rename the file, commit that, then make any additional changes required, and commit that separately. (If you need to make changes to other files in the commit that renames the file, that's fine: that doesn't interfere with the rename detection at all. What I mean here is that, e.g., a Java class file has to have a name that matches the spelling of a lot of words in the file, so if you're renaming a Java class, you have to split it into one rename commit that won't build, followed by one update commit that fixes the file. If you use a single commit that both renames the class and fixes the file, it's possible that Git's rename detector will think that the file is so different that it wasn't merely renamed but rather deleted entirely, with a new and different file being added.)
There are no better options at this time. A future version of Git might have better ways to detect renames, but this method works now.