Reputation: 18531
I wanted to make my original complicated question much simpler.
I have the following file in a repo:
E:\\a\b\FooOld\foo.java
I copied the file to another directory a few weeks ago with a new repo:
E:\\c\d\FooNew\foo.java
Is there a way to copy the file history of foo.java from the old repo to the new repo?
Upvotes: 6
Views: 2697
Reputation: 2191
git filter-repo
command.create an empty repo:
mkdir ~/work/new_repo
cd ~/work/new_repo
git init
add location of old repo as new repo's remote
# it can be a URL
git remote add old_upstream https://github.com/xxx/yyy
# or an local directory
git remote add old_upstream D:/work/old_repo
create branch based on you interested files/directories
git fetch
git checkout -b my_branch old_upstream/some_branch
delete all the files in current working, except the files you interest
git rm -rf build # remove the directory `build`
git rm -f README.md # remove the file `README.md`
git rm -rf . # removes all files. Do this if you know what you're doing.
Now, the working directory is clean, but the commit history still contains some files you won't want to see. let's remove them.
install git filter-repo
python -m pip install git-filter-repo
Remove git commit history items that contain specified file/directories
git filter-repo --invert-paths --path some_directory --force
git filter-repo --invert-paths --path some_file.md --force
(You may use VSCode's git-lens extension, or other tools, to compare the count of git commit history before and after each git filter-repo
command. The count number decrease as we expected).
Upvotes: 0
Reputation: 11953
It can be done, in two big steps. Let's say you have a repo A
that contains files that you want to be added on a different repo B
:
git filter-branch
to create a clone of repo A
containing only the history of the files you want to preserve.To achieve this, you can take a look at this answer if you need to preserve history of moves and renames, otherwise there are plenty of other answers on Stack Overflow that does that in a simpler way using git filter-branch
. Or you can use filter-repo, which seems to be a much faster and simpler approach to re-write history.
Important: Remember to run git filter-branch
on a clone of your repo. I also recommend running git remote rm origin
on the clone so there is no chance of pushing this stripped version to origin by accident.
Merge stripped A
into B
. In repo B
, do this:
2.1. Create a remote connection from B
to A
:
git remote add repo-A <git repository stripped A directory>
;
2.2. Pull using the option --allow-unrelated-histories
. Providing both repos are using the master
branch, the following command will merge one repo into another:
git pull repo-A master --allow-unrelated-histories
2.3. Remove the remote connection:
git remote rm repo-A
Upvotes: 9
Reputation: 490078
This is literally impossible, for the simple reason that there is no such thing as "file history" in Git. In Git, the history is simply the set of all commits. If you add commits, you add history. Whatever commits there are, those are the history. And, each commit represents a complete snapshot of all of your files (well, all the files that are in that commit, but that's a bit redundant).
You can ask git log
to show you commits that modify some particular file. The way this works is that git log
traipses along through history—backwards, through each commit, one at a time, in other words—and compares all the files in this commit to all the files in the previous commit. If the one specific file you're curious about has changed, git log
now shows this one commit. Then it moves on—or rather, back—to the previous commit, whether or not it showed this one commit, and shows, or doesn't, that commit using the same rule, and so on.
Upvotes: 1