Skip to content

Instantly share code, notes, and snippets.

@dwilliamson
Last active December 20, 2021 19:38
Show Gist options
  • Save dwilliamson/e9b1ba3c684162c5a931 to your computer and use it in GitHub Desktop.
Save dwilliamson/e9b1ba3c684162c5a931 to your computer and use it in GitHub Desktop.
Workflow for using git subtree on Windows
To include a library as a subtree, follow these steps:
1. Add the project as a remote
git remote add <remote-name> <source-repo>
2. Fetch the remote
git fetch <remote-name>
3. Add the project
git subtree add --prefix "path/to/project" <remote-name> <remote-branch-name> --squash
Notes about this process:
* Path separators must be forward-slash as Windows git breaks otherwise. To allow this, quote paths.
* Using SourceTree to achieve this currently doesn't work because it will pass back-slashes.
* Afterwards, SourceTree won't list the subtree until you try to "Add/Link" it from its UI.
* Squashing the commits (--squash) reduces all source repo commits to one simple commit (doesn't spam your main list).
To push changes made in the subtree upstream to the source repo, use:
git subtree push --prefix "path/to/project" <remote-name> <remote-branch-name>
If the upstream repo currently has <remote-branch-name> checked out, THIS WILL FAIL. So instead, make sure the source
repo has an extra branch to receive any pushes.
Suggested pattern:
* Have "develop" and "master" branches.
* In the upstream/source repo, always work on "develop".
* In downstream/dependent repo, always push to "master".
Assuming you have "master" in the upstream/source repo checked out, it's a simple case of merging back to "develop" to
have everything synced up again:
git checkout develop
git merge master
Pulling remote changes is a little simpler:
git subtree pull --prefix "path/to/project" <remote-name> <remote-branch-name> --squash
Again, the commits are squashed.
@dougbinks
Copy link

Thanks for the write-up, although I've been using git for a while I'm only just moving over to using subtrees from a manually managed set of repos under a common root.

For branches, I would use "projectname" rather than "master" for development under a subtree structure when using a repo from a project which gets used elsewhere. This is especially useful if your subtree repo is a fork, as it's otherwise easy to make mistakes when pulling from the original repo.

@dougbinks
Copy link

RE: SourceTree

I've discovered that SourceTree does work if you type the folder in manually and use relative paths rather than the full path, and use forward rather than backslashes.

@dwilliamson
Copy link
Author

Yeah, if you baby-feed the SourceTree dialogue it all works. But by that point its use becomes pretty pointless :) I find it easier to work from the CLI and then select Add/Link once the subtree is setup. At that point, at least, forward/back & absolute/relative seem to all work.

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