The Automated Solution: Checking Out Subprojects Using Custom Scripts

After reading the previous section, you might have reasons not to copy the history of your subproject directly into a subdirectory of your application. After all, anyone can see that the two projects are separate: your application depends on the library, but they are obviously two different projects. Merging the two histories together doesn’t feel like a clean solution.

There are other ways of approaching the problem that you might like better. Let’s look at one obvious method: simply git clone the subproject into a subdirectory by hand every time you clone the main project, like this:

$ git clone myapp myapp-test
$ cd myapp-test
$ git clone ~/git.git git
$ echo git >.gitignore

This method is reminiscent of the partial checkout method in Subversion or CVS. Instead of checking out just a few subdirectories of one huge project, you check out two small projects, but the idea is the same.

This method of handling submodules has a few key advantages:

  • The submodule doesn’t have to be in Git; it can be in any version control system or just be a tar or zip file from somewhere. Since you’re retrieving the files by hand, you can retrieve them from anywhere you want.

  • The history of your main project never gets mixed up with the history of your subprojects. The log doesn’t become crowded with unrelated commits, and the Git repository itself stays small.

  • If you make changes to the subproject, you can contribute them back exactly as if you were working on the subproject by itself—because, in essence, you are.

Of course, there are also some problems that you need to deal with:

  • Explaining to other users how to check out all the subprojects can be tedious.

  • You need to somehow ensure that you get the right revision of each subproject.

  • When you switch to a different branch of your main project or when you git pull changes from someone else, the subproject doesn’t get updated automatically.

  • If you make a change to the subproject, you must remember to git push it separately.

  • If you don’t have rights to contribute back to the subproject (i.e., commit access to its repository), you may not be able to easily make application-specific changes. (If the subproject is in Git, you can always put a public copy of your changes somewhere, of course.)

In short, cloning subprojects by hand gives you infinite flexibility, but it’s easy to over-complicate things or to make mistakes.

If you choose to use this method, the best approach is to standardize it by writing some simple scripts and including them in your repository. For example, you might have a script called ./update-submodules.sh that clones or updates all your submodules automatically.

Depending how much effort you want to put in, such a script could update your submodules to particular branches or tags or even to particular revisions. You could hardcode commit IDs into the script, for example, and then commit a new version of the script to your main project whenever you want to update your application to a new version of the library. Then, when people check out a particular revision of your application, they can run the script to automatically derive the corresponding version of the library.

You might also think about creating a commit or update hook, using the techniques of Chapter 14, that prevents you from accidentally committing to your main project unless your changes to the subproject are properly committed and pushed.

You can well imagine that if you want to manage your subprojects this way, other people do, too. Thus, scripts to standardize and automate this process have already been written. One such script, by Miles Georgi, is called externals (or ext). You can find it at http://nopugs.com/ext-tutorial. Conveniently, ext works for any combination of Subversion and Git projects and subprojects.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.144.170