I am trying to move a single file (call it foo.txt) from one repository to another (unrelated) repository, preserving its history. ebneter's question shows how to do this for a subdirectory. taw's question has some hints and suggestions, but not a step-by-step procedure to follow. jkeating's question looked promising, but didn't work for me. Google searches came up empty for this particular use case. What I am looking for is a clear sequence of commands to accomplish this.
The sequence of commands I started to follow was this:
$ git clone source-repo/ source-repo-copy $ cd source-repo-copy $ git filter-branch --tree-filter 'test ! "$@" = "foo.txt" && \ git rm --cached --ignore-unmatch $@ || true' --prune-empty
The logic of my filter command is to git rm
all files that are not foo.txt. I added the || true
to the command to force it to have a zero return value to satisfy filter-branch.
My intention was to set source-repo-copy as a remote for my target repository (target-repo), and assuming git filter-branch
filtered out everything but foo.txt, fetch and merge source-repo-copy into target-repo. Unfortunately, the git filter-branch
command seemed to have no effect. It ran with no errors and appeared to grind through the 600+ commits in source-repo, but when it finished, the git log
and files in source-repo-copy looked the same. Shouldn't all files but foo.txt be missing and all commits that didn't touch it be gone from the log?
At this point I don't know how to proceed. Any suggestions?
Navigate to the repository you just cloned. Pull in the repository's Git Large File Storage objects. Mirror-push to the new repository. Push the repository's Git Large File Storage objects to your mirror.
This worked for me, but with a whole directory.
As shown here
~$ cd neu ~/neu$ git filter-branch --subdirectory-filter FooBar HEAD ~/neu$ git reset --hard ~/neu$ git remote rm origin ~/neu$ rm -r .git/refs/original/ ~/neu$ git reflog expire --expire=now --all ~/neu$ git gc --aggressive ~/neu$ git prune ~/neu$ git remote add origin git://github.com/FooBar/neu.git
EDIT: For a single file:
Filter the directory first:
git filter-branch --prune-empty --subdirectory-filter myDirectory -- --all
Filter the single file:
git filter-branch -f --prune-empty --index-filter "git rm --cached --ignore-unmatch $(git ls-files | grep -v 'keepthisfile.txt')"
Do some cleanup:
git reset --hard git gc --aggressive git prune
This should do it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With