Learning a new tool can sometimes seem boring. Especially when there are a lot of new concepts involved. And just when you think you are comfortable you might need to Google for the right options. Git is one such tool. Earlier I wrote about an interactive Git tutorial along with links to some informative resources on Git. I also shared the list of common Git commands I use regularly for development.
Today I came across a game to evaluate one’s command on Git: git-game. It’s a set of tasks you need to complete. Each task is a level, much like the puzzle games. The levels are incrementally difficult too.
How to play
Checkout the repository from GitHub:
$ git clone https://github.com/hgarc014/git-game
The next clue (including the first one) is always in the README.md file. Good luck!
UPDATE: If you are done with version 1, you can move on to The game of git version 2. Clone the repository:
$ git clone https://github.com/git-game/git-game-v2
and start with README.md.
Scared of git because of the options and switches you may need to remember? Try hub, developed primarily with GitHub users in mind. It simplifies the syntax of many common git commands and integrates well with GitHub repositories.
hub provides shortcuts for the following (at the time of writing):
- git clone
- git remote add
- git fetch
- git cherry-pick
- git am, git apply
- git fork
- git pull-request
- git checkout
- git merge
- git create
- git init
- git push
- git browse
- git compare
- git submodule
- git ci-status
- git help
$ hub clone jarun/markit
$ git clone git://github.com/jarun/markit.git
$ hub remote add jarun
$ git remote add jarun git://github.com/jarun/CURRENT_REPO.git
Refer the project page for details and examples on all the commands (link below).
Download the latest pre-compiled binary for your architecture. hub works best when it is aliased as git.
Display instructions for the current shell:
$ hub alias
//-s outputs a script for eval
$ hub alias -s
Add the following to your .bash_profile:
eval "$(hub alias -s)"
hub provides shell tab completion scripts for bash and zsh shells.
GitHub is the most popular development platform among open source developers. The ease of use and interface the provides on top of the robust and complex version control system Git is amazing. However, the service is a commercial one for paid or larger projects. However, organizations all around the world (around 100,000 of them) use its open source clone – GitLab Community Edition to setup their own version control system.
GitLab is written in Ruby on Rails. Features include:
- Activity stream
- File browser
- Git powered WiKi
- Powerful code review
- Issue management
- Code snippets
- Web hooks
- and more…
The community edition can be downloaded free of cost and deployed on a server. GitLab also has its own hosting service. It offers unlimited private or public repositories and unlimited number of private collaborators.
The community edition packages are available for Ubuntu, Debian, CentOS and Raspbian.
Webpage: GitLab HQ
Git is a very advanced and powerful version control system. It supports too many features and it’s difficult to remember each and every command unless you are a heavy Git user or a Git dev yourself. I try not to remember too many of them. However, Git is used best when it is used from the cmdline. And in my experience, there are a few commands that are used much more frequently than others. I will list those in this article to have a reference for myself as well as for others. In the examples I will use GitHub’s own Atom project repository link for the examples.
Before I begin, here’s a good practice for a Git dev – always have a clean master branch checked-out from the original project’s master branch. Make your changes to a separate development branch and rebase your master and dev branch regularly with the main project branch. In other words, your changes should go into the project’s master branch from your dev branch. Those changes are then pulled into your master branch.
Git installation and initial setup
Add a project
- Use GitHub’s web interface to fork your own master branch from the project’s main branch. Clone your mater branch locally.
$ mkdir atom
$ cd atom
$ git clone https://github.com/username/atom.git
- In case of very old or large repositories, you can do a shallow clone by fetching history of only latest n commits.
$ git clone --depth 2 https://github/username/atom.git
- Add the original Atom project as upstream.
$ git remote add upstream https://github.com/atom/atom.git
- Use the GitHub web interface to create a new branch named dev. This is where your own changes should go first.
- Check-out (or switch to) the dev branch
$ git checkout -b dev
The powerful checkout command
Get upstream changes to your master branch
Get changes from your master to dev branch
A few words of merge and rebase first. Rule of the thumb is – use merge/rebase when you have no changes in your local dev branch. Both result in same commit history. However, if you have changes in your local dev branch but would like to get the changes in remote as well, then use rebase for a clean commit history.
Other common scenarios
- Check the branch and local status (maybe after a merge/rebase conflict)
$ git status
- Check and local modifications to tracked files
$ git diff
- Set diffuse as the diff tool
$ git config --global diff.tool vimdiff
$ git config --global difftool.prompt false
$ git config --global alias.d difftool
To view the diff in diffuse
$ git d
$ git d commit#1 commit#2
$ git diff HEAD^ HEAD
- Check commit history
$ git log --stat
- Hide local changes and pull, then unhide local changes
$ git stash
$ git pull
$ git stash pop
- Commit changes locally
$ git commit -a -s
- Push the changes to origin
$ git push origin dev
- Undo a commit, make changes, redo it
$ git commit ...
$ git reset --soft HEAD^
$ git add ...
$ git commit -c ORIG_HEAD
- Edit/amend the most recent commit message
$ git commit --amend -m "New commit message"
If the commit is already pushed to remote
$ git push origin dev --force
- Clean local changes
$ git reset --hard HEAD
$ git clean -f -d //cleans all untracked files as well
- Reset unmerged files
$ git reset filename
$ git checkout filename
- Accept all changes post merge conflict occurs
$ git reset --hard origin/dev
$ git merge -X theirs master
- If you have lost the URL of the remote repo you forked
// if referential integrity has been broken:
$ git config --get remote.origin.url
// if referential integrity is intact:
$ git remote show origin
Tags are baselines you can revert back to in the future.
- Get and list tags
$ git pull --tags
$ git tag
- Create a tag
$ git tag -a tag_name -m "your message here"
$ git push origin --tags
- Delete a tag
$ git tag -d tag_name
$ git push origin :refs/tags/tag_name
Another useful list is the giteveryday man page.
Feel free to suggest if you think I should add any command to the article.
Git is a very advanced version control system and using Git can be tricky if you are new to it. ungit is a great aid in spending less time in learning Git than in actual development. It is a web-based application that uses node.js. IMHO it is also a very helpful utility to learn Git visually first than jumping into the cmdline with Git. The video above gives a quick overview of how ungit can help you stay off the cmdline to use Git. The visual representations of the probable actions are simply brilliant!
ungit is multiplatform and tightly integrated with GitHub. It has a plugin based architecture so it can be extended easily to support other source control services those support Git.
You need node.js, npm (comes with node.js) and git to use ungit. Necessary instructions to use ungit are given in the ungit GitHub page (link below).
I was looking for a good GUI based Git repository browser to view changes. To speak the truth, the terminal is not really the best option to look at a overwhelming number of change records which need to be examined in detail and in reasonable time. There are many Git GUI interfaces on Linux but some of them are bulky and some lack finesse. I found QGit to be exactly the tool I needed.
- Very lightweight. Written using Qt/C++.
- Auto branch configuration detection
- Shows everything you need to understand a change: commit history (including range), change log for individual commit, diff, modified file list
- Can launch an external diff viewer like Diffuse
- File tree view that helps to track commits to a single file
- Save a patch series to send for review, apply a patch at any revision, view a patch
- User defined keyboard shortcut for Actions
- Commit, amend commit, make branch, make tag
- Available by default in the repositories for major distros
QGit integrates seamlessly with Diffuse, a graphical file diff viewer. Diffuse is one of the few diff-merge tools that supports N-ary file merge. However, one of its most powerful features is the support for version control systems. Diffuse is written in Python.
- Merge N number of files side by side in different panes
- Manually adjust line matching and directly edit files
- Integrates with file manager menu
- Modify both left and right side files (2-way merge)
- Retrieve revisions of files from Bazaar, CVS, Darcs, Git, Mercurial, Monotone, SVN and SVK repositories for comparison and merging
To install QGit and Diffuse on Ubuntu, run:
$ sudo apt-get install qgit diffuse
Webpage: QGit, Diffuse
Tig is an ncurses-based text-mode interface for git. It functions mainly as a Git repository browser, but can also assist in staging changes for commit at chunk level and act as a pager for output from various Git commands. To browse a git repository navigate inside a versioned directory and run
tig. To install tig on Ubuntu:
$ sudo apt-get install tig
If you are related to Linux development, you probably have heard of Git already. It is a powerful and widely popular version control system. The Linux kernel project is managed using Git. Git does not have any GUI of its own and needs to be accessed from the cmdline. SmartGit/Hg is a multi-platform (Linux, Windows, Mac) GUI client for Git and Mercurial (Hg). It is simple to use, has powerful features and comes as a bundle that packages utilities like SSH, FTP etc. so that you do not need to install anything separately. As you can see from the above image, the interface is pretty attractive as well. SmartGit/Hg depends on the JAVA runtime environment.
Linus explains distributed version control systems with the example of git (which he wrote for Linux kernel version management) in this old video. I don’t think anyone else can make a technical discussion as hilarious and enjoyable as Linus.
Many projects run on the open source version controlling system Git. If interested in learning the basics, here is a fascinating tutorial to start with:
Got 15 minutes and want to learn Git?
Tutorials on how to use GitHub/Git: