Maintaining Drupal with fake Git submodules

With Drupal moving to the Git version control system, I'm looking at refining a good way to install, update, and customize Drupal installations using Git.

Since Drupal core, modules, and themes will be separate Git repositories, it seems like using Git submodules, or subtrees are worth looking into for module and theme management.

Several of the drivers behind Drupal's movement to Git are strongly recommending the use of Git submodules for module and theme management. Along those lines, here's one of the better practical guides to using submodules :

Still, submodules have always seemed clunky to me, with potential land mines if you miss a command in the update sequence. Maybe I'm just not used to them.

But then I came across a post about using fake submodules.

In the following example, I first clone a bare repository of Drupal core. At the moment, I like the idea of having three different branches :

1) Drupal core (core)
2) Drupal contrib (contrib themes and modules)
3) My custom stuff (custom)
4) Merged version (master) of all branches

Although you can keep things separate to a degree with directories, I like the idea of separate branches to see what I've done.

To do this, you need to start from a 'bare' repository and create these separate branches.

In a Drupal context you would do :

$ git clone git://  
$ cd drupal
$ git log --reverse                   (find first commit)
$ git checkout 9ff3094c36bd9          (checkout first commit)
$ git checkout -b null                (create 'null' branch)
$ git rm index.php                    (drop sole file from first commit)
$ git commit -am "Create truly null branch"
$ git tag NULL                        (create NULL tag)
$ git tag | grep ^7.0-beta            (find 7.0 tags)
$ git branch merged 7.0-beta2         (create new local branch from tag)
$ cd sites/all/modules
$ mkdir contrib                       (we'll store contrib modules here)
$ cd $_
$ git checkout null                   (start contrib branch from null)
$ git checkout -b contrib             (create contrib branch)
$ git clone git://
$ git add views/                      (add views Git repo - need final /)
$ git commit -m "Add views/ repository"
$ cd views
$ git branch -va                      (notice we're in Views repo)
$ git checkout remotes/origin/7.x-3.x (get 7.x-3.x version of Views)
$ git checkout -b views7.x-3.x        (create new local branch)

In this case, the branch 'merged' is the combined branch including Drupal core, contrib, and any customizations. Leave the 'master' branch to Drupal core.


There are 3 Comments

Thank you for this article!

Just found one typo here - it should be
git log --reverse instead of git log -reverse

$ git clone git://
$ cd drupal
$ git log --reverse (find first commit)

Yes, this is corrected now. 'Long' arguments are preceded by two dashes.