Git

  • Distributed Version Control(DVCS) e.g. Git, Mercurial(Hg), BitKeeper, Bazaar.
  • Linus Torvalds created Linux and Git.
  • Msysgit is good git version for Windows.
  • Every object in Git has unique SHA1 key

Porcelain Commands:

  • Add
  • Commit
  • Push
  • Fetch
  • Pull
  • Branch
  • Checkout
  • Merge
  • Rebase

Plumbing Commands:

  • Cat-file
  • Hash-object
  • Count-objects

Install git on Linux system:

  • Debian/Ubuntu distro: apt-get install git-core
  • Fedora distro: yum install git-core

Git version command:

1
2
$ git --version
git version 2.11.1.windows.1

Get help command:

1
$ git --help

Git areas(Mnemonic WIRES)

  • Working-Area
  • Index-Area
  • Repository-Area (Local m/c)
  • External-Repository-Area ( Remote m/c)
  • Stash-Area

Pointers:

  • HEAD: Pointer to a pointer. Points to current branch.
  • Master: Pointer to default local branch.
  • Origin: Pointer to default remote branch.
  • Stash: Pointer to stashed content.
  • BranchName: Pointer to branchName SHA1 hash.

.gitignore

1
/log/*.log

Git hash-object command:

1
2
$ echo "Apple Pie"|git hash-object --stdin
23991897e13e47ed0adb91a0082c31c82fe0cbe5

Git init command:

  • Initiates a Git repository
  • Adds a .Git folder.
  • You will only find one instance of .git directory per repository. It is not repeated in sub directories similar to SVN.
    1
    2
    $ git init
    Initialized empty Git repository in C:/Users/unshakeable/MyGit/.git/

Git hash-object Command with -w flag:

1
2
$ echo "Apple Pie"|git hash-object --stdin -w
23991897e13e47ed0adb91a0082c31c82fe0cbe5

GitHash

  • MyGit>.git>objects directory stores all Git objects
  • You can ignore info and pack directories

Git cat-file command with -t flag:

  • Use cat-file to check the value stored in Hash-map against the SHA1 key
  • “t flag” is used to display type.
    1
    2
    $ git cat-file 23991897e13e47ed0adb91a0082c31c82fe0cbe5 -t
    blob

Git cat-file command with -p flag:

  • “p flag” is used for pretty printing
    1
    2
    $ git cat-file 23991897e13e47ed0adb91a0082c31c82fe0cbe5 -p
    Apple Pie

Sample Folder/File structure:

  • Create “cookbook” directory with below structure:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ tree
    .
    |-- .git
    |-- menu.txt
    `-- recipes
    |-- README.txt
    `-- apple_pie.txt
    1 directory, 3 files

Git status command:

1
2
3
4
5
6
7
8
9
10
11
12
$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
menu.txt
recipes/
nothing added to commit but untracked files present (use "git add" to track)

Git log command:

1
2
3
4
$ git log
:q to quit log output, Ctrl+F, Ctrl+b
$ git log --oneline
$ git log --oneline | wc -l
  • Most commonly used:git god
    1
    $ git log --graph --oneline --decorate --all

Git shortlog command:

1
2
$ git shortlog
$ git shortlog -sne

Git add command:

  • used to stage a file i.e move from Working-Area to Index-Area.

  • Add all new files and modified files to staging area:

    1
    $ git add .
  • Add new file to staging area:

    1
    $ git add -u
  • Add all files to staging area:

    1
    $ git add -A
  • Add all html files to staging area:

    1
    $ git add *.html

Git rm –cached command:

  • Used to unstage a file i.e deletes the file from Index-Area region only.

    1
    2
    $ git rm --cached menu.txt
    rm 'menu.txt'
  • Deleting file from both Index-Area and Working-Area. Warning will be displayed

    1
    $ git rm <fileName>
  • Force delete file from both Index-Area and Working-Area

    1
    $ git rm f

Git clean

1
2
$ git clean -n
$ git clean -f

Git checkout command:

  • Used to move a file from Index-Area to Working-Area.
  • Changes in Working-Area will be overwritten.
    1
    $ git checkout -- menu.txt

Git Configuration:

Git configuration can be stored at 3 places. Git config is hierarchical in nature. Below is the order of hierarchy:

  • System-level configuration(Rarely used): git config –system [config file is stored at C:\Program Files\Git\etc\gitconfig]
  • User-level git configuration: git config –global [config file is stored at C:\Users\helloGuy.gitconfig]
  • Repository-level git configuration: git config [config file is stored at C:\Users\helloGuy\Code.git\config]

Common user-level git configuration:

  • Add user.name to global git config:

    1
    $ git config --global user.name "helloGuy"
  • Add user.email to global git config:

    1
    $ git config --global user.email "hello.world@gmail.com"
  • Add help.autocorrect to global git config:

    1
    $ git config --global help.autocorrect 1
  • Add color attributes to global git config:

    1
    2
    3
    $ git config --global color.ui auto
    $ git config --global color.status auto
    $ git config --global color.branch auto
  • Add core.autocrlf to global git config:

    1
    $ git config --global core.autocrlf true
  • Add branch.autosetuprebase to global git config:

    1
    $ git config --global branch.autosetuprebase always
  • Add default diff algorithm

    1
    2
    $ git config --global diff.algorithm histogram
    $ git config --global diff.algorithm patience
  • Add alias for commonly used commands:

    1
    $ git config --global alias.god "log --graph --oneline --decorate --all"
  • Configure Beyond Compare as diff-tool:

    1
    2
    $ git config --global diff.tool bc3
    $ git config --global difftool.bc3.path "c:/Program Files/Beyond Compare 4/bcomp.exe"
  • Configure Beyond Compare as merge-tool:

    1
    2
    $ git config --global merge.tool=bc3
    $ git config --global mergetool.bc3.path=c:/Program Files/Beyond Compare 4/bcomp.exe
  • Show all global git config:

    1
    2
    3
    4
    5
    6
    7
    $ git config --global --list
    user.name=helloGuy
    user.email=hello.world@gmail.com
    core.editor=notepad++
    core.autocrlf=true
    help.autocorrect=1
    color.ui=auto
  • Remove user.name from repository git config:

    1
    $ git config --unset user.name
  • Show all repository level git config: This will list all config properties from all 3 scopes.

    1
    $ git config --list

Git commit command:

  • What is a commit?
    • SHA1 to a tree
    • Author name
    • Commit date
    • Commit message
    • Parent: used for versioning
1
2
3
4
5
6
$ git commit -m "my first commit"
[master (root-commit) 2bde229] my first commit
3 files changed, 3 insertions(+)
create mode 100644 menu.txt
create mode 100644 recipes/README.txt
create mode 100644 recipes/apple_pie.txt

Git Object Modal
Git Object Modal

Git object model: Structure of the initial commit

1
2
3
4
5
6
7
8
9
$ git cat-file 2bde2295ed4b1d2eefaa0486cf098d8669621a50 -t
commit
$ git cat-file 2bde2295ed4b1d2eefaa0486cf098d8669621a50 -p
tree be4d5bfce489a2591e7fed5c672f9e52cd695a43
author Unshakeable <unshakeable@gmail.com> 1487695379 -0500
committer Unshakeable <unshakeable@gmail.com> 1487695379 -0500
my first commit

Git object model: Structure of subsequent commits(versioning)

  • From 2nd commit onwards, you have additional “parent” field, which points to previous commit.
1
2
3
4
5
6
7
8
9
10
$ git cat-file f2b32d8d5f262f035e0090c7b7d2161f2ff26f45 -t
commit
$ git cat-file f2b32d8d5f262f035e0090c7b7d2161f2ff26f45 -p
tree 4e100b23f2cf34b2931f8131aa8219a3419d6d60
parent 2bde2295ed4b1d2eefaa0486cf098d8669621a50
author Unshakeable <unshakeable@gmail.com> 1487704250 -0500
committer Unshakeable <unshakeable@gmail.com> 1487704250 -0500
my second commit

Git object model: Structure of tree

  • Tree object can point to files and other trees
    1
    2
    3
    4
    5
    6
    $ git cat-file be4d5bfce489a2591e7fed5c672f9e52cd695a43 -t
    tree
    $ git cat-file be4d5bfce489a2591e7fed5c672f9e52cd695a43 -p
    100644 blob 23991897e13e47ed0adb91a0082c31c82fe0cbe5 menu.txt
    040000 tree 3ee76fde69b730530f1682f1f51789e89cf30500 recipes

Git object model: Structure of blob

  • File name is not stored in blob, but in the tree pointing to it.
    1
    2
    3
    4
    5
    $ git cat-file 23991897e13e47ed0adb91a0082c31c82fe0cbe5 -t
    blob
    $ git cat-file 23991897e13e47ed0adb91a0082c31c82fe0cbe5 -p
    Apple Pie

Git count-objects command:

1
2
$ git count-objects
8 objects, 0 kilobytes

Git Tags:

  • Tags are like labels/references.
  • A tag is like a branch that doesn’t move.
  • Git has two type of Tags.
    • Regular or lightweight tags
    • Annotated tags

Annotated tags: comes with message

1
$ git tag -a myTag -m "I love tags"

Lightweight/Regular tag:

1
$ git tag myLightTag

Get list of Git tags:

1
2
3
$ git tag
myTag
myLightTag

Git object model: Structure of Tag

1
2
3
4
5
6
7
8
9
10
$ git cat-file myTag -t
tag
$ git cat-file myTag -p
object f2b32d8d5f262f035e0090c7b7d2161f2ff26f45
type commit
tag myTag
tagger Unshakeable <unshakeable@gmail.com> 1487705105 -0500
I love tags

Stash: is useful when we have uncommitted changes and need to switch branch.

$ git stash
$ git stash apply
$ git stash list
$ git stash clear
$ git stash pop
$ git stash drop

Git branch:

  • Git creates the default branch(master) on first commit.
  • Current branch will be marked with asterisk.
  • Branch is just a reference to a commit.

Command to list all branches:

1
2
3
$ git branch
$ git branch -r
* master

Structure of Master branch:

  • Git Master branch reference is stored in .git/refs/heads directory
    1
    2
    $ cat .git/refs/heads/master
    f2b32d8d5f262f035e0090c7b7d2161f2ff26f45

Command to create new branch:

1
2
3
4
5
6
7
8
9
10
11
$ git branch decRelease
$ git branch
decRelease
* master
$ cat .git/refs/heads/decRelease
f2b32d8d5f262f035e0090c7b7d2161f2ff26f45
$ cat .git/refs/heads/master
f2b32d8d5f262f035e0090c7b7d2161f2ff26f45
1
$ git branch --set -upstream master origin/master

Command to delete a branch

1
git branch -D <BranchName>
  • HEAD is just a reference to a branch.
  • So it is kind of pointer to a pointer.
1
2
$ cat .git/HEAD
ref: refs/heads/master

How to switch to other branch: checkout

As part of checkout following two actions happens:

  • HEAD reference moves to decRelease
  • Content of decRelease is downloaded to Working-Area and Index-Area.
    1
    2
    $ git checkout decRelease
    Switched to branch 'decRelease'

Git diff command:

  • Find difference between Working-Area and Index-Area:

    1
    $ git diff
  • Find difference between Index-Area and Repository-Area:

    1
    $ git diff --cached
  • Find difference between two commits:

    1
    $ git diff hash1..hash2
  • Find difference between current commit and previous commit:

    1
    $ git diff head~1..head
1
$ git diff head~3:Readme.txt..head:Readme.txt
1
$ git diff --histogram

Git reset command:

  • It moves the head to specified location and updated area contents based on flags.

  • Hard reset: Sets the HEAD to corresponding location and updates both Working-Area and Index-Area.

    1
    $ git reset --hard <branchName>
  • Mixed reset(default): Sets the HEAD to corresponding location and updates just the Index-Area.

    1
    $ git reset --mixed <branchName>
  • Soft reset: Just sets the HEAD to corresponding location. Does not update content of any area.

    1
    $ git reset --soft head~1

Gitk: git UI tool

1
$ gitk

Merge command:

  • You are on master branch and want to merge with decRelease branch

    1
    $ git merge decRelease
  • In case of merge conflict git will place markers in the corresponding file, which need to be removed manually in Working-Area.

  • Use ADD to stage your merged files
  • Use Commit to check-in the merged files. This is a special commit and it will have two PARENT tags in it.
  • For complex merge conflicts its better to configure and use merger tool e.g. WinMerge, tourtoiseMerge

Fast-forward:

  • Generally, after merge it make sense to do merge in other direction as well

Detached Head:

  • Use git checkout command with SHA1 to move head to a particular SHA1.
  • Use normal commit to create subsequent commit points and move HEAD.
  • At any point you can switch to master to move HEAD back to it and abandon new commits. As no pointer is pointing at newly created SHA1 references, they will be garbaged collected
  • If you want to preserve them just create a Branch

Git fsck command:

  • find dangling and unreachable commits
    1
    2
    $ git fsck --dangling --no-progress
    $ git fsck --unreachable --no-progress

Clone command:

  • Copy entire .git folder from remote.
  • Clone only copy the master branch to Working-Area.
  • This operation makes a entry in git config about the remote repository.
    1
    2
    3
    $ git clone https://github.com/unshakeable
    $ git clone https://github.com/unshakeable .
    $ git clone https://github.com/jquery/jquery.git

Display all branches after cloning:

1
$ git branch --all

Git Remote command:

1
2
3
4
5
6
7
8
$ git remote
$ git remote -v
$ git remote add MyRemoteRepo http://github.com/helloGuy
$ git remote add origin https://github.com/unshakeable.git
$ git remote rm origin

Git show-ref command:

1
2
$ git show-ref master
e25f61694ed34b220148a63cb0e7aefa5917c12c refs/heads/master

Git show command:

1
$ git show cbe1249b140dad24b2c35b15cc7e26a6f02d2277

Git push command:

  • Push local commits to remote repo defined in git config
    1
    2
    3
    $ git push
    Username for https://github.com':
    Password for https://github.com':
1
git push --set-upstream origin master
1
$ git push origin master

Git fetch command:

  • Fetch> Merge> Push cycle
    1
    2
    $ git fetch
    $ git fetch origin

Git pull command:

  • git pull is equivalent to FETCH followed by MERGE.
    1
    $ git pull

Fork:

  • Remote clone