Copy a file from one repository to another with its history

Viewed 172

I would like to copy a list of files from a given directory in a repository A to repository B with its commit history.

The internet is full with solutions for copying a full directory with all its content: Git: Copy history of file from one repository to another or https://mattsch.com/2015/06/19/move-directory-from-one-repository-to-another-preserving-history/

Those solution assumed I would like to copy all files in a subdirectory, which is not my case. I would like to copy a subset of files from a directory with its commit history from one repository to another.

For example: I would like to copy https://github.com/carla-simulator/scenario_runner/blob/master/srunner/examples/catalogs/EnvironmentCatalog.xosc to another repository B and to place it there at root (./).

The suggested solution from @jingx solved almost this problem.

Using

git am <the-patch-files>

the file will be placed in repository B at B/examples/catalogs/EnvironmentCatalog.xosc instead of B/EnvironmentCatalog.xosc

After moving the files to the "right" place, an additional commit is needed due to this directory change.

Unfortunately I was unable to do this using this method above.

How can I solve this problem?

1 Answers

In principle you could do:

git format-patch --root -- file1 file2 etc.

Which will generate a series of *.patch files. Then in the new repo you would do:

git am <the-patch-files>

You might run into issues however if your repo has some complex history though, e.g. merges and file moves involving some of the files on your list.

Another solution would be to use git filter-history to rewrite the entire history, and essentially remove any files that you do not want to keep. You'd still need to deal with merges and file moves though.

[Edit] You can manipulate the target path, to some extent, to which a patch is applied by using -p and --directory with git am. For example, in the scenario you added, git am -p3 0001.patch would put file EnvironmentCatalog.xosc under the project root, and git am -p3 --directory alt 0001.patch would put it under alt/.

The big caveat here is of course that both the number you give to -p, and the path to --directory will vary from commit to commit. And it's not going to work if you have a commit with multiple files, each under different subdirectories at different levels.

Related