|Brennen Bearnes 9f01e78448 update.gif||5 年前|
This was created with:
mkdir libs git subtree add -P libs/Big_Easy_Driver --squash firstname.lastname@example.org:sparkfun/Big_Easy_Driver.git master git subtree add -P libs/Adafruit-PiTFT-Helper --squash email@example.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 firstname.lastname@example.org: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
email@example.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.)
update_subtrees.sh. It looks like this:
#!/usr/bin/env bash git subtree pull -P libs/Big_Easy_Driver --squash firstname.lastname@example.org:sparkfun/Big_Easy_Driver.git master git subtree pull -P libs/Adafruit-PiTFT-Helper --squash email@example.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.
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.
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:
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. 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:
--recursiveto get dependencies - code’s just there.
--squash, you just wind up with one commit pointed at the target ref.
Here are some writeups: