Using Git and Github to contribute

We use git and Github to manage changes to Cataclysm: DDA. Why? Because it makes it simple and easy to coordinate dozens of separate contributors all sending in patches for the same chunks of code.

Github is a site that stores our code for people to access, and also has a number of tools to assist us. Git is the actual tool itself, the bit that does the low-level file tracking and such.

However, not everyone knows how to use git, and there are a few minor gotchas that can make things messy. So, I’m hoping to provide enough instruction for people to be able to use git well, in the case of Cataclysm: DDA. The instructions will resemble the Github tutorial to some degree, albeit reordered and customized for Cataclysm: DDA.

This also assumes that you’re comfortable with command lines, because git’s origins are in the command line. If someone can get good GUI instructions for Windows users, that would be very much appreciated.

[hr]

[size=14pt]Forking the official repository[/size]

The first step is to fork the official repository. This allows you to post changes to Github, with a minimal degree of hassle. It’s also a very simple step.

All you have to do is navigate to the official repository, and hit the “fork” button in the top-right corner. If you don’t have a Github account, you should be prompted to create one.

Once that’s done, you should have your very own Cataclysm: DDA repository on Github, ready for you to tinker with!

[size=14pt]Setting up git to track your fork[/size]

The next step is to set up git on your local machine, and tell it about the fork you’ve just made.

First, install git. The details of that will depend on your system, so you may want to follow the Github tutorial’s directions. If you’re on Windows, it’s a good idea to make sure you have access to a git command prompt, so that the Linux-based devs (i.e., the majority of us) can actually help you when you have questions.

Once you’ve installed git, you’ll want to configure a few local settings. Run the following commands, replacing the text inside the strings (“Your Name”, etc.) as appropriate:

git config --global user.name "Your Name Here"
git config --global user.email "your_email@example.com"

Mind you that the email should be one that Github knows about.

After that, navigate into the directory that you want to work in, and enter the following (again, replacing “YourUsername” as appropriate):

git clone https://github.com/YourUsername/Cataclysm-DDA.git

And you’re done! (although you’ll need to move into the new directory that’s created, most likely)

[size=14pt]Making changes[/size]

So, you’ve got your fork, and you’ve probably got some changes you want to submit. How do you do that?

First, make sure you’re on a clean, fresh branch:

git checkout master
git branch whatever-you-want
git checkout whatever-you-want

Obviously, you can replace “whatever-you-want” with… well, whatever you want. You should now be on a new branch, with a name of your choosing. If you want to switch branches, use the “git checkout” command again. It is highly advised that you do not make local changes to the master branch, because it makes it harder to get clean commit histories.

At this point, you Make some edits, and save the modified files. Once you’ve got a working set of changes, you’ll want to commit them. To commit all the modified files in the current directory (make sure you don’t have any extraneous modifications), run the following:

git commit .

You’ll probably be prompted (somehow) for a commit message. Try to write a good, succinct summary. If you’ve added files, however, you’ll have to tell git you want to track them first. To do so, use the “git add” command. For instance, if you’ve made a bunch of changes AND added foo.h, foo.cpp, and bar.cpp:

git add foo.h foo.cpp bar.cpp
git commit .

There’s also a way to have “git add” automatically add all files in the current directory to the project. However, before running that, be sure that you don’t have any user-specific junk files in your working directory. For example, temporary build files, or executables. Due to the risk of accidentally adding large files to the repository, I won’t put that command in this tutorial - better to read the docs.

[size=14pt]Submitting your changes[/size]

Once you’ve made one or more commits that you’re happy with, you’ll probably want to submit them for potential inclusion in the official Cataclysm: DDA repository. First, we need to get those changes pushed to Github, which we do with the “git push” command. First, make sure you’re on the branch with your changes (remember, use “git checkout”). Let’s assume you’re on the branch named “whatever-you-want”. To push your changes to your fork on Github, run the following command:

Now your changes should be on Github. In order to get it seen by the project maintainers, you need to submit a pull request.

In order to submit a pull request, go to your fork on Github. There should be a button near the top-right of the page that says “Pull request”. Click on it, and select the branch that has the changes you want to submit. Type a suitable message in the boxes, and hit the send button. You’ve just submitted a pull request, and the project maintainers should take a look at it when they’re next available.

[size=14pt]Grabbing new official changes[/size]

Sooner or later, you’ll want to update your local files to match the current official version. Probably sooner, if the current development pace is maintained. First, you should configure your local copy of git so that it knows about the official repository. Run the following:

The word “upstream” can be replaced with whatever you want, although “upstream” is a common choice.

Now, whenever you want to pull in changes from the official repository, run the following command:

[hr]

[size=14pt]Summary of the edit-submit-update-edit cycle:[/size]

Once you’ve gone through all those steps once, and configured everything, the general workflow is as follows.

Grab latest changes, on a clean master branch:

git checkout master
git pull upstream master

Make a new branch for some new changes:

git branch some-new-branch
git checkout some-new-branch

Edit code. Then, commit it:

Push it to your Github fork:

Submit a pull request, so that people are aware of your changes.

Go back to step #1 :).

[hr]

[size=14pt]Q: Do I need to use git?[/size]

If you’re a programmer: almost certainly yes. Changes to the game’s code can be messy, sometimes very messy, and it seems to be assumed that if you’re capable of writing code, you’re capable of learning how to use a version control system such as git.

If you’re just modding data files: possibly not, because

In any case: the project maintainers are generally busy, and need to make effective use of their available time. The easier you make it for them to include your submission, the more likely your submission will be accepted. Using git to submit things makes it easier. So, use git, if you can.

[hr]

I hope that was helpful!

EDIT: Kevin Granade: For further info, the Github help pages are EXTREMELY… helpful.
EDIT2: Kevin Granade: We use the GitHub Flow model of contributing.

Nice work Soron, Its good to know someone is making an effort in teaching us all the intricacies of version control.
Lets hope future contributors will find it easier to adjust to git-hub.

Awesome thread! I have used this manual from github to learn git basics:
https://help.github.com/articles/fork-a-repo
I use such set of commands to get the latest version of Cataclysm:

git fetch upstream
git merge upstream master

What is the difference from

git pull upstream master

I heard that it is possible to revert your branch state to any commit you’ve made before. Is it so?

To the best of my knowledge, “git pull” just grabs the latest version of that particular remote branch and merges it into your current working branch. “git fetch” checks the remote repository, and updates a local copy of that repository with information about the various branches it has.

If you’re only ever grabbing the upstream changes from the master branch, it’s probably fine to just use git pull. If you start doing more complex stuff, it might be a good idea to get used to using fetch/merge instead.

It IS indeed possible to revert to previous commits, or grab previous commits and examine them. Use “git checkout hash” to checkout a particular commit based on its hash. If you want to keep that point, or continue work on it, you should then do “git branch some-branch” and then checkout that branch (if you checkout a commit by itself, and then do more work, it’s easy for stuff to get lost in the ether).

If you want to actually revert to a previous, recent commit (e.g., if you screwed up), you probably want to use “git reset”. To clear all current changes that you haven’t committed, use “git reset --hard”. To go back a certain number of commits but keep the changes in your working directory, use “git reset HEAD~n”, where n is the number of commits that you want to undo. You can also combine the two, as “git reset --hard HEAD~n”, which goes back n commits and wipes any changes that have happened since then. Obviously, use that one with care. Also, be careful about resetting changes that other people have grabbed (such as if you’ve submitted a pull request and had it approved) - it can make the history kinda gnarly.

There’s also “git revert”, which you can use if you want to undo the effects of a previous commit without removing it from the history.

What I’ve currently got up is meant as a beginner’s guide, so I probably won’t put potentially-dangerous stuff like “git reset --hard” in the same section of the OP. Once I get a feel for what kinds of stuff people want to see/need to know, I’ll probably put it in a different section in the OP, or possibly in a different thread.

I have found something very useful. It is a throughout guide written by a fellow countryman, Igor Baloš.
He shows how easy it is to set up, use and contribute via msysgit

BeanStalk Guides - Working with Git on Windows
http://guides.beanstalkapp.com/version-control/git-on-windows.html

GoogleCode - up-to-date msysgit downloads
http://code.google.com/p/msysgit/downloads/list?q=full+installer+official+git

I believe that after one gets familiar with either PuTTy or SSH for win, can follow rest of the steps as Soron wrote them as msysgit respects the same old commands of UNIX origin.

I got one question.
Do I need to use a different directory for every new branch?
I see if I switch to another branch and pull, all files are changed to that branch.

Git branches can do some odd stuff if you’re not expecting it, but you actually don’t want to use separate directories for every branch. I think that works (and is even advised) for some version control systems, but with Git, it’ll just confuse stuff.

What happens is that Git swaps out the files in-place when you change branches (or at least, all the tracked files). It keeps a record of all the differences it has to make in order to do that, and will restore the previous versions of those files when you switch back to your previous branch.

Yeah, I see. Thank you.

I sometimes use

with the intent of pulling remote master into a new branch. However, whenever I do this, remote master also gets pulled into the current branch I am in. My work around is to create a dummy branch, pull, checkout to new branch, delete dummy branch. Is there an easier way to do this?

(I also can’t think of an example as to why I do this… normally it’s when I mess something up)

[quote=“Shoes, post:9, topic:1030”]I sometimes use

