I am versioning my config files with git. Now I need to move some of my config files to a different repository, to achieve a clean structure. Is there a way I can keep the change log for a file if I move it to a different repository?

I would like to have all commits of repo A in repo B that touched file A/a if I move it to B/a. Ideally, if I afterwards move A/x to B/x, I would want to see B/a and B/x appear together in commits that touched both files in repository A. I would not expect to have any development step of A/a merged into any of the commits of B, I just want them to appear there afterwards.

Thank you, best regards

  • How do you want this to appear? Git does not keep changelogs for individual files, only for entire repositories. Do you want the file to be added to past commits? Do you want an entirely separate line of development containing just these config files to get merged into master? – Stephen Jennings Jul 16 '10 at 15:04
  • Also, which operating system are you using? – Stephen Jennings Jul 16 '10 at 15:06
  • I hope the second paragraph I added to the initial question clarifies my idea. The repositories are located on various linux distributions (I added that tag). – exic Jul 16 '10 at 17:45
  • +1 because this was an interesting question to (hopefully) solve – Stephen Jennings Jul 17 '10 at 6:58

Assume you want to transfer the history of filename.conf from one source repository to another receiving repository. I think the strategy you want to follow is:

  1. In the source repository, create a branch of commits which are re-written to contain only filename.conf.
  2. Merge the independent line of commits into a normal branch in the receiving repository.

Definitely make backups of your repositories before you do this!

In the source repository, use filter-branch to rebuild the history removing everything except filename.conf.

git checkout -b filtered-commits
git filter-branch -f --prune-empty --tree-filter 'find . -not -name filename.conf -exec rm {} \;' filtered-commits

Then, in the receiving repository:

git pull path/to/source/repo

If you also need to move the path that filename.conf is in within the repository, you'll probably need to use the --subdirectory-filter option on git filter-branch.

  • It really seems to be working. Someone should make a script out of this, catch all things that can go wrong and make it available to the whole git community :-) – exic Jul 27 '10 at 14:20
  • Yet the filter-branch command is missing an option to keep the history of filename.conf if it was moved/renamed at some point of its lifetime. (edit: no <pre> or <code> here...) – exic Jul 28 '10 at 15:23
  • This answer used to have complicated instructions for doing something Linus figured out how to do in 2005, but apparently git pull has gotten a lot smarter since then, thank goodness. – Stephen Jennings Jan 19 '13 at 0:55

I was thinking about something like this for Mercurial the other day. I think I'd write a script (probably python, but really anything that can run shell commands) to:

  1. For each revision that touched File X (call it "#rev")
    1. Copy File X from #rev to its new location
    2. Commit in the new repo with the message from #rev

It would be nice if the script could allow comment-editing and "forgetting" of some versions, where desired.

  • It also should keep date and author, I guess this script would get quite big.. maybe I'll find a way to merge single files into a new directory, hrm... anyway, thanks for your input! – exic Jul 16 '10 at 14:51

Since git filter-branch can be intolerably slow for a large repository, this trick using git log, git format-patch, and git am can be a useful alternative.


Perhaps wrong tool... git is for handling collections of files that change in some coordinated way, configuration files usually live an isolated life. Check out one-file-at-a-time VCSs, like RCS (yes, it is still around, probably even has an official package in your Linux distribution) or the new, very lightweight (and actively looked after) SRC. The last one is meant to (somewhat) work with git, it uses the same fast-import/fast-export formats, and (re)uses some of git's global or user configuration.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.