-
Notifications
You must be signed in to change notification settings - Fork 38
How To Git
Git is a distributed source control system, which keeps track of all changes made to files within a "repository", and provides tools for navigating these histories and merging with changes from others.
If you haven't used Git before, please take the time to learn how to use it. This page is not a full tutorial, but it will point you to the right direction. If you do have past experience with git, it's still a good idea to check out our best practices. These are pretty standard stuff, but try make sure you are aligned with it.
Contents:
- Getting Started
- Forking
- Cloning
- Setting up Remotes
- Committing your changes
- Branches
- Creating a New Branch
- Multiple Branches
- Merging Branches To Master
- Merging Master to Branches
- Working With Remotes
- Push
- Keeping Your Repository Up To Date
- Pull Requests
- Mistakes and Pitfalls
- Adding Unwanted Files
- Bad Golf: Community Edition Specific Notes
- 23rd of February history changes
- Open Issues
There are much better guides on how to work with Git than this one. Probably one of the best ones to get started with is this guide in Stack Overflow.
Quick tip: don't feel overwhelmed!* It takes a bit of practice to get the hang of it. A lot of the examples are command line interface, but most commands are fairly simple. You may find some useful GUI frontends (such as Git Tortoise or the GitHub app for Windows and Mac), but it's better if you know your basic command lines. Regardless to the way you run Git, you must learn the basic concepts and best practices. When you feel lost or insecure, just ask!
See this github help page for some details of what's being discussed in this part.
Since you want to contribute to this project, you don't create your own repository. Instead you should fork the current repository. Forking a repository means you have your own copy. Unlike your file system in which you copy a file and it's completely separate, forking means you can still get updates from the main repository and still contribute changes you make in your forked repository back to the main repository.
In github it's rather simple to fork, just click on the button and a forked repository will appear for your github user.
We are pretty much done with the github web interface for now, so get comfortable. The next step is to clone your forked repository to your local machine. Cloning is actually just like forking, but in this case you will be using git. Go to the parent directory where you'd like to clone your repository.
$ git clone https://github.com/<username>/bad-golf-community-edition.git
Where is your github user name. This command will create a subdirectory called bad-golf-community-edition and copy all the files in the repository.
So now you have 2 of your cloned repositories. The first is the github fork and the second is your local clone. When you cloned the repository git automatically added a remote called 'origin'. Whenever you commit your changes to git it saves them only locally. If you would like to update your changes to your forked repository you will have to push your changes (more on that later). Before we do that, we should add a second remote repository, which is the main repository. This is normally called upstream (you should use the same naming convention so you can easily follow other instructions later)
$ cd bad-golf-community-edition
$ git remote add upstream https://github.com/Double-Fine-Game-Club/bad-golf-community-edition.git
To save your changes to your current repository (remember, you are working on a local repository) it's not enough to just make the file changes, you must update the repository itself.
To see the pending changes just type
$ git status
Modifying files will automatically appear as modified in the status. However, to add a file it's not enough to add it to the directory. You need to add it to the repository as follows:
$ git add <filename>
Files that are not in the repository, but are in the directory are 'unstaged'. Take special care not to add unnecessary files. Some of the files are generated by Unity and should not be part of the repository.
To revert a change you have done to an existing file use the following command:
$ git checkout -- <filename>
This will give you a fresh copy of the unmodified file (note that you will lose your local changes)
To unstage a file you added use the following command
$ git reset HEAD <filename>
Finally, to save your changes you should use the commit command. It's very important to add a meaningful message on what you have done. This is good practice so others understand your commits. So for example:
$ git commit -m "Issue #33: Fixed cart catching fire when space is pressed"
We will not going into further details here on these basic commands, you can find a lot more right here
So you are ready to go, right? Well, not yet. There's a very important aspect for you to learn which is branches.
The main branch is called 'master'. This is where the latest code is always available. By default, when you cloned your repository you are set to work on this main branch. However, changing your code in master is bad practice. It is much better to start using branches. Even if the change seems small, it is still highly not recommended to do these on master. There are several reasons for that. The first is that branches allow you to create granular changes. It will be easier for others to understand what you've done. The second reason is that it will be much easier for you to work on other things while your changes have not been integrated yet. It may seem like an annoyance at first, but do trust us this is in fact easier to work this way, mainly because you are not developing here alone.
Recommended reading: here
Suppose you want to create a new cart model. Then let's create a branch for that
$ git checkout -b my_cart_model
Note that the '-b' switch creates the branch, and the checkout command switches to that branch. if you don't like using that switch and prefer using 2 commands then do the following:
$ git branch my_cart_model
$ git checkout my_cart_model
Using a single command or two commands is equivalent so use whatever you find easier and less prone to errors.
You can have as many branches as you'd like. Suppose you are still in the middle of creating your cart and would like to add a new tree type. This has nothing to do with the cart, so we should branch off from the master again. First go back to the master branch
$ git checkout master
Now, simply create your second branch
$ git checkout -b great_tree
At some point you'll want to merge changes of your branch back to master. This is rather simple, just switch to master and merge:
$ git checkout master
$ git merge my_cart_model
You will most likely update your master branch from time to time to be up to date with the latest main repository changes (details next section). If you'd like your branch to also be up to date you can simply merge the master to your branch. The procedure is exactly the same, while you are in your branch do
$ git merge master
In fact, remember this part, it will be useful later.
Remember that your changes are all local even after you commit your changes. To apply your changes to your forked remote repository simply can simply push your changes to the origin. To push the master branch back to origin do:
$ git push origin master
You cannot push directly to the 'upstream' remote we created. That requires a pull request which we'll explain in a moment.
Obviously you are not alone. Other continue to work on the game while you make your own changes. The simplest way to be up to date is to use the pull command (reminder: upstream is this repository)
$ git pull upstream master
This will take the changes from master in upstream, and merge them to your own branch. Notice that the merge is done to your current local branch, so if you'd like to pull into master only and not your branch, ensure you checkout master first.
It's probably best you first pull changes from upstream to your own repository master before merging changes from a branch. This way you can address conflicts while doing the merge, and if they are difficult to solve you can go back and still have an up to date master branch.
Finally we arrive at the point where you can submit your code. You can make pull requests to ask the people maintaining the main repository to merge your changes. Of course you should do that when you're done. Github allows an easy interface to do that.
It's best practice to create pull requests for your branches. If you properly followed the recommendations here you should have a branch per specific topic. This will allow you to make multiple contributions without having to worry when the pull request has been approved (it's not uncommon for pull requests to be handled only after a few days). This means you can continue working uninterrupted on any other task.
Before making the pull request you should make sure you pulled the latest from upstream and merged those changes into your branch. This will ensure you have resolved all possible merge conflicts and it will mean much quicker and easier response to your pull request.
Issues are created, or can be created, whenever a change is requested for the project. This includes all of implementing a feature, fixing a bug, creating a model, and writing documents for this Wiki. An issue consists of a subject for the issue and a description where full details can be provided about what the issue wants resolved as well as attachments. Issues also provide a place for contributors to discuss possible solutions for the requested changes. Each issue is automatically given an issue number by GitHub e.g. #24
.
Refrain from adding files that are auto-generated by Unity. Doing so would not only unnecessarily increase the repository size, but it will also make tracking changes an impossible task. If you added those inadvertently do not just delete the files and make another commit. Git will remember those actions which again will be difficult for everyone else later.
It's best you contact the community here if that happens, do not create a pull request with such changes.
If you have forked after the 23rd of February, specifically after 4bd119a714441c46483768fd59a88bd246163b25, you can safely ignore this.
Similarly if you haven't pulled since before 82af6a751edcba4235e154bb38daef7ed97a28a4, you can ignore it too.
Due to accidental commits of large files which belonged in the asset sources repository, we've made things a bit awkward for everybody with downstream forks. Though the files were removed (even before they were pushed to the repository), they still exist in the git history, increasing its size unnecessarily. Through this process, we were able to nearly half the repository size.
Unfortunately, this is going to break pull requests and require you to re-make any commits which haven't made it upstream (or use git cherry-pick and create patches to manually apply if you're up to doing that). Anybody with knowledge of a simpler workflow for navigating this sort of thing is welcome to chime in!
The following assumes you have an "remote" called upstream
as described at the first section of this page.
git stash
(if you have any uncommitted changes)
git rebase <branchname> --onto 82af6a751edcba4235e154bb38daef7ed97a28a4
(If working from a local branch replace with the branch's name, otherwise remove it)
git pull upstream master
git push
git stash pop
(if you stashed uncommitted changes before)
From there, continue working as normal! Grumbliness about this situation can be thrown in Cheeseness' direction <3
Should we require squash merge to have a single commit before merge? (probably requires creating a branch just for merge, a bit more complex but cleaner)