A minimal set of commands for using Git to collaborate using pull requests.
Note that this is not the only way to do this, but it is one way that works. If someone says to do something else, they aren't necessarily wrong- it could just be a different means of accomplishing the same thing.
Check out the latest version of master
from GitHub:
git checkout master
git fetch
git rebase
Create and switch to a new branch for your feature:
git checkout -b dp/some-crappy-feature
Create a new commit on your current branch:
git add .
git commit -m 'This message explains my dumb feature'
Push your branch to GitHub:
git push origin HEAD
Merge the latest changes from master
into your current branch and push them to
GitHub:
git fetch
git rebase origin/master
git push origin HEAD -f
Git is a version control system that allows multiple users to work on the same codebase at the same time, then merge their changes back together. It has many, many very complicated features. But you probably just want to contribute some code, so here's what you need to know for that.
While using Git, you'll typically be on a "branch." Code that you write will
live on that branch and doesn't leak into the other branches. In our repos, we
have a branch named master
which represents the latest state of the code
shared by everyone. To check which branch you're on (and see some other
information), run
git status
which gives output that might look like
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
That top line is saying that we're currently on branch master
.
When someone else on the team wants to deploy a new version of the code into
production, they'll typically check out the master
branch and deploy whatever
version of the code is there. For this reason, it's best to always leave
master
in a clean state, without any partially completed features or buggy
code, because whatever is there may inadvertently end up running in production.
Thus, instead of doing your work directly on the master
branch, it's typically
better to create your own branch locally, do all your work on that branch,
possibly get it reviewed by other people, and then merge it into master
when
done.
To get started, you'll want to be on the latest version of the code. To do so,
we'll switch to the master
branch, fetch any changes from GitHub, and then fix
up our own local master
branch to look like the one from GitHub. These three
steps precisely correspond to the following commands:
git checkout master
git fetch
git rebase
To get the ball rolling, create a branch as follows:
git checkout -b dp/some-crappy-feature
The git checkout
command switches branches, and -b
says "create a new branch
before switching." I like to name my branches starting with my initials DP as
above because it makes it easier to see who is responsible for what branch on
GitHub.
After doing this, we are now on our own branch, which we can see by running git status
again:
$ git status
On branch dp/some-crappy-feature
I can now go ahead and make all my changes. When I'm done with them, I'll make a "commit," adding all the changes to my branch. I'll need to give it a "commit message," a short description of what changes I just made:
git commit -m 'This message explains my dumb feature'
Now my branch has my changes on it, but only my computer knows about it. I want to send my branch to GitHub so other people can look at it. To do so, I run
git push origin HEAD
Explanation: git push
sends Git data to elsewhere. origin
specifies that the
place we are sending it to is GitHub, since GitHub is where we originally got
the repo from when we ran git clone
long ago. HEAD
is an alias for "the
branch where I am right this moment," e.g. dp/some-crappy-feature
in this
example.
This makes a lot of stuff show up, but the output will look something like this:
$ git push origin HEAD
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 276 bytes | 276.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote:
remote: Create a pull request for 'dp/some-crappy-feature' on GitHub by visiting:
remote: https://github.com/OMGWINNING/alchemy-website/pull/new/dp/some-crappy-feature
remote:
To github.com:OMGWINNING/alchemy-website.git
* [new branch] HEAD -> dp/some-crappy-feature
The next step is to create a "pull request," an entry on GitHub where we propose
to the team that our branch be merged into the master
branch. The easiest way
to do this is to click the convenient link that popped up in the output of the
previous step. You can also do so by visiting the repo in question on GitHub, and
a UI element will appear at the top of the page asking if you want to create a
pull request.
When you have the pull request on GitHub, you can look over your code or add other people as reviewers. At this point, you may decide you want to make more changes to your code. If you do, simply make more commits on the same branch and push them, and they will automatically show up in the pull request. For example, you might make some changes and then run
git add .
git commit -m 'Fixed a typo'
git push origin HEAD
where all of these commands are the same as above.
There is one bit of trickiness here, which is that while you were doing your
work, other people may also have been working on the same project and have
already merged their changes into master
before you finished with yours. To
deal with this, when getting ready to merge your code or whenever you feel like
it you will want to grab the latest version of master
and make sure that your
branch is based on it. To do so, run
git fetch
git rebase origin/master
git push origin HEAD -f
Explanation: first, git fetch
has Git go and find out about all the things
that GitHub knows about, such as changes that have been made to master
. Then,
git rebase origin/master
adjusts your current branch to incorporate any
changes from master
- as above, the origin
in origin/master
refers to
GitHub, the repo from which you originally ran git clone
when you were first
getting set up. Finally, we push the changes, but this time our git push
command includes the -f
flag for "force," which is necessary after a rebase.
The explanation of why this is needed is somewhat involved and is best saved for
another time.
When you're happy with a pull request, press the big green "Merge" button in the
pull request UI to merge your changes into master
. Now back in our terminal,
you can switch back to master
and pull the latest version, and you should be good to go with an up-to-date repo that includes all your changes. As a reminder, the commands to switch to master and update to
the latest version, as given above, are
git checkout master
git fetch
git rebase
If you have an hour or two, Learn Git Branching is an excellent interactive game for building a mental picture of Git.