francesco
francesco

Reputation: 7539

move some files from a git repository to a new one

I have a git repository which, essentially, contains two related projects, which I would like now to split. I would like to move the files related to one project to a new repository, preserving the history of changes. To be concrete, let us suppose that the original git repository contains:

file1.c
file2.c
subdir/file2_extra.c

Also, the original git repository contains several branches. I want to keep onlly some of them, those related with the files I want to separate.

How can I create a new git repository containing, say, file2.c and subdir/file2_extra.c only, together with the history of commits to them?

Notice that the files I want to separate are not found in a separate directory. For otherwise, I think one can use git subtree.

I tried to use git filter-branch, without success. Let us assume the original repository is git_original, what I have tried is

$ git clone git_original/ git_new
Cloning into 'git_new'...
done.
$ cd git_new
$ git rm file1.c
rm 'file1.c'
$ git filter-branch --prune-empty -- --all
Cannot rewrite branches: Your index contains uncommitted changes.

But if I commit the removal of file1.c, then git filter-branch does not do anything.

Upvotes: 2

Views: 164

Answers (1)

francesco
francesco

Reputation: 7539

Based on this link (thanks to @marekful for providing this) I have devised this solution. The main idea is to clone the repository into a new one, and eliminate the unwanted files in each commit. I am assuming one has a remote repository, and each local branch tracks the corresponding remote branch.

Clone the old repository into a new one.

$ git clone git_original/ git_new

Go into the new repository.

$ cd git_new

For each desired branch in the new repository set up a branch.

$ git branch -t branch_name origin/branch_name

Delete every unwanted file in the new repository. E.g., in the example of the question, I wanted to delete the file file1.c.

$ git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch file1.c' \
      --prune-empty -- --all

The option -f should be necessary if you delete more than one file, as it forces to overwrite the "old" refs.

By a git checkout to all the branches of the new repository, you can check that indeed the unwanted files have been eliminated.

Some cleanup.

$ git reflog expire --expire=now --all
$ git gc --prune=now --aggressive

Now, remove the old origin and associate with a new remote repository.

$ git remote rm origin
$ git remote add origin remote_origin_address

Finally push everything to the new remote.

$ git push -u origin --all
$ git push -u origin --tags

Upvotes: 2

Related Questions