Git for dummies
This is a very clear and simple cheat sheet that describes all you need in order to use the 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.
Installing git
Windows
Download installer, which installs a terminal version that is similar to linux one
MacOS
There should be a package at https://git-scm.com/download/mac or you could just compile it yourself!
Linux
For some weird reason, 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 https://git-scm.com .
Setting it up
You need these in order to push:
- Wkimedia Developer account to contribute to Git repositories
- SSH key
Terminology
VCS
Abbreviation for the generic term "Version control system". "Git" is one of many VCS's.
Git
Content tracker created by Linus Torvalds. Git, unlike many other VCS's is distributed, which means that everyone has a copy of whole repository, instead accessing it through a central server.
Branch
Makes it possible for you to diverge from the main line of development and continue to do work without messing with that main line. Usually, you want to make all your changes in your own branch instead of writing them to master one.
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 of 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).
Gerrit
Review system built on top of Git. It allows experienced developers to review changes made by others and merge them into master branch.
Guide
Download the repository: clone
Initial checkout - called "clone". Fetches a remote repository from a remote server and save it to local folder.
git clone <repository goes here>
Example:
# Download a read-only (you can't push) copy of huggle using http git clone https://github.com/huggle/huggle3-qt-lx # Download a read-only copy of huggle using http to folder "foobar" git clone https://github.com/huggle/huggle3-qt-lx foobar
Update the downloaded repository: pull
- update your copy of repository with the version on remote server
git pull
- update which automatically merge stuff - called rebase, update the repository and merge it with your commits
git pull --rebase
- 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.
git review -d <number>
where <number> is the gerrit change number to download the patchset to a new branch, and work on that instead. Note that if you have previously used git review -d
to download a patchset and made changes to it, but have not uploaded the changes to gerrit, running the command again would destroy all local changes, so you should first use git checkout -b branch_name
to copy the local changes to a new branch if you want to preserve them.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:
# compare current head with previous commit, that mean it compare what you just committed with what was there before you did that git diff HEAD^1 # compare with any given id git diff <commit-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 <branch_name>
If you want to push your branch to origin
git push origin <branch_name>
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
# insert a file to commit git add file2 # in case you decided that you don't want to commit file2 you can revert the git add by doing git reset file2 # Or all pending changes with just: git reset (but this won't change the files on disk) git add file.cpp # commit only the files which were marked with git add git commit # or commit also all files tracked by git which were changed git commit -a
In case you want to change the commit you just made, do
git commit --amend # for example you forgot to add important_thing.c 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
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).
# backup whole repository
cp -r . /tmp/backup
# request git to merge two last commits (HEAD and previous 1 commit)
git rebase -i HEAD~1
# leave pick near to message you want to keep, change all messages you want to merge to "squash" like
# sometimes it is needed to do this
git rebase
# now you can try to push again
git-review -R
# or
git push
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.
Upload your commits, branches or tags to server: push
When everything is fine
Ideally you type git push
and everything works.
Unfortunately, that works rarely.
When it's not fine
- 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)
scp -p -P 29418 username@gerrit.wikimedia.org:hooks/commit-msg .git/hooks/ git commit --amend
- There were some updates and you are not up to date
git pull --rebase
- You are using wrong command to push
- Sometimes it's needed to use following, should you know why, feel free to explain it:
git push origin HEAD:refs/publish/master
- Some repositories have own system
git push-for-review-production
- Some repositories require git review
git-review -R
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:
# soft reset - this will reset all git add <whatever here> - this will NOT reset any changes you have done to files
git reset
# revert all commited files to version they had after last commit - this will revert all changes to file you have done to latest commit
git stash
# hard reset
git reset --hard origin/master
# if you want to revert all changes to all files and remove all files that were added since last commit,
# restore all files that you removed, basically you want to revert repository to what it was since you cloned it
# or commited, get to root of repository (where .git is) and delete everything except .git
rm -r *
git stash
Gerrit specific
Installing git review
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/c/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
# configure git
git config --global user.email some.guy@example.org
git config --global user.name Petrb
#########################################
# GERRIT
#########################################
# get a repo
git clone https://gerrit.wikimedia.org/r/mediawiki/core.git mediawiki
cd mediawiki
# now, do some changes and commit them:
git commit -a
# now push them
git-review -R
#######################################
# GITHUB
#######################################
# get a repo
git clone git@github.com:huggle/huggle3-qt-lx hg
cd hg
# checkout new branch
git checkout -b feature
# now, do some changes and commit them:
git commit -a
# now push them
git push origin feature