Last updated September 27, 2016. Created on August 17, 2009.
Edited by steniya, Sharanc25, catch, alpritt. Log in to edit this page.

This page is now outdated since Drupal.org has its own git repository

Here's one workflow for creating and maintaining Drupal core patches using git. Check out general git documentation including http://git-scm.com/documentation and http://cheat.errtheblog.com/s/git/.

The instruction here are abbreviated and assume you are already reasonably expert with ssh, Drupal cvs, etc.

Set-up steps

  • Install a current version of git (even the Ubuntu 9.04 distro has a somewhat out-of-date version). "sudo apt-get install git-core", or compile from source.
  • Configure git, including:
    • git config --global --add push.default tracking
    • git config --global --add alias.co checkout
    • git config --global --add alias.ci commit
  • sign up for a github account and supply your ssh pubkey
  • Go to http://github.com/drupal/drupal and click the "Fork" button to make your own copy. This will mean your patches will show up as being related to other forks of the drupal repo. Note https://github.com/mikl/drupal/ is deprecated since it was built with a cvs export that has funky Id tags due to a Debian bug. Using the drupal/drupal repo removes the need for the gitfixer script described at the bottom of this page. Note, however, the master branch at drupal/drupal is named 'CVS' not 'master' as is usual for git.
  • On your fork find "Your Clone URL:", and copy it. This is [url] and clone a local copy using
    git clone [url]
    after a little while you will now have a local directory named drupal. You can rename this if desired.
  • List your local branches using
    git branch
  • List your remote branches using
    git branch -r
  • Check the status of your working directory with
    git status

You may also want to add a .gitignore file so that git status command ignores files that you know are supposed to be untracked. Add this file at the top of the cloned repo. A reasonable starting version is:

sites/default/settings.php
sites/default/files
sites/default/private
.gitignore

You don't want any of these files under revision control since they should not appear in your patches.

Make a new remote branch and a new local tracking branch

Let's assume you are working on issue http://drupal.org/node/654321, let's prepare a new branch for this patch.

  • Make a remote branch based on your master (which is Drupal CVS HEAD):
    git push origin +CVS:654321
    note that for easy reference we name the branch after the issue nid. Older versions of git may need a different command.
  • Make a local tracking branch
    git co --track -b 645321 origin/654321
    (not we aliased co for checkout). You should see output like:
    Branch 654321 set up to track remote branch 654321 from origin.
    Switched to a new branch '654321'

    Current versions of git will support a shortcut for this:
    git co --track origin/654321
  • Apply your patch (or start hacking). As soon as you have a meaningful change make a local commit. Git is different than svn or cvs that you must either specifically use git add to indicate which changed files to commit, or pass the -a flag to commit all local changes.
  • Prepare a patch to post to drupal.org (note: if you've been working a while, see the keeping in sync steps below).
  • git diff --no-prefix upstream/CVS > description-654321-1.patch

Keep your forked repo and patches in sync

The drop keeps moving, so you will want to pull in new commits to Drupal cvs HEAD. These commits will show up in the drupal git repo, so you want to pull them into your master and patch branches. This essentially follows the steps here: http://github.com/guides/keeping-a-git-fork-in-sync-with-the-forked-repo

  • git remote add upstream git://github.com/drupal/drupal.git
  • git fetch upstream
  • Now you can list your remote branches and you'll see upstream as well as origin.
  • We are keeping "master" as a clean copy of Drupal core. To merge changes from Drupal HEAD into your master branch, make sure you working copy is clean:
    git status
    Then switch to your master branch and pull in updates and push them up to github:
    git co CVS
    git pull upstream CVS
    git push
  • To update your patch branch:
    git co 654321
    git merge CVS
    assuming no conflicts:
    git push

Make a patch

git fetch upstream
git diff --no-prefix upstream/CVS

Gotchas

Note - this section is no longer relevant if you are using the drupal github repo vs. the mikl repo (both are managed by Mikkel)

Somehow the cvs to git process ends up altering the $Id strings at the top of files. this can lead to patches that don't apply to a cvs checkout if the patch includes that part of a file, or if you are removing a whole file.

example CVS:

<?php
// $Id: menu.inc,v 1.348 2009/10/01 19:07:12 dries Exp $

git:

<?php
// $Id: menu.inc,v 1.348 2009-10-01 19:07:12 dries Exp $

You can fix a git patch applying a bash script like this (gitfixer.sh):

#!/bin/bash
sed -E -i"~" -e "s/($Id: .+ )([0-9]{4})-([0-9]{2})-([0-9]{2})/\1\2\/\3\/\4/g" $1

run as : ./gitfixer.sh myissue.patch

This will leave the original as myissue.patch~

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

flickerfly’s picture

In my git ignore I prefer to use a something like this site/*/settings.php. This allows more flexibility should you be dealing with a multi-site setup.

seutje’s picture

isn't it more interesting to use the .git/info/exclude file, as that is not tracked by default, so u don't also have to exclude the .gitignore file itself?

or perhaps even add them to system-wide exclude?