Stuart P. Bentley
Stuart P. Bentley

Reputation: 10675

How can I make a a subdirectory in my GitHub project into a new repository?

I recently moved a couple of subdirectories in a project of mine on GitHub, and I was curious about the best way to clone a subdirectory into a new project. Specifically, I want any mentions of issues in the commit messages for these new projects to point to the old project.

Upvotes: 2

Views: 880

Answers (1)

Stuart P. Bentley
Stuart P. Bentley

Reputation: 10675

Despite hype around new commands like git subtree split, the best way to make a new Git project from a subdirectory of an old Git project is still to clone the project, then use git filter-branch --subdirectory-filter to rewrite the project's history to only include the given subdirectory.

However, with GitHub, there's still a little more work to do- if you're taking commits from an old project into a new repository, you may have references in your commit messages to issues from that original repository (such as Fixes #3). If you're going to re-use these commits in another project, you'll need to convert them to explicit references to issues in the original repository (such as Fixes stuartpb/mothership#3), so that the "new" commits in the separated project will be linked to that original issue, and won't get linked to any of the new project's issues.

Luckily, git filter-branch provides an option to filter commit messages as well, so we can do all this in just a few commands:

  • $WORK_DIR refers to the directory you want to check your project out to.
  • $SUB_DIR is the subdirectory you want to convert to a separate project.
  • $ORIGINAL_REPO is the username-and-repo-name of the project with the subdirectory you're splitting.
  • $NEW_REPO is the username-and-repo-name you want to push the new repo to.

The commands, from start to finish:

git clone https://github.com/$ORIGINAL_REPO $WORK_DIR && cd $WORK_DIR
git filter-branch --subdirectory-filter $SUB_DIR --msg-filter 'sed -re
  "s=(^| )(#[0-9]+)=\1'$ORIGINAL_REPO'#\2"=g' -- --all
git remote set-url origin [email protected]:$NEW_REPO.git
git push -u origin master

Upvotes: 4

Related Questions