7

I would like to move several directories from one git project into another one preserving their histories. The problem is, all the examples I'm seeing seem to be showing how to do extract a directory into it's own git project, preserving the history using git filter-branch. Is it possible to move these directories from one repository to another, keeping their history, if the destination repository already has other versioned files (not conflicting with the ones to be moved in any way)...?

Could somebody please show me an example of how to do this? Thanks!

carlspring
  • 31,231
  • 29
  • 115
  • 197
  • Please specify how you want the merged history to look like: Commits ordered by date, one project after another, ...? – krlmlr Jul 30 '13 at 18:12
  • @krlmlr: Could you please show me examples of both, or either? I think by date would be fine. – carlspring Jul 30 '13 at 21:37
  • My comment was just to point at a glitch in the specification of the problem. Does this help you: http://stackoverflow.com/q/1425892/946850? – krlmlr Jul 30 '13 at 21:49

2 Answers2

1

Answering my own question with this little script I knocked up in bash (make sure you read it first and have backed up your files):

#!/bin/bash

gitURL=$1
project=$2
srcProjectBaseDir=$3
destProjectBaseDir=$4

# Remove stale checkouts in order to do a clean clone
rm -rf ${srcProjectBaseDir}

git clone --no-hardlinks $gitURL ${srcProjectBaseDir}
cd ${srcProjectBaseDir}
git remote rm origin

# These make sure your extracted module is called as the directory's name.
# If this is of no interest to you, comment out these three lines and you
# should be alright.
mkdir temp
git add temp
git mv ${project}/ temp/

git commit -m "Refactoring: Isolated files for filter-branch."

git filter-branch --subdirectory-filter temp HEAD

git add .
git commit -m "Refactoring: Filter branched."


if [ ! -d ${destProjectBaseDir} ]; then
    mkdir ${destProjectBaseDir}
    cd ${destProjectBaseDir}
        git init
    cd ..
fi

cd ${destProjectBaseDir}
git remote add repositoryAbranch ${srcProjectBaseDir}
git pull repositoryAbranch master
git remote rm repositoryAbranch

This script is based on most of the instructions seen here (with a few additions).

carlspring
  • 31,231
  • 29
  • 115
  • 197
0

You can do this with git subtree split and git subtree add/merge. Say your source repository is at ~/source and you want to move ~/source/subdir into ~/target at some (possibly the same) location in that git repository:

cd ~/source
git subtree split -P subdir -b split/subdir
cd ~/target
git remote add source ../source
git fetch source split/subdir
git subtree add source/split/subdir -P new_subdir

Later on, if the source has updated stuff you can do the exact same steps again except the final step, which becomes git subtree merge rather than git subtree add (with the same parameters).

The split and add/merge command don't need to be used together. You can merge in a whole repository that wasn't first split, and you can also just take the split branch and turn it into a repository, by cloning from that branch:

cd ~
git clone source/ -b split/subdir subdir
cd subdir
g remote add git@github.com/Me/MyNewProject
etc.
TamaMcGlinn
  • 2,840
  • 23
  • 34