Search code examples
gitrefactoring

How do you extract the commits of a single file into a fresh git tree?


I'm splitting out a library from an existing source tree so the library can be maintained separately.

How do you extract all the commits for one file and import them into another tree, but without all the .git/objects clutter from the original tree?

I was thinking something like this:

cd /new/tree
git init

cd /original/tree
git show --reverse  815f0f..HEAD -- lib/PDL/Opt/Simplex/Simple.pm | \
    (cd /new/tree ; git am)

but it gives errors and won't import.

I also thought of just branching, deleting everything, and then fetching the pruned branch into a new tree---but (I think) that would import all the other tree's commit data in .git/objects that would be orphaned in the new tree.

Is there a "proper" way to do this cleanly?


Solution

  • Copied from https://github.com/PDLPorters/devops/blob/master/NOTES.md#how-to-split-history:

    How to split history

    Make sure git-subtree is installed and works (if not, get from https://github.com/git/git/blob/master/contrib/subtree/git-subtree.sh and place with +x in /usr/local/libexec/git-core/git-subtree)

    # example for pdla-io-hdf
    KITCHENSINKREPO=$HOME/pdla
    KITCHENSINKDIR=IO/HDF
    SPLITOUTREPO=$HOME/pdla-io-hdf
    SPLITBRANCH=splitout
    MASTER=master
    pushd $KITCHENSINKREPO
    git subtree split -P $KITCHENSINKDIR -b $SPLITBRANCH
    git push $SPLITOUTREPO $SPLITBRANCH:$SPLITBRANCH
    git branch -D $SPLITBRANCH
    cd $SPLITOUTREPO
    git checkout $MASTER
    git reset --hard $SPLITBRANCH
    git branch -d $SPLITBRANCH
    git push origin
    popd