Thanks to the extraordinary amount of Open Source ActionScript projects it is very common that we handle 3-4 different external libraries per project. PureMVC, Signals, GTween... How do you keep track of all that?!
SVN has externals
and GIT has submodules
. The idea is simple: make your project by a composition of other projects.
This is a mini tutorial / note to self post on how to do it for GIT, mostly a mix and match of Git Submodules: Adding, Using, Removing, and Updating
, Using git submodules to track plugins
, this tutorial
and the official documentation.
Some important stuff to keep in mind:
* A submodule is just get a GIT repository within another GIT repository.
* When you add a submodule you are not only adding its files, you also add a pointer to the specific commit at the time you added it
. Let's say your repo is in revision 10 and the submodule is in revision 100. After sometime you need to update the submodule to revision 101. Once you do that, you need to also update the pointer of the main repository to the submodule, so it's pointing to the latest version, not the initial one when you added the submodule. Sorry, can't express that better! We'll see how to do this in a moment.
* You have to manually force an update on the submodule to get its latest changes, as opposed to SVN externals where an update in the main repository automatically triggers an update in the submodule. IMHO, this is good
, cause it prevents undesired updates.
Enough talking, let's go for it.
Let's assume you have your MAIN repository running and that you want to add AS3 signals
as a submodule in lib/signals
[code lang="bash"]git submodule add git://github.com/robertpenner/as3-signals.git lib/signals
git commit -m "Adding AS3 signals as a submodule."[/code]
That's it, you got yourself a copy of AS3 signals straight from the main repository. Now let's say a new feature gets added or a bug is fixed. You need to update your submodule. Remember, you have to manually do this. To update a specific submodule just browse to it and run a pull:
[code lang="bash"]cd lib/signals
That has brought you the updates of the submodule, but you also have to tell GIT you are keeping those changes
. To do so, go back to the root folder and commit (what you commit is a new pointer to a different commit in the submodule repository):
[code lang="bash"]cd ../../
git commit -a -m "Updating submodule because bla bla"[/code]
Cloning a project with submodules is a little bit different that usual, but no problem if done correctly. The issue is that when you clone the submodule its head is "detached", is not pointing to a branch. To avoid so run the following when cloning a project with submodules:
[code lang="bash"]git clone project/path/or/url
git submodule update --init
git checkout master
git config submodule.lib/signals.update merge
# we are using lib/signals as the name, cause that's where we checked it out[/code]
This way when you run updates you won't need to re-check out the branch you were in.
Once the project is correctly checked out and new changes are coming other devs get the submodule updates using:
[code lang="bash"]git pull # to update the pointer
git submodule update # to get the actual update[/code]
If you make a mistake while adding the submodule sadly there's no single command to remove a it, you have to do it by hand (got this from How to remove a git submodule
* Edit both .gitmodules and .git/config and remove the lines corresponding to the submodule you want to remove.
[code lang="bash"]git rm --cached lib/signals
rm -rf lib/signals
git commit -a -m "Removing signals as a submodule"[/code]
Also, if you need to setup a SVN repository as a GIT module, read Is it possible to have a subversion repository as a git submodule?
Basic GIT stuff as the bonus track:
[code lang="bash"]# change gedit for "mate" or your text editor of choice
git config core.editor "gedit"
# set up credentials for this project only
git config user.name "You Name Here"
git config user.email "email@example.com"[/code]
Set up Beyond Compare as your editor for GIT diffs using this lamescript