Edit: Since this post was created, I’ve since changed my Drupal development workflow (again) and would no longer recommend this approach. Instead, we’re now using a versioned drush-make script and aegir. A new workflow post is coming, eventually.
Edit: Since making this post, I’ve dropped this workflow and moved to one where Drupal Core is a submodule – this avoids storing it in the local repository but requires some directory symlinks to work correctly. See the post: Drupal project workflow and version control with git – now 90% less complicated!
The side-project that has my most direct attention at the moment is a Drupal 7 site that will provide a forum for discussion, social interaction, and event planning for a gaming guild. Since I’m going to be learning and working with Drupal 7 for my job, I figured it would be useful to leverage the experience I’d be gaining for the benefit of one of my projects. Although in my opinion Drupal’s forum offerings have been lackluster in the past (I can’t speak to their current state yet since it’s been a few years since I last paid any serious attention to the state of Drupal’s Forum module), I feel like the more flexible platform Drupal provides will be a significant enough benefit that I should base the project on Drupal instead of trying to add features to software that is a forum at its core.
One of the first issues I encountered was setting up a version control system for the project. There were several challenges and conditions I was hoping to meet with the selection of the version control setup. Specifically, I was hoping to be able to pull updates from Drupal’s own repository (as they maintain a stable branch), I was hoping to avoid storing Drupal Core code in my own repository (since that would just be inflating the size of my project repository), I was hoping for the ability to include sub-repositories since the project might involve writing custom Drupal modules that really should be in their own separate areas as they’re small projects in their own right, and finally I wanted the system to be a DVCS because then my development machine would be a free repository backup.
I’ve used Mercurial in the past and have been pretty happy with, but the tool of choice for the Drupal development team seems to be git. After reading about several variations on workflows, I finally settled on one that seems good:
- Clone the Drupal Core into a new git repository.
git clone --branch 7.x http://git.drupal.org/project/drupal.git MyProjectName
This leaves us with the Drupal Core as the origin remote.
- Pick the tag you want to run, and check it out. If you want to run development, check out the appropriate version branch (such as 7.x) instead. Note that this will cause Drupal’s auto update system to complain that it doesn’t recognize your version. In my case, I want to run the most recent stable 7.x release, not the development head:
git tag -l git checkout 7.8
- Rename the origin remote to upstreamor something similar. We’ll use this remote to pull in updates from the Drupal Core repository when an update is released so that we don’t have to worry about downloading and unpacking tarballs over our existing site.
git remote rename origin upstream
- (Optional) Disable pushing to upstream. In general, without the correct permissions you’ll be unable to push to the Drupal branch you cloned. However, in the case that you actually were to have the permissions to make changes to Drupal, or if you just want your repository configuration to be as clean as possible, you should rename the branch you checked out so it does notshare a name with its tracking branch on upstream (by default, a branch will think it can push to any identically named branch on the associated remote). In this example:
git branch -m 7.x drupal-7.x
Now, if you run
git remote show upstreamyou’ll notice that the local branch no longer has an entry for ‘git push’.
- Create a new branch master and switch to it
git checkout -b master
git branch master git checkout master
- (Optional) Set up a new origin remote if you have a remote repository you usually push to. In my situation, I’m using a gitolite repository, but the instructions for something like github should be similar. First we want to push our local repository. This should only be done into an empty remote repository. Optionally, also push tags to the remote repository – although be aware this will copy all of the Drupal project tags as well, so you may wish to forgo this part.
git push --all theRemoteRepoString git push --tags theRemoteRepoString
Then we want to set up origin and tracking:
git remote add --track master origin theRemoteRepoString
- This method, while useful, will result in (relatively) large repositories, since you’re also mirroring the Drupal development repository. If you want to avoid this, there are other options, such as maintaining your own “drupal” branch, and extracting the packaged Drupal updates into it. This might be useful in a situation where the size is of a concern, or you’re maintaining multiple installations of the project and can justify the effort needed to maintain the branch yourself, since it loses the ability to simply update by doing
git pullon the upstream branch.
- It would be ideal if there were a way to make this work without re-storing the Drupal files in the local repository since they’re managed by a different repository. While that would technically be more correct, I have no idea how you would accomplish that.
- Even if you push with the –mirror option in step 6, other developers working on the project will not get the upstream remotes that you’ve configured. This might not be an issue, as you may only want to have one developer responsible for updating things from upstream, but if you do, you’ll either need to copy (not clone, copy) the local repository set up, or have each developer configure the upstream and the upstream tracking branch. There could potentially be a solution that involves git hooks, but I don’t know what it is. That said, the branch containing drupal itself will track from that branch on your own server, so when a developer pulls from upstream and commits, other developers will still get those changes from your server.
- This workflow is good, but not ideal in my opinion. If you know a better workflow, tell me!