with the intent of pulling remote master into a new branch. However, whenever I do this, remote master also gets pulled into the current branch I am in. My work around is to create a dummy branch, pull, checkout to new branch, delete dummy branch. Is there an easier way to do this?

(I also can’t think of an example as to why I do this… normally it’s when I mess something up)[/quote]

Lol, yea, git seems to get confused, possibly, because you didn’t specify your local in your refspec.

Personally, I would use an alias to prevent accidents:

git config --global alias.nbwp '!sh -c "git branch $1 --track upstream/master && git checkout $1 && git pull"' git nbwp tinker-time

nbwp = new branch with pull

Although you can have multiple working directories hooked up to one git repo if you want multiple branches open at the same time, which I don’t use for this project but I find invaluable at work. Git comes with the following script that will set that up for you:
[tt]git-new-workdir project-dir new-workdir branch[/tt]

Man, https it really slow here. I spent several hours last night to clone a repo but still failed at around 30mb. :stuck_out_tongue:

I’m using this instead on another PC and the speed seems normal (200kb/s).
git clone git@github.com:username/Cataclysm-DDA.git


And it seems I’m having problem adding upstream.

git pull upstream master
fatal: ‘upstream’ does not appear to be a git repository

git remote add upstream git@github.com:CleverRaven/Cataclysm-DDA.git
fatal: remote upstream already exists.

I have to use this instead to change upstream url:
git remote set-url upstream git@github.com:CleverRaven/Cataclysm-DDA.git

OK, just discovered that the browser-based & Windows Git clients don’t automatically keep themselves updated.

Whoops. X-( What’s the mainline-updating solution for someone who uses GUIs?

(Looked into the tutorial vultures posted, but it seemed full of how-to-SSH. Not helpful for my problem, so far as I can tell. Sorry.)

Using Github app:

Github made an application for windows so you’d have a GUI instead of just a command prompt. So to make it easier for new people to use that GUI here’s a little guide:

[hr]
[size=24pt]Setting up your Github, with Github application for Windows.[/size]

[ol][li] Create an account on https://Github.com. It’s the first thing you see on the site.[/li]
[li] Now go to https://help.github.com/articles/set-up-git and click Download Github for Windows.[/li]
[li] Run the install, you shouldn’t run into any trouble. It does have to download 40 mb so if your connection is slow you might have to wait a while.[/li]
[li] Once the installation is done the application should open and prompt you to log in, log in.[/li]
[li] The GUI should like the image (it could also open the options automatically the first time). Click on tools at the top and choose options. [URL=http://imageshack.us/photo/my-images/823/github1.png/][/URL][/li]
[li] I recommend changing the default shell to Git Bash, as all the code and guides already here work on Git Bash[/li]
[li] Now it’s time to get your copy of the Cataclysm source code. Go to https://github.com/CleverRaven/Cataclysm-DDA and press the Fork button. Github should then tell you it is forking the code and send you to your own github page when done.[/li]
[li] Open the Github application you just downloaded and you’ll see the new forked repository in your Github. Clone it to your local machine by clicking the clone button on the repository.[/li]
[li] Now click on the repository and click on tools -> open shell here. You’ll have to set the original Cataclysm git as upstream, do this by running this line of code in Git Bash: $ git remote set-url upstream https://github.com/CleverRaven/Cataclysm-DDA.git (Regrettably, [.code][./code] does not work in lists).[/li]
[li] Now go to your local repositories and open Cataclysm. On the top click on master and add a new branch. You can name it whatever you want and then click on tools -> open in explorer.[/li]
[li] This is your directory where you can make your changes! When you are done you’ll have to press the publish button on the top and I’ll be published on your Github. If you want to mod the game and not send your changes to the devs just give someone a link to your github like this: https://github.com/Isylwin/Cataclysm-DDA/tree/Archery and then let people download it as a zip. (Just an example don’t download it)[/li]
[li] If you want to send your changes to the devs then you’ll have to go to your github branch you want to post (i.g. https://github.com/Isylwin/Cataclysm-DDA/tree/Archery) and press pull request (next to unwatch) and send a request to the master branch at CleverRaven. It goes without saying that you attach details to your request which are clear and easily understandable for the devs. Devs are fragile people and they need good care :p, it’s your job to make it as easy as possible for them.[/li][/ol]

[hr]
[size=24pt]Merging branches with Github[/size]

It’s important to update your branch you are currently working on with the latest changes. That’s why you should merge your updated master branch into the branch you are currently working on.
To do this you click the branch icon (the same as for creating branches) and click the manage/merge branches in the dropdown menu. In the left down corner you’ll see a merge option. Put the updated branch (usually the master branch) in the left slot and the branch that needs updating in the right slot. That’s it.
WARNING: I hope this goes without saying but always have a backup of your files you modded/changed. Better safe than sorry.

[hr]
[size=24pt]Updating your repository with Github[/size]

Go to your repository in the Github application, not the local one, and run a shell there (the shell should be Git Bash). First off check if your upstream is correct by running this code:

The upstream should direct to https://github.com/CleverRaven/Cataclysm-DDA.git ofcourse. If it isn’t run this line of code:

If you have made a mistake and want to remove your current upstream run this code:

In order to get the latest changes from CleverRaven’s github you’ll have to run this line of code in Git Bash: git pull upstream master
Your shell will kind of look like this when it has updated your repository: [URL=http://imageshack.us/photo/my-images/515/github2.png/][/URL]

Now all you have to is press sync in your repository to sync the changes with your repository and it will automatically update your local repository as well.
It’s best to make this your habit every time you want to add changes, just pull the newest code from CleverRaven and implement them.
Please check out the merging branches if you want to update your own local branch with the newest changes.

[hr]

Any dev/moderator make take this text above this line and alter and copy it to their liking and if you place this on top of the post please spoiler or delete my whole post so it doesn’t clog up the forum. If I find out more that’s important I’ll of course add it here. There’s one important thing to note at the moment, as KA101 posted before me, Github app is a bit weird when it comes to updating. Specially because adding CleverRaven’s git as an upstream results in error’s (saying that the upstream exists). I’d like to work on this weirdness and see if there’s a reliable workaround as I can’t say for sure if anything works (though the replies here have great ideas/solutions)

I hope this could help some people out with github, as it is an awesome concept (and I’ve only discovered it yesterday) and also lower the wall for some people to start modding/contributing to this awesome awesome game. Furthermore I’d like to suggest something for The Lab (I know it’s not the place to do suggestions like these but meh). A sticky saying that people should use Github if they want to help out (and link to this post ofcourse), so that people are aware that they should use github and not throw their changes into a .rar hehe. Also, I find, it’s easy to not see the toolbox subforum so such a post could help some blind people see. I’d be happy to write it and pm it to an admin, just give me a call.

-Isy

(EDIT: I’ve added how you can update your repository and made the whole thing a little bit neater. Also, thanks to utunnels for the alternative way of setting your upstream, thanks man.

…So I went to lauch the merge whatever and… It seems like I broke it, all I did was change a few names from the cannibal expansion thing (I think?) and to my knowledge it should have merged fine?

…I don’t really have the foggiest idea what I’m doing, I’m using some windows-launched program that the GitHub site has to do the merging, in the past it failed because of a typo in the json, but now the console output doesn’t make any sense to me…

[code]GitHub pull request #4371 of commit 5c4c9a85d5b0d7a5fbe1078434e0739e1e1600e1 automatically merged.
Building in workspace /var/lib/jenkins/jobs/Cataclysm-PullRequests/workspace

Deleting project workspace… done

Fetching changes from the remote Git repository
Fetching upstream changes from git://github.com/CleverRaven/Cataclysm-DDA.git
Checking out Revision bce1ad723c41429b3def1606ceeeac52745f4a18 (origin/pr/4371/merge)
Run condition [Boolean condition] enabling prebuild for step [Execute shell]
[Boolean condition] checking [true] against [^(1|y|yes|t|true|on|run)$] (origin token: ${CHECK_MAKEFILE})
Run condition [Boolean condition] enabling perform for step [Execute shell]
[workspace] $ /bin/sh -xe /tmp/hudson2840394629452856267.sh

  • diff -q /var/lib/jenkins/cataclysm-reference-repo/Makefile Makefile
    Files /var/lib/jenkins/cataclysm-reference-repo/Makefile and Makefile differ
    Build step ‘Conditional step (single)’ marked build as failure
    Archiving artifacts
    Finished: FAILURE[/code]

Can someone tell me what I did wrong? I just have the distinct feeling someone somewhere is going “Oh god fucking damn it Ekarus broke fucking everything…”

I’m not sure if it’s just me, but git push -u origin some-new-branch does not work for me, trying to push commits will result in a 403 error. Apparently ‘origin’ is set to the same as upstream by default, in this case it’s CleverRaven/Cataclysm-DDA.git . I had to change it to my own repo using git remote set-url origin https://github.com/infectedmochi/Cataclysm-DDA.git And it works fine again.

Edit: And I can’t replicate this :confused: Maybe it was a screw-up on my part after all.

You wrote this:

The rest of this sentence somehow got lost. Could you please complete it?

PS: Thank you for this guide. It really helps!

Soron has been gone for almost a year now. That said that last section should really be changed to:
“Yes, you need to use git. The community is busy enough that it’s a requirement. We’ll be happy to help you setup and learn to use git, but it’s a definite requirement if you want to get anything merged into the mainline”.

Is it okay that my forked repository is X commits behind original repository after I did git pull --ff-only upstream master and local master is now equal to upstream/master?