git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: move files between disparate repos and maintain version history

From
David Copeland <davetron5000@gmail.com>
Date
Mar 3, 2009, 16:58 UTC
Message-ID
<f95d47890903030858xb398b5fy1aeabb19166e6077@mail.gmail.com>
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 <peff@peff.net> wrote:
Show 67 quoted lines
> 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 -- <path> >~/patches
>  cd /path/to/core
>  git am ~/patches
>
> where <path> 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 -- <path>
>
> 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.
>
Previous: Jeff KingNext: Jeff King
Message 3 of 7 in “move files between disparate repos and maintain version history”
  1. davetron5000Mar 2, 2009
  2. Jeff KingMar 3, 2009
  3. David CopelandMar 3, 2009
  4. Jeff KingMar 3, 2009
  5. David CopelandMar 3, 2009
  6. Peter BaumannMar 3, 2009
  7. Jeff KingMar 3, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.