Git is a distributed source control management system, which allows a greater flexibility in your workflow than the venerable SVN. With the recent improvements to GameMaker: Studio's Source Control Management, it is now possible to use GIT from within the IDE.
This guide will walk you through how to set it up, and will follow the same lines as the Adding Mercurial Support to GameMaker:Studio guide.
Getting Started
So, first thing's first, we need to setup the Git file paths in GameMaker: Studio. This can be achieved via File -> Preferences then clicking the Source Control tab.
- Click down the use built-in SVN box, and click Custom.
- You'll then need to point it to where git.exe resides ( for example: C:\Program Files (x86)\Git\bin\git.exe )
- Check the Enable Advanced SCM Options.
- Now, click Create SCM Config.
This creates a default SVN config, the majority of which we will be replacing.
SCM Commands - Git
Now you need to edit the SCM Config file, so click the button labelled Edit SCM Config to open the SCM Configuration window. Here, we are going to change and modify settings and options to make sure it all works with GIT, starting with the SCM Commands list. It should be set up as follows:
Add: add
Blame: blame
Changelog: show
Checkout: clone.
Cleanup: clean
Pre-Commit: add
Commit: commit
(Whereas commit under SVN will store your changes on the server, Git does not - instead it stores them in your local repository, and you have to separately "push" them to the remote repository on the server, which is done in the post-commit)
Post Commit: push
Delete: rm
Info: <empty> (There is no info option in Git)
Import: init
(creates a new repository in the path you specify)
Post-Import: remote
(tags a remote server to push/pull from)
Lock: <empty> (There is no lock option in Git)
Rename: mv
Resolve: checkout
Resolved: add
(Note that Git doesn't really have a "resolved" state. Instead, you just re-add your file to the commit list, so we place "add" here, but you can also leave it blank)
Revert: checkout
Showlog: log
Status: status
Unlock: <empty> (There is no unlock option in Git)
Update: pull
SCM Command Options - Git
Once you have configured the commands, you need to set up the Command Options where we should have the following:
Add: $FILE --force
Blame: $FILE
Changelog: --name-status --pretty=format:"commit:%H | %an | %ad %n%s%nChanged paths:" $REVISION
(As the Status Log does expect things in a certain type of order, what we have to do here is tell Git to reformat itself to closer match up SVN does it. We are stating our status headers to read: "commit:(commit id) | (author) | (date)(newline)(message)(newline)Changed paths:" The parts we are most interested in are "commit:(commit id)" and "(newline)(message)(newline)". We require "commit:" to be there, so we know what the commit id is. In general, it doesn't matter where it is, as long as it's on the first line. That first line ends with (newline), which is then where the commit message is displayed, before another new line and "Changed Paths:")
Checkout: $SERVERURL $PATH
Clean: -f
Pre-Commit: $FILE
Commit: -m $MESSAGE
Delete: $FILE --force
Import: .
Post-Import: add origin $SERVERURL
(The command we specified for this is "remote" so we have "git remote add origin $SERVERURL" This adds a link to the remote server as the "origin" of the project. So that when we push/pull, we talk to this server)
Rename: $FILE $RENAMED
Resolve: --ours $FILE
Resolve-Mine: --ours $FILE
Resolve-Theirs: --theirs $FILE
Resolved: $FILE
Revert: $FILE
Showlog: --pretty=format:"commit:%H | %an | %ad | %f" --name-status
(Like Changelog, we need to shuffle about how the log is printed out - this is mostly the same, apart from %f which is a "sanitized subject line" per Git docs)
Status: $FILE --porcelain
(The porcelain flag ensures that the format isn't going to change in an incompatible way with newer versions of Git)
Update: origin master
(To maintain SVN-like compatibility, we specify updating from origin - which we set on post-import - and master, the default main branch)
All the other options can be cleared as we don't need them.
External SCM Tools - Git
In the External SCM Tools section, we need to specify the merge tool to use, in this case we use Git itself, which will attempt to choose for us:
Mergetool: git
You then need to add the following into the External SCM Tools Options:
Option: mergetool $MERGED
Status Log - Git
The Source Control Config window also has a Status Log tab, which you should now select. Here you can just have the following two headers:
status-from: Status From
status: Status To
filepath: Filepath
You can now remove the rest of them, as they are unneeded. The Status Log Format will then need to read as follows:
status-from: ,M,A,D,R,C,?,!,U (NOTE THE INITIAL SPACE!)
status: ,M,A,D,R,C,?,!,U (NOTE THE INITIAL SPACE!)
filepath: $PROJECTPATH
And these values are as follows:
Unmodified: (NOTE THAT THIS IS A SPACE!)
Modified: M
Added: A
Deleted: D
Replaced: R
Conflicted: U
Updated: M
Ignored: !
Unversioned: ?
Copied: C
The rest of the entries can be left blank, but make sure that Unmodified is a <space>.
SCM Functions- Git
Finally, we need to configure the Functions tab (if this is not visible, then you need to select the "Advanced SCM Options" check-box in the Preferences). This is mostly personal preference as to what you want, however it may be beneficial to add the following Additional Functions (note that this is mostly personal preference as to what you want here, so we shall leave the common functions alone, and add three additional ones to show how they work):
Blame: Blame
Push: Push
Pull: Pull
With the accompanying Additional Function Options:
Blame: $FILE
Push: <empty>
Pull: origin master
Push is empty as we want to push everything and Pull has the same values as we had in Update earlier. Again, it was a preference as to whether you wanted GameMaker:Studio to automatically push your changes to the server, or wait until you manually Push when you are ready. You could also add the ability to change branches here, or any other git command, which can be useful for switching between testing and working sets (for example).
So, assuming a 'testing' branch exists you would have the following additional functions:
checkout: Switch to Working
checkout: Switch to Testing
and their options:
checkout: master
checkout: testing
Using Git support in GameMaker:Studio
Unlike SVN, Git is a "distributed" source control system. This means that the entire source tree is copied to each user, meaning that they are free to make their own branches and merges locally before pushing back to a remote tree that others will pull from. While this does give an additional step of pushing the changes to the remote server, it offers extra flexibility in how you work. You can also revert back changes that you may have decided against before pushing them to the remote for everyone else to get.
We'll look at a few use cases for Git with GameMaker:Studio, as well as some more interesting uses of the new config system.
Local Git Repositories
The first interesting use we have, is that of creating a local repository right where our projects are created. This gives us the ability to track and revert changes without requiring a remote server, or any special setup, to store them. In order to do this, we have two methods we could use:
- When creating a New Project, we tick the Use Source Control box, and specify '.' in the server url. That's it, just a period in the server url box, then click Ok. Git has no username or password to set up. GameMaker:Studio will then tell Git to initialise in the project's directory and use that. This makes the Push and Pull/Update commands useless, as we have no "remote" repository in this case, but we can still commit changes and track them as if we did.
- Of course, you may already have a Project you want to use Git with. In this case, you would access Global Game Settings and click on the Source Control tab. There all you need to do is specify '.' in the URL box (that is, a single period). Again, no username nor password are required. Click on the Use Source Control checkbox, then Import Project to Repository. As before, Push and Pull/Update commands will be useless as there is no "remote" repository.
Remote GIT Repositories
Most users will likely be wanting to use their own repositories - perhaps setup on GitHub or BitBucket, for instance. In this case, it works exactly the same way as it would for a local repository, explained above. Git does not use the username or password boxes, as it has it's own configuration setup. As such, you'll need to use your own Git management tools for creating your user setup, as well as importing of SSH keys where needed. Check your tools documentation on how to achieve this.
There are two methods to adding a remote GIT repository to your project through GameMaker:Studio:
- When creating a New Project, we tick the Source Control box and directly specify the server's URL. Again, username and password are useless here, however as we have set a "remote" server, the push and pull/update commands should now work.
- Alternatively, adding a remote server to an existing project is done in a similar manner. Open Global Game Settings, and click on the Source Control tab. Fill out the URL box, tick Use Source Control, and then Import Project to Repository. Note that Git will expect this to be an empty repository.
Branching and Merging
GameMaker:Studio does not directly handle branching and merging, however basic support can be added via the additional commands config.
- Open up the SCM Config Tools via File -> Preferences, then clicking the Source Control Tab and Edit SCM Config.
- Click the Functions tab.
- Add a new function with the command "checkout" and the option being your branch name, in this case "test1". Have the title read "Switch to Test1"
- Add another new function with the command "checkout" and the option being "master" - which is generally the default branch name. Have the title read "Switch to Master"
These will allow us to switch branches via the right click menu in GameMaker:Studio. However, if these branches do not exist yet, it will throw an error.
To create a branch we can choose one of two methods: by creating a special advanced function in GameMaker:Studio, or using the Git tools you have installed when installing Git. Since external tools are outside the scope of this guide - as there are many, many Git tools - we shall instead create a "throwaway" function just to illustrate how the system works
Create another Additional Command with the following description and option:
branch: Create Branch (command)
branch: $STRINGDIALOG (option)
The $STRINGDIALOG will give us a text input window to type whatever we want in. That alone should warrant caution in it's use, as what you type is not checked before being passed to GIT. If you make a typo or anything, it won't be caught. It is therefore important that $STRINGDIALOG is used sparingly. However, in this case, it is useful for being able to create branches from within GameMaker:Studio - in this case, it allows you to have the option to Create a branch, and prompt you to type the name of the branch.
In the same way, you could add Merge commands. You have two options here - you could have specific options for each branch as in the "Create Branch" example above (which is the preferred method), or you can use the $STRINGDIALOG command (but you'd need to remember what branches are available).
We'll illustrate the first option here, as it's the least error-prone. First create new command functions:
merge: Merge from Master
merge: Merge from Test1
And their options:
merge: master
merge: test1
This will allow you to merge between the two branches via clicking the option from the SCM menu (accessed via a right click the resource tree).