Moving a directory with history from one repository to another while renaming

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I'm sure this has come up before, and I'm sure the answer is 
git-filter-branch.

I have repositoryA, which has a subdirectory, say "repoA_directory", and I've 
done some development in it.  I now wish I'd done this development in a 
different repository, repositoryB and that it would have been in a different 
directory, "sub/dir/repoB_directory".

What's the best way to do this?

*** Stop press (I tried a bit harder before sending the above email) ***

This is what I did, and am reporting here for future googlers; and in case 
you're all interested in git-filter-branch success stories (which, 
incidentally is a fabulous little tool).

In repositoryA...

 git-filter-branch --subdirectory-filter "repoA_directory" directoryonly

Now, the branch "directoryonly" contains repoA_directory (and history) as a 
new root commit, and as the root directory of the repository.

 git checkout directoryonly
 git-filter-branch --tree-filter "mkdir -p sub/dir/repoB_directory; \
    mv file1 file2 file3 sub/dir/repoB_directory" directorymoved

Now, the branch "directorymoved" contains repoA_directory (and history) alone, 
moved to "sub/dir/repoB_directory".

In repositoryB...

 git-fetch /path/to/repositoryA directorymoved:repoAbranch

repositoryB now contains a new, independently rooted, branch containing only 
sub/dir/repoB_directory.  We would ideally at this point just rebase that 
independent branch to the appropriate point in the main development branch of 
repoB, but we can't because repoAbranch doesn't share a common ancestor with 
any of the repositoryB branches.

That is to say, we have these two branches:

 * --- * --- * --- * --- * (master)

             B --- * --- * (repoAbranch)

but we want:

 * --- * --- * --- * --- * (master)
                          \
                           B --- * --- * (repoAbranch)

Find the commit hash of the first commit in repoAbranch, B, and apply that one 
commit as a patch to your mainline branch (probably making a temporary branch 
on your way, to preserve your current master)

 git checkout -b temp
 git show --pretty=email hash-of-B | git-am

 * --- * --- * --- * --- * (master)
                          \
                           B' (temp)

             B --- * --- * (repoAbranch)

We've now got a commit that will serve as a common ancestor.

 git-rebase --onto temp hash-of-B repoAbranch
 git-branch -D temp

 * --- * --- * --- * --- * (master)
                          \
                           B' --- *' --- *' (repoAbranch)

                           B  --- *  --- *  [orphan branch]

Voila. repoAbranch is now the original repoA_directory, but stored at 
sub/dir/repoB_directory and includes the development history.

git-gc --prune will get rid of the orphan branch if you're bothered about the 
storage.



Andy
-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@xxxxxxxxx
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux