Friday, August 2, 2013

Git Commands Cheat Sheet

Provide Your Identity to Git
Configure your identity to Git by setting your name and email id. Git uses this to track your changes when you commit. 
$ git config --global user.name "Siddheshwar Rai"
$ git config --global user.email "rai.skumar@gmail.com"

--global is optional and it means Git will always use above details (for all projects inside repository). To use a different name for a specific project, you should run above commands inside project without passing --global

Set Your Editor
Git uses vi or vim editors by default. If you want to use a different editor you need to override the default value.
$ git config --global core.editor emacs

Set Your Diff Tool
Git supports tools like kdiff3, tkdiff, xxdiff, emerge, vimdiff etc.
$ git config --global merge.tool vimdiff

Check Your configured settings 
$ git config --list
$ git config user.name 

Git Help
$ git help <verb>
$ git help config

Initializing a Repository
If you are starting from scratch and want to track your project in Git. Move to your project directory and then initialize Git repository. 
$ cd /d/workspace/MyProject
$ git init

Above command creates .git directory inside your project. This directory will contain all your necessary repository files. As of now it will be an empty directory.

Add Files to Repository
In order to track file/s; you need to add them to the repository as shown below :
$ git add *.java   #add all java files
$ git add Apple.java
$ git add README

Clone an Existing Repository
If you want to contribute to an existing Git project, you need to start by cloning it. The corresponding thing in SVN/CVS is checkout. When you checkout you get all the latest files of the given project.  This means you get all history data along with the latest one. This way you can also restore your server with your local data in case server gets crashed/corrupted. 
$ git clone <url>
$ git clone https://github.com/raiskumar/XImage.git  #clones my project XImage

Above command creates a directory named as XImage, initializes .git directory inside it and takes out all code.
$ git clone https://github.com/raiskumar/XImage.git MyXimage

Names your local copy as MyXimage instead of XImage. Note that above commands we are using HTTP protocol to fetch code. Similarly, you can use the git protocol as well. 

$ git clone git://github.com/raiskumar/XImage.git


Check File Status
You can check which stage your file is through status command. It also tells you which branch you are on.
$ git status
# On branch master (master is default).

If you add a new file to your project and then run status command then that file will be listed under header Untracked Files. This basically means that Git sees a file you didn't have in the previous snapshot(commit). To include it, you need to commit it. 

Tracking New Files
You begin tracking a file by running add command. After running add command on a file if you run status command then Git shows that file as tracked and staged. 
$ git add README
$ git add dir  # Add all files of the directory
$ git status

Now README file will be under Changes to be Committed heading (means its staged). 

Staging Modified Files
Let's change a file that was already tracked and then run status command. Let that file is A.java.
$ git status

A.java appears under Changes not staged for commit - means, the file that is tracked is modified in the working directory but not staged yet. To stage it; you need to run add command. So through this command, you begin tracking new files, stage files and for marking the merge-conflicted file as resolved. So now running add command on A.java will show it under Changes to be committed heading. 

Now suppose you again modify it and then run the status command again. Now, this file will be shown under?
Both Changes to be committed and Changes not staged for commit.

So it is listed as staged as well as unstaged both. This is because Git staged file as it is when you run add command but it underwent changes after that. 

Ignoring Files
There are cases when you don't want to add some of the files. These could be automatically generated files like logs or files which get generated by the system like compiled files. This you can achieve by creating a .gitignore file.

$ cat .gitignore
*.class

#ignore build directory
build/

#Eclipse . files
.classpath
.project
.settings

#target file which has a jar
target/

Viewing Staged and Unstaged Changes
status command tells only which file changed, but doesn't give details. diff command can be used to know more details about staged/unstaged files and exact changes. Diff command tells which line was changed. 
$ git diff   # see what have you changed but not yet staged 
$ git diff --cached  # see what have you staged which will got to next commit
$ git diff --staged  # 1.6.1 and later 


Committing Your Changes
$ git commit   # launches editor for giving comments 
$ git commit -m "message 1"  # inline message
$ git commit -m "comming message" path/to/dir/*  # commit a particular file/files inside a directory

Note: If you don't give directory path; it will commit all staged files.

Successful commit shows which branch you committed, what SHA-1 checksum the commit has, how many files were changed, statistics about line added/removed.

Show committed files / To-be pushed files
$ git diff --stat origin/master

Above command will list down all file names (one in each line) which are committed.

Last line of output tells number of files changed, insertions(+) performed, and deletions(-) performed.

Skipping the Staging Area
Git provides a simple shortcut -a to skip the staging area.
$ git commit -a -m "Added new file"   

Removing Files
To remove a file from Git, you have to remove it from your tracked files (i.e remove it from staging area ) and then commit. The Git rm command does that and also removes the file from your working directory. 
$ git rm Abc.tmp 
$ git commit   # File is permanently gone 

What if you want to remove file from staging area but keep it in working area. That is, keep file on your hard drive but remove it from Git. This is particularly useful if you forgot to add a file in .gitignore file. 
$ git rm --cached readme.txt 
$ git rm log/\*.log  # Remove all log files 

Moving Files
Unlike some other VCS systems Git doesn't track file movement explicitly. If you rename a file in Git , Git doesn't store its history. 
$ git mv README.txt README 

View Commit History 
Unlike some other VCS systems Git doesn't track file movement explicitly. If you rename a file in Git , Git doesn't store its history. 
$ git log  # Prints history in reverse chronological order 
$ git log -p -2  # Shows difference introduced in each commit; -2 to limit count
$ git log -U1 --word-diff # Word diff instead of line diff
$ git log --stat  # Show abbreviated stats of each commit
$ git log --pretty=oneline  # pretty for changing format other than default (short,full, fulller, oneline)
$ git log --pretty=format:"%h %s " --graph  
$ git log  --since=2.weeks

Push Files
$ git push origin master
$ git push -u origin master
git push origin <branch-name>

Pushes change to 'master' branch at 'origin'.

Note: By convention remote repository is referred to as origin and initial local repository/branch as master

Pull Files
$ git pull origin master

Pulls changes locally from the master. It does two things: it does git fetch and git merge as per the setup in your config.

Undo Last Pull
$ git reset --hard

Above command resets to previous state.

GUI History Visualizer
You can visualize commit history using a GUI tool. 
$ git gitk 

Undoing Things
What if you commit to early, forgot to add something or messed up something. Such case you need to commit again.
$ git commit --ammend  #Takes your stagging area and uses it to commit 
$ git commit -m 'Initial commit '
$ git add Forgotten_File.java
$ git commit --ammend

Fix merge conflicts 
$ git mergetool&
Above command opens a GUI tool if you have installed one.

Create a feature branch from master
$ git branch
master

$git branch feature1

So whatever branch you are on, above command will create a copy of that branch and name it as feature1.

$ git branch

feature1
master

$git checkout feature1

Now, you are on feature1 branch