|
|
- 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
|