Git Good workshop

Git is version control software that will help support a productive workflow throughout all stages of development. This article was written by Thomas Lock, Christopher Ross and David Churchill.

Why version control?

Version control aims to solve the problem of keeping code in order in any scope, whether working solo or as a team. There are many different types of version control available, but Git is the most commonly used in industry.

There are several reasons for this: collaboration features, the branch system, clear update messages and explanations of these updates… it’s such important and widely used software that it’ll come pre-installed as standard on most UNIX machines and distributions.

Basic usage

Initialise a repository

Git solves the problem of keeping code by organising it into “commits”. Each commit is a full copy of the current working code and you’re able to go back at any point to review these older versions. In order to get started, we need to initialise a Git repository.

To do this, open the folder where your code is located and type git init in console. This will create a .git file: a folder that contains the configuration for this instance of git as well as all stored versions of code.

Branching

You now want to create what’s known as a branch.

A branch is a different staging area. This means that changes you make within a branch only affect that branch. You’ll usually want at least 2: one (the default) called ‘master’ that represents the current stable working version of the code and one (or more!) for moving between development and testing phases.

To set up a new branch from the command line you can type git checkout -b *branchname*. When you want to switch to an existing branch type git checkout *branchname*.

Commit

Updates to code are known as “commits” and feature messages that explain what has been done since the last update. These are written in imperative tense ie “add feature” not “added feature”. This makes syntax when dealing with reversions or merge conflicts easier.

To commit to the current working branch you first need to add the modified files to staging. Git offers the ability to add specific files that have been changed or all files at once. To add specific files type git add *filename* or to add all files type git add *.

You’re now ready to commit. Type git commit -m “*message*” to commit. The -m parameter indicates that you’ll be using a message which is contained within quotation marks.

Push / pull / clone

Interaction between remote working environments (such as GitHub or GitLab) can be done through these three commands: git pushgit pull and git clone.

git push sends all commits and updates (such as creating new branches) currently not on the remote server to the remote server.

git pull receives the current version of the repo from the remote server.

Finally, git clone is what allows you to download existing repos from a remote host.

Exercise: let’s collaborate on a story

Let’s put all of the above to use by writing a story together.

You’ll need to set up a GitHub account if you haven’t done so already. GitHub is totally free for University students (and now also totally free for most people. Thanks Microsoft!)

Login to your account and head to the collab-story repo. Press the “Fork” button on the top left side of the screen. This will create a copy of the repo on your account. Find the URL for this repo and copy it.

Now we move to the command line.

Start by typing git clone https://github.com/YOURUSERNAME/collab-story into the console. This will create a folder “collab-story” and download the repo from GitHub.

Type cd collab-story to enter the repository folder and switch branch to “writing” by using git checkout writing. Modify story.txt adding in whatever you want to continue the story. Then, git add story.txt and git commit -m “updated story”. Finally, git push to send your update to the hosted repo.

Note: You may be asked to enter in some other commands to set your identity and set upstream. These will be clearly outlined for you: rather than explain them myself, take a look at what the software is telling you and try to enter the commands to fix the issues. If you get really stuck feel free to call someone over.

In a web browser head back to your fork of collab-story and press “New pull request”. Make sure you select the “writing” branch for both repos when comparing.

Type whatever you want for the message and comments and press the big green “Create pull request” button.

IT IS DONE!! I’ll be looking to accept these requests as soon as possible so by the end of this session we’ve written a full story together.

Further reading

Note that in a real-world scenario what we just did might cause a lot of problems. When you try to modify something that someone else has just modified you’ll run into what’s known as a merge conflict

These can be tricky to solve, but there are several plugins available that make dealing with them significantly easier. Git is clever in that it tracks each individual character of a document, so if you’ve changed E.G lines 1 – 3 of a file and a colleague has changed lines 5 – 8 of a file you’ll not run into any conflicts.

You’re now ready to go with version control! Let’s move on to using GitHub for Desktop as a visual aid and an easy way of setting up and updating repos.

Click here for a full guide on using more advanced techniques and terminology in the command line.

GitHub Desktop

GitHub is a service that  hosts Git repositories. GitHub desktop aims to make the process of using Git significantly more user-friendly by obfuscating the commands ran beneath the GUI. In order to understand Git properly, it’s important to understand that GitHub is only a hosting platform. GitHub desktop automates commands without teaching you how to use them properly. In a real world work environment, it is highly unlikely that you’d ever use GitHub desktop.  However, it is useful for beginners to get started using Git and offers various tools to make the transition from no version control to full version control easier.

When opening a new project, GitHub desktop can be used to create a new repository. These repositories, once named, can be made either private or public depending on whether you wish others to see your work.

Once the repository is set up, you will then be required to publish it, see figure 2 for what the publish button looks like. Note: It can only be seen when a new repository has been created.

Figure 1. Getting started
Figure 2. Publish branch

From this point, you may find the location of the local repository by pressing the “Show in Explorer” button as seen in figure 3.

Figure 3: Finding the local repository

When items are added to this local repository, they will appear in the changes tab. Once all the desired changes have been made, they can then be sent to GitHub by pressing the commit button found in figure 4, and then the push button, seen in figure 5. This process can be repeated as many times as you want.

Figure 4: Commit

If you have changed your code and it has been committed to GitHub, the history tab as seen in figure 6, can be used to search through all of the changes that have been previously made.

Figure 5: Pushing to GitHub
Figure 6: History Tab

If your changes were later found to be undesired, they can quickly be reverted back at the click of a button by right clicking the commit that you would like to revert back to and selecting “Revert this commit”.  This can be seen in figure 7 and saves countless hours in trying re-implementing what was deleted.

Figure 7: Revert

GitHub’s branching tool seen in figure 8 is also very useful, as allows developers to create an additional environment, where new concept ideas and features can be implemented and tested. The changes that are made on this different branch, will not affect any of the other branches that may exist, meaning developers have the freedom to experiment and commit changes, safely without any fear that it may affect vital code.

Figure 8: GitHub Desktop

 

Procedural Generation Techniques – Poisson-Disc Sampling

If you’re a game developer, there’s a good chance that you’ve tried generating random or procedural terrain at least once before. You start with the ground, the grassy and rocky areas, and then begin to populate your world with trees, rocks and other decorative foliage.

At first, it might seem like a good idea to simply generate a random position within some boundaries and place your object level with your terrain at a given height. For most cases where not much detail is required this will usually suffice, however this approach will likely lead to objects overlapping as well as producing overpopulated and underpopulated areas as shown below:

Random distribution of points on a plane

If you imagine the points above represent your foliage, such as trees, it’s clear that using this method will produce an unrealistic distribution and sometimes place trees within each other. They don’t do that in nature.

This is where the Poisson-Disc sampling technique comes in. We’re aiming to maintain the pseudo-randomness of the points, but enforce some rules so that each point maintains a specified minimum and maximum distance away from another given point to give a nice even and organic-looking distribution, seen below:

Poisson-Disc distribution of points on a plane

There are several methods of implementation, such as Bridson’s Poisson-Disc or Mitchell’s best-candidate algorithm but they all essentially perform this same task.

It works by generating points in a radius around existing points, after checking that the distance requirements are met. You’ll need 2 lists, one to keep track of samples that are currently being generated and another for those that need processing. Then, create a grid such that each cell only contains at most 1 sampling point. If the points are going to be r distance from each other, the cell size should be r/2π.

For the first starting point, it doesn’t matter where this is, so you can generate this randomly or input the position manually. Place this first point inside the processing list, sample list and the grid. Then, while the processing list contains points, chose a random point from the processing list and generate up to k points within a sphere around it. The value for k can vary, however larger values will likely slow down generation time. Then, for each of the generated k points, check that there are no surrounding points that are too close, and if there are none, add the point to both lists and the grid.

Finally, remove the origin point from the processing list and return the output list as the sample points. Done! This algorithm can seem rather daunting at first, but it’s actually quite simple to implement and for more information on how to do so, check out the links below.

Further Reading:

https://bl.ocks.org/mbostock/dbb02448b0f93e4c82c3

http://gregschlom.com/devlog/2014/06/29/Poisson-disc-sampling-Unity.html

http://devmag.org.za/2009/05/03/poisson-disk-sampling/