Git for dummies

This is a very clear and simple cheat sheet that describes all you need in order to use the stupid content tracker Git and Gerrit. It should give you at least the minimal knowledge needed in order to push to all major repositories we use, including these on GitHub and other sites.

If you are a git expert, you are welcome to improve this manual, but please keep it extremely simple.

Windows
Download installer from here: http://git-scm.com/download/win which installs a terminal version that is similar to linux one

MacOS
There should be a package at http://git-scm.com/download/mac or you could just compile it yourself!

Linux
For a weird reasons the git package in debian and ubuntu is called "git-core" and git doesn't link to it. Getting git-core will install it.

On other distro's visit http://git-scm.com

Setting it up
You need these in order to push:
 * account on wikimedia gerrit or any other git repository hosting
 * e-mail
 * name
 * public / private key - http://git-scm.com/book/en/Git-on-the-Server-Generating-Your-SSH-Public-Key

You can configure your username and e-mail by typing (please use your own mail and name): git config --global user.email mail@example.org git config --global user.name "Bob the Great :o"

VCS
Version control system - GIT is one of many VCS's

Revision
When you commit your changes, a new revision is created. History in git, consist of revisions. Every revision has a commit message and unique ID.

Remote
Repository that is hosted on remote system, usually accessible through ssh or https.

Repository
Base for all content that is tracked by git.

Origin
In git default alias for remote repository you cloned is called "origin". If you clone repository foo from server "http://bar/foo.git" that will be your origin.

Master
Git's default branch that is usually created upon creation of repository, but doesn't need to be. It's most common name for a default branch for a repository, but it doesn't need to be. (Just as superuser in Linux doesn't need to be called root, but almost always is).

Download the repository: clone
Initial checkout (svn checkout) - called "clone". Fetches a remote repository from a remote server and save it to local folder. git clone

Example: git clone http://github.com/huggle/huggle3-qt-lx git clone http://github.com/huggle/huggle3-qt-lx foobar
 * 1) Download a read-only (you can't push) copy of huggle using http
 * 1) Download a read-only copy of huggle using http to folder "foobar"

Update the downloaded repository: pull
git pull git pull --rebase
 * update (svn up) - called pull
 * update which automatically merge stuff - called rebase, update the repository and merge it with your commits


 * Edit conflicts

It often happens that you run into an edit conflict. That is annoying, but git has fairly good mechanism to deal with them. There is a magic command

git mergetool

You can also install some 3rd editor such as kdiff3 that will open a nice GUI which can help you with merging, mergetool will then ask you which editor you wish to use.

Check what has been changed: diff
In order to see what you changed before you commit do:

git diff

In order to see what you changed after commit do:

git diff HEAD^1 git diff 
 * 1) compare current head with previous commit, that mean it compare what you just committed with what was there before you did that
 * 1) compare with any given id

Create your own branch
You can view all branches that were ever checked out on your local copy using git branch

If you want to create a new branch, forking the branch you are currently on, use git checkout -b 

If you want to push your branch to origin git push origin 

Save the changes: commit
Unlike in svn, the committing is done locally and then it needs to be sent to server (using git push) or for a review (using git review).

You need to specify which files will be committed. Even if you change the file it won't be committed, unless you tell git to do that. You can use command git add in order to make it commit the changes git add file2 git add file.cpp git commit git commit -a
 * 1) insert a file to commit
 * 1) in case you decided that you don't want to commit file2 you can revert the git add by doing git reset file2
 * 2) Or all pending changes with just: git reset  (but this won't change the files on disk)
 * 1) commit only the files which were marked with git add
 * 1) or commit also all files tracked by git which were changed

In case you want to change the commit you just made, do git commit --amend git add important_thing.c git commit --amend that will change the content of existing commit, if you already pushed it, then this can't be pushed to remote again as you changed something what already exist, do this only if you didn't push yet
 * 1) for example you forgot to add important_thing.c

Now that you committed the change, you may be ready to push it.

Merge multiple commits: squash
Gerrit doesn't like too many commits in 1 push, so that you need to occasionally make 1 commit of multiple (that is called squashing).

Viewing the status of a branch: git status
git status

Viewing the commit log for a branch: log
git log

Press 'q' to back out of this view.

When everything is fine
Ideally you type  and everything works. Unfortunately, that works rarely.

When it's not fine
scp -p -P 29418 username@gerrit.wikimedia.org:hooks/commit-msg .git/hooks/ git commit --amend git pull --rebase git push origin HEAD:refs/publish/master git push-for-review-production git-review -R
 * You get rejected because you don't have permissions:
 * You may have missing username in url, everytime you ssh somewhere, you need to specify your username (petrb@server.com)
 * You checked out using http
 * You can change the url in .git/config
 * You really don't have permissions
 * You need to contact the owner of repo
 * You are missing some hooks
 * Gerrit requires the commit-msg hook (this may no longer be required)
 * There were some updates and you are not up to date
 * You are using wrong command to push
 * Sometimes it's needed to use following, should you know why, feel free to explain it:
 * Some repositories have own system
 * Some repositories require git review

If you are using git-review you need a .gitreview file in a repo, if it's not there, you need to create it: [gerrit] host=gerrit.wikimedia.org port=29418 project= here you add a relative path example: labs/toollabs.git defaultbranch=master defaultrebase=0

Resetting the repository: reset & stash
Git makes it very hard to revert the changes or reset the repository to original state as it was when you cloned it. In svn, you can simply delete the files and run svn up which restore them. In git doing so has no effect.

There are many ways to reset the repository to original state, but I found it simplest just to delete it and clone it again. In case it's a huge repository, you probably don't want to waste time and try these:

Ubuntu / Debian
sudo apt-get install git-review

Downloading a patchset from gerrit
git review -d 31337

This downloads the contents of https://gerrit.wikimedia.org/r/31337/, puts them in a new branch, and switches to the branch.

Rebasing a patchset on master
First, try clicking "Rebase" in gerrit. If that fails, make sure everything is committed, and then run git checkout master git pull git checkout branch_name git rebase master

Follow the on-screen instructions.

Examples
svn checkout - clone