HOWTO use Git subtrees, I kinda think ===================================== structure of this repo ---------------------- This was created with: mkdir libs git subtree add -P libs/Big_Easy_Driver --squash git@github.com:sparkfun/Big_Easy_Driver.git master git subtree add -P libs/Adafruit-PiTFT-Helper --squash git@github.com:adafruit/Adafruit-PiTFT-Helper.git master You could also do the same thing by creating a named remote first: git remote add Adafruit-Pi-PiTFT-Helper git@github.com:adafruit/Adafruit-Pi-PiTFT-Helper.git git subtree add -P libs/Adafruit-PiTFT-Helper --squash Adafruit-Pi-PiTFT-Helper master `master` here could be a branch or a specific commit. (Notice how in the `subtree add`, I used the named remote instead of `git@github.com:adafruit/Adafruit-PiTFT-Helper.git`. This can be convenient, but it will only exist on a local copy of the repo, so it's one extra layer of confusion when explaining to people.) There's an `update_subtrees.sh`. It looks like this: #!/usr/bin/env bash git subtree pull -P libs/Big_Easy_Driver --squash git@github.com:sparkfun/Big_Easy_Driver.git master git subtree pull -P libs/Adafruit-PiTFT-Helper --squash git@github.com:adafruit/Adafruit-PiTFT-Helper.git master The reason this is in a script is that every `git subtree` command pretty much requires a prefix, a remote, and a ref. This is too much to expect anybody to remember without googling. Trust me, you'll forget it an hour after you set up the subtree the first time. If you don't put it in a script, at least document all the commands you use in your README. ![update_subtrees.sh](/imgs/update.gif?raw=true) I have tested this on Debian. It would _probably_ run on Windows in a git shell (assuming Bash), but I haven't tried that yet. what? ----- Ok, so first, **why** subtree? Lots of people I know (especially in the hardware community) seem to be dealing with dependencies between repositories lately. `git` is actually quite bad at handling this problem, to date. In fact, I'm not sure if there exists an otherwise usable VCS that's any _good_ at it. It just doesn't seem to be very much part of the model for anything. (Somebody tell me if I'm wrong about this.) There are two out of the box solutions that I'm aware of: - submodules - subtrees Of these, submodules are probably better documented and have more first-class UI. They also seem to break things a lot and confuse users pretty badly. Here's [the relevant google search][should]. I have had a real bad time with submodules, but this isn't meant as a polemic. There may be use-cases for submodules, and they may be improving as git is developed. Anyhow, subtrees: Subtrees are a fundamentally pretty different abstraction. Rather than pointing at some remote, they copy the contents (and optionally history) of a remote repository. Advantages: - users don't have to initialize anything or clone with `--recursive` to get dependencies - code's just there. - if you use `--squash`, you just wind up with one commit pointed at the target ref. - I'm guessing it's less likely to blow up in your face with a branching workflow, but who knows. Here are some writeups: - https://github.com/git/git/blob/master/contrib/subtree/git-subtree.txt - http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/ - https://medium.com/@v/git-subtrees-a-tutorial-6ff568381844 Good luck. [should]: https://www.google.com/#q=should+i+use+git+submodules