From: David Copeland Date: Tue, 03 Mar 2009 16:58:42 GMT Subject: Re: move files between disparate repos and maintain version history Message-ID: In-Reply-To: <20090303041300.GA18136@coredump.intra.peff.net> The first option worked, insomuch the history of diffs is preserved, but the dates are all today. The second option was a little over my head; is the idea there that you are setting up a branch that has ONLY the files I care about (with all their history), and then I pull from the other repo as if they are related? That seems like it might preserve the dates... Dave On Mon, Mar 2, 2009 at 11:13 PM, Jeff King wrote: > On Mon, Mar 02, 2009 at 12:30:58PM -0800, davetron5000 wrote: > >> So, is there a way I can move a file between two git repositories, >> maintaining the change history?  I guess it would be something like >> "apply all patches that this file was involved in, but ONLY apply the >> ones affecting this file, to the new repo, then delete from the old"? > > Yes, that's more or less how you would do it. There are actually two > separate issues, and each has two possible solutions. > > Issue 1 is moving the history to the new repo. > > One solution is, as you guessed, to export as patches and import into > the new repo: > >  cd /path/to/app >  git format-patch --stdout --root -- >~/patches >  cd /path/to/core >  git am ~/patches > > where can be a file, directory, or a list of either or both. > This should work fine if the history of that path is linear, since a > list of patches is, by definition, linear. You can see the "shape" of > the history with: > >  cd /path/to/app >  gitk -- > > The other solution is to actually rewrite a version of git history that > sees only those paths, then merge it in. That will retain the actual > shape of the history. You can do this using "git filter-branch": > >  cd /path/to/app >  # we do our work on a temporary branch >  git branch just-path >  # the actual filter; note you could do more than just grep here >  # if you wanted to munge the pathnames >  git filter-branch --index-filter ' >    git ls-files -s | grep path | >      GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info && >    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE" >  ' --prune-empty just-path > >  # you can inspect just-path at this point with "gitk just-path" >  cd /path/to/core >  # and then pull it into core's history >  git pull /path/to/app just-path > > The second issue is what you want to have happen in the "app" > repository. Presumably you no longer want the moved files there. You > _could_ filter-branch to pretend as if they were always in "core" and > never in "app". But that is probably not a good idea because: > >  1. You are rewriting history, which will make merging more complex for >     your users. > >  2. You may be breaking historical builds which expect the files to be >     there in the past. > > So I think you're probably best to just remove them with a new commit > and have the duplicated history in both. > > -Peff > > PS I think you might be able to replace the filter-branch invocation > with a fast-export / fast-import pipeline, but I haven't tried. >