Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Adding subdirectory of a remote repo to a subdirectory in local repo

This is way more complicated than it should be. The following conditions need to be met :

  1. need to be able to track and merge in upstream changes
  2. don't want remote commit messages in master
  3. only interested in sub-directory of another repo
  4. needs to go in a subdirectory in my repo.

In this particular case, I'm interested in bringing in the 'default' template of jsdoc as a sub-directory in my project so I could potentially make changes to the markup it genereates while also being able to update from upstream if there are changes. Ideally their template should be a separate repo added to jsdoc via a submodule -- this way I could fork it and things would be much easier.... but, it is what it is.

After much struggling with git, subtree and git-subtree, I ended up finding this http://archive.h2ik.co/2011/03/having-fun-with-git-subtree/ -- it basically sets up separate branches from tracking remote, the particular sub-directory, and uses git subtree contrib module to pull it all togther. Following are the commands, modified for my use case :

Initial setup...

# add jsdoc remote, create new tracking branch, 
git remote add -f jsdoc-upstream git@github.com:jsdoc3/jsdoc.git
git checkout -b upstream/jsdoc jsdoc-upstream/master

# split off subdir of tracking branch into separate branch
git subtree split -q --squash --prefix=templates/default --annotate="[jsdoc] " --rejoin -b merging/jsdoc

# add separate branch as subdirectory on master.
git checkout master
git subtree add --prefix=jsdoc-template --squash merging/jsdoc

Fetching upstram

# switch back to tracking branch, fetch & rebase.
git checkout upstream/jsdoc 
git pull jsdoc-upstream/master

# update the separate branch with changes from upstream
git subtree split -q --prefix=templates/default --annotate="[jsdoc] " --rejoin -b merging/jsdoc

# switch back to master and use subtree merge to update the subdirectory
git checkout master
git subtree merge -q --prefix=templates/default --squash merging/jsdoc

May I never have to google this again. I still haven't tried merging upstream yet, guess I'll cross that bridge when I get to it.

@PGrothaus
Copy link

PGrothaus commented Sep 6, 2018

May I never have to google this again.

I'm so glad for finding this. Thanks a lot! Super helpful.

@zepptron
Copy link

zepptron commented Sep 26, 2018

May I never have to google this again.

this! a thousand times this! thanks for sharing

@fatfatson
Copy link

fatfatson commented Jan 17, 2020

how to push modify to upstream?

@rob101
Copy link

rob101 commented Mar 12, 2020

Following your commands verbatim, I get 'templates/default' does not exist; use 'git subtree add' is it missing a step?

@ChristianUlbrich
Copy link

ChristianUlbrich commented Jun 15, 2020

@fatfatson
The other way around. Split a sub-dir as a sub-tree from current branch and merge it into the remote tracking branch upstream. Sadly there is not enough margin to fit the commands in here. :)

@tswaters
Copy link
Author

tswaters commented Jun 17, 2020

I'll be honest, I haven't used this since I spent the afternoon 2 years ago figuring it all out.

If I needed to do something like this these days, it would likely involve using git worktree and manually moving upstream changes from a remote branch into my real worktree.

Life is too short to mux around with flakey git commands 😀

@mcsherrylabs
Copy link

mcsherrylabs commented Sep 4, 2020

Following your commands verbatim, I get 'templates/default' does not exist; use 'git subtree add' is it missing a step?

@rob101 Me too. Did you find a solution?

@diegocn
Copy link

diegocn commented Nov 16, 2020

I do not know about the details of the project itself, but the current template folder seems to be packages/jsdoc/templates/default.

@artu-hnrq
Copy link

artu-hnrq commented May 1, 2021

Very nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment