The Git for Developers page on Moodle.org is pretty helpful in getting you started in developing for the Moodle LMS platform. However if you need to use Git on Windows for your Moodle development, there are some differences as the Git for Developers page often assumes you are using Git on Linux.

This page summarizes how Moodle developers can use Git on Windows to create fixes and patches for Moodle core code however much of it could be applied to other open source projects on GitHub.

This article covers the following topics:

Setting Up Your Moodle Development Environment

Other tools that you might find useful include:

Configuring Git

Once you've installed Git for Windows, enter the following commands in Git Bash, replacing your name and email address:

$ git config --global user.name "Your Name"

$ git config --global user.email yourmail@domain.tld

$ git config --global core.filemode false

Forking and Cloning Moodle

Start by forking the official Moodle project into your GitHub account. This is done by logging into GitHub, going to the official Moodle project page and clicking on the Fork button near the upper right corner of the page.

The next step is to create a local copy. This will be the copy you will be working on. If you plan on actually running this copy, you will need to make a seperate clone for each version of Moodle as the database is different for each version and it isn't changed when you switch Moodle versions.

The process is called cloning your Moodle project. This will make a local copy of your Moodle project from your GitHub account. You can do this in Git Bash using the following command:

$ git clone git@github.com:YOUR_GITHUB_USERNAME/moodle.git LOCALDIR

…where YOUR_GITHUB_USERNAME is your username on GitHub and LOCALDIR is the path to the folder where you will keep your Moodle files.

Next provide git with the original source for the Moodle repository:

$ git remote add upstream git://git.moodle.org/moodle.git

Should you ever get confused as to which is upstream and which is origin, use the following command to display the information:

$ git remote -v

Using Notepad++, edit the .git/config file under your new local Moodle folder and add the following lines:

[alias]
  updatefix   = !sh -c 'git checkout $0 && git rebase $1 && git checkout $1 && git push origin -f $0 -'

  updatefixes = !sh -c 'git checkout $0 && git branch | grep -v $0 | grep -v Sandbox | xargs -i git updatefix "{}" $0 -'

This will create a new git command called git updatefixes which will be used to rebase all of your branches except master and sandbox. More on this later.

Integrating WinMerge in to Git

You can use WinMerge as your merge tool. Use the following commands from the Git Bash prompt to add these settings to your .gitconfig file (this only needs to be done one time):

On 32-bit Windows:

$  git config --global mergetool winmerge

$  git config --global mergetool.winmerge.cmd “'C:/Program Files/WinMerge/WinMergeU.exe' "$MERGED"”

On 64-bit Windows:

$  git config --global mergetool winmerge

$  git config --global mergetool.winmerge.cmd “'C:/Program Files (x86)/WinMerge/WinMergeU.exe' "$MERGED"”

Integrating Notepad++ in to Git and Other Useful Tweaks for Bash

Add the following lines to your %HOMEPATH%\.bashrc :

alias ls='ls -F --color --show-control-chars'

alias ll='ls -l' alias less='less -r'

alias edit='/c/Program Files/Notepad++/notepad++'

cd /driveLetter/pathToMoodle

If you are on a 64 bit version of Windows, the alias edit line will be:

alias edit='/c/Program Files (x86)/Notepad++/notepad++'

Tip: From within Git Bash, you'll be able to access this file using the following command:

$ edit ~/.bashrc

Tip: Should you feel more comfortable at the DOS Command prompt, adding the following path to the Windows PATH environment variable will make the Git command available from any command prompt:

c:\Program Files\Git\cmd

Some Basic Git Terminology

Here is some Git related terminology you will see used in this article and in the commands.

  • origin: This refers to your forked copy of the Moodle source code on GitHub.
  • upstream: This refers to the official Moodle source code repository.
  • branch: A particular version of source the code.
  • checkout: Opening a particular branch of the code.
  • master: This refers to the latest version of the source code in a repository.
  • pull: Downloading and merging code.
  • Pull Request: The act of asking the keeper of the official code to download and integrate your changes into their master version.
  • push: Uploading code.
  • rebase: The process of synchronizing and merging your changes into the official source code.

Updating Local Copy and Synchronizing Your GitHub Fork

The Moodle master files are updated on Monday and/or Tuesday each week resulting in the + releases (like v2.7.1+).

WARNING: The following steps will delete any uncommitted files you might have added or edited. If you are not sure of what you are doing, make a backup of your whole project folder including the .git folder before proceeding. Having a recent backup is always a good plan.

Use the following commands to update your local copy of Moodle bringing it in sync with the official files from Moodle.org:

$ cd /driveLetter/pathToMoodle

$ git fetch upstream

$ git checkout master

$ git reset --hard upstream/master

$ git merge upstream/master

Now use update your GitHub fork with the local files:

$ git push -f origin master

The above could be done on one line as follows:

$ git checkout master; git reset --hard upstream/master; git merge upstream/master; git push origin -f master

You will also need to repeat this this process for each of the moodle stable branches. Fortunately you can do this in one shot (all on one line):

$ for VER in $(seq 19 28); do git checkout MOODLE_"$VER"_STABLE; git reset --hard upstream/MOODLE_"$VER"._STABLE; git merge upstream/MOODLE_"$VER"_STABLE; git push origin -f MOODLE_"$VER"._STABLE; done

When a new version of Moodle becomes available or if you just want to keep a copy of the branches you work on, you will need to customize the "seq" numbers to just include the versions that you work on. Example: $(seq 25 28) will only process Moodle releases 2.5 to 2.8.

Managing Your Moodle Patches

Creating a New Patch

Important: Never modify the master branch! Always create a new branch based on master, after first updating master of course, and then start working on your changes.

It is for this reason that I created a Sandbox branch. By setting Git to this branch when I'm done, I don't accidentally mess any existing branches up if I forget to change branches before modifying code or I just want to try something.

Using Git GUI

  1. Launch Git GUI
  2. Select Open Existing Repository and select your Moodle folder. After you've done this for the first time, it will be listed under Open Recent Repositories.
  3. Click Branch > Create and enter a branch name. This should be in the MDL-XXXXX format. You can also include the component and brief description here but it must all be separated by dashes. In the Local Branch section, make sure that master is selected.
  4. Make changes to the Moodle source code files.
  5. In the Commit Message section, the first line must be in the following format: MDL-XXXXX-Component-name-Brief-description
  6. If the change is more than trivial, skip a line and add some additional information.
  7. When done making changes, click the Rescan button.
  8. Verify all of your changes and be sure to test your code. Nothing annoys the community more than someone wasting their time with buggy code that doesn't run. You can continue to make changes here until you are satisfied with your code.
  9. Next, click the Stage Changed button.
  10. If you want credit for your efforts, click the Sign Off button. This will add your name and email address to the bottom of the commit message.
  11. Click the Commit button followed by Push to upload your changes to GitHub.

Using Git Bash

  1. Create a new branch. You will get the MDL-XXXXX number on the Tracker site when you first create your issue:
    $ git checkout -b MDL-XXXXX master
  2. Edit the files and then commit your changes:
    $ git commit -m "MDL-XXXXX component name: brief description"
  3. Publish your patch to GitHub:
    $ git push origin MDL-XXXXX

Submitting Your Changes

Regardless of which method you chose, go to your GitHub Moodle repository immediately and find the URL to your patch. The Compare and Pull Request page will do fine.

You can also see a list of your current branches on GitHub by going to:

https://github.com/[YourGitHubUserID]/{yourForkName]/branches

Do not submit a Pull Request. The Moodle community works a little different. Instead, add the link to this page to the Pull Master Diff URL field on tracker.moodle.org.

When updating the URL on tracker.moodle.org, add "cime" to the Labels field. This will cause CiBot, the automated validation checker to verify your changes to ensure you've been following Moodle coding standards. If it reports any issues, you will need to amend your changes and correct ALL of the reported issues. Be sure to check your email periodically to get a report. It will also be posted on the tracker issue page but only if there is anything to report. You will receive an email regardless of the outcome.

Tip: Only change the lines your changes require. Any changes you make to existing code will automatically make you responsible for  ensuring that line of code also meets Moodle coding standards and be subject to review and approval of the Moodle community gatekeepers.

Backporting to Previous Versions

In some cases, you will be asked to backport your code to previous versions of Moodle, not so much when adding new features but certainly when fixing bugs. Backporting is simply applying your fixes to previous versions of Moodle. I don't recommend creating backported versions until your code is approved by one or more Moodle community reviewers or you may find yourself having to make changes to multiple copies of your code each time the Moodle community comes back to you with requests for changes. If you are just starting out and are not setup with multiple instances of Moodle yet, don't be afraid to let the reviewer know. Although you should do this at some point, they will help beginners out by doing this for you as long as the changes are not too complex.

Git GUI TIP: The version specific branches, like MOODLE_25_STABLE and MOODLE_26_STABLE, won't initially appear in GitGUI like the master branch even though they do exist. You will need to use Git Bash to checkout each of these branches at least once. After that, they will automatically appear in GitGUI.

To backport your code, create a new branch based on the version of Moodle that you need apply your code to, calling it simply MDL-XXXXX-M and the moodle version number. DO NOT include subversion numbers like M261 because you are always fixing the latest version. Apply your changes, test your code and, once you are satisfied that it is working, commit and push it to GitHub. The rest of the process is pretty much the same as for Submitting Your Changes except that you would add the URL to the appropriate -- example Pull 2.6 Diff URL.

Which versions of Moodle do you need to backport to?  See Moodle's General Policy on Backporting. In general, you'll need to apply your fixes to the latest version (master) and the two most recent stable versions although this may not be true once an LTS versions has been out for at least a year.

Rebasing Your Patch

When you submit a patch, it may be a while before someone reviews it. The process can actually take anywhere from days to several months before a change is accepted and integrated into the core Moodle code. During that time, Moodle code will get updated. You will therefore be asked to "rebase" your code every once in a while. This can easily be done from Git Bash using the following commands:

$ git checkout MDL-XXXXX

$ git rebase master

$ git checkout master

$ git push origin -f MDL-XXXXX

To see a list of your current branches:

$ git branch --list

If you set the alias’ as described earlier, you can also use the following command to rebase all of your branches at once:

$ git updatefixes master

Occasionally someone else may also update the same file as you. While Git is impressively good and merging code changes together, you will need to help it out in cases where someone modified the same code or code near the changes you made. This is known as resolving conflicts. Note that you will need to update the Pull Master Diff URL field with a new link to your latest patch on GitHub.

Resolving Conflicts

When you experience a merge conflict, you will see something like "(master|REBASE 1/1)" at the command prompt. This means you are still in the middle of a rebase and must resolve the conflict before you can continue. You can find out what the issues are by using the following command:

$ git status

To resolve the conflict(s), use the following command:

$ git mergetool –y

If you configured WinMerge as described above, this command will launch WinMerge to allow you to compare and resolve each of the conflicting files.

Tip: You must close WinMerge completely in order to move onto the next conflict. Once all of the merge conflicts have been resolved, delete any files ending with .bak or .orig. Then use following command for each file you resolved. Be sure to include a relative path to the root of your Moodle folder if there is any. For example: mod/feedback/complete.php:

$ git add [name of your file]

Next, use the following commands to resume the rebase process and push your fix to GitHub:

$ git rebase –continue

$ git checkout master

$ git push origin –f MDL-XXXXX

Until you resolve merge conflicts, you will not be able to checkout any of your other branches. If you don't have time to fix a merge conflict, you have two other options:

  • Skip the patch: $ git rebase –skip
  • Abort the rebase process: $ git rebase –abort

Recovering When Things Git Wrong

WARNING: This will delete your working directory changes. If you want to backup anything, now is the time!

Accidentally Modifying the Master or a STABLE branch

This happens to me every once in a while, but less frequently than it used to before I created the Sandbox branch. mentioned above. I've spent days sometimes trying to fix this and lost all my patches in the process. Fortunately there is a simple solution for rolling back a commit.

In this example, I accidentally made and committed a change to MOODLE_26_STABLE.

To roll it back, start by checking out the affected branch:

$ git checkout MOODLE_26_STABLE

Then list the most recent change.

$ git show

You will only see the most recent commit. If you have committed more than one, you will either need to change the reference to 1 in the next command below or just repeat this process as needed.

Next rollback the change:

$ git reset --hard HEAD~1

If you accidentally do one git reset --hard HEAD~1 too many, you can recover by immediately doing the following command:

git reset --hard HEAD@{1}

I say immediately because Git does do garbage collection from time-to-time and the information will only be available for recovery temporarily.

Taking Risk that May Not Work Out (i.e. When a bad day Gits worse)

If you are reading this, you are likely still learning Git and may be poking around the Web in hopes of achieving some desired outcome. Git includes many commands that can actually take you from a bad place and make your day much worse. Hopefully you are reading this before you took a chance that did this to you.

A really easy way to ensure that you can recover from any potentially dangerous command is to start by creating an archive using 7-zip (zip or 7z format) of your local Moodle Git repository. Once you have put this archive file in a safe place, go ahead and Git some fun. If anything goes terribly wrong, just delete your local Moodle Git repository and unzip the original files back into place. Everything will be put back exactly as it was before you started.

Additional Information

Got some tips to share? Drop me a note. I would love to hear from you.