<<Version Control with Git>> Notes: Git Basic Object Types

Categories: Development Notes; Tagged with: ; @ May 1st, 2014 19:11

Good book for Git: http://shop.oreilly.com/product/0636920022862.do

Powerful tools and techniques for collaborative software development

 

The Birth of Git

Prior to Git, the Linux Kernel was developed using commercial BitKeeper VCS,  however, in 2005, “The commercial company that developed BitKeeper broke down, and the tool’s free-of-charge status was revoked. This prompted the Linux development community (and in particular Linus Torvalds, the creator of Linux) to develop their own tool” — http://git-scm.com/book/en/Getting-Started-A-Short-History-of-Git

Installing Git

Ubuntu/Mint: sudo apt-get install git-core
Windows:  mysysGit
Getting Started

1. Init repo:

init a new repo,  no any object.

GDEV git # git status
fatal: Not a git repository (or any of the parent directories): .git
GDEV git # git init
Initialized empty Git repository in /guoliangDev/workspaces/git/.git/
GDEV git # find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/info

2. Add files

Created two files,   the status for these two files are: untracked.

GDEV git # echo "foo" > file1
GDEV git # echo "bar" > file2
GDEV git # find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/info
GDEV git # git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    file1
#    file2
nothing added to commit but untracked files present (use "git add" to track)
GDEV git # git ls-files –stage

git add file1: added to stage, and file1 tracked;

GDEV git # git add file1
GDEV git # git ls-files --stage
100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0    file1

GDEV git # git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#    new file:   file1
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#    file2

Objects:

GDEV git # find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/25
.git/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99
.git/objects/info

What is : 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 ?

GDEV git # git cat-file -t 257cc5642cb1a054f08cc83f2d943e56fd3ebe99
blob   // Blob is one of the git object types: Each version of a file is represented as a blob
GDEV git # git show 257cc5642cb1a054f08cc83f2d943e56fd3ebe99
foo

Add file2 and check the objects:

GDEV git # find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/25
.git/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99   //file1:foo
.git/objects/info
.git/objects/57
.git/objects/57/16ca5987cbf97d6bb54920bea6adde242d87e6  // file2: bar

Let’s commit these two files:

GDEV git # git commit -m "init commit"
[master (root-commit) a936fc9] init commit
2 files changed, 2 insertions(+)
create mode 100644 file1
create mode 100644 file2
GDEV git # find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/25
.git/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99 // we know it’s file1
.git/objects/info
.git/objects/f9
.git/objects/f9/c36476895b0f9a475dfbaeb492332c63c148ec
.git/objects/57
.git/objects/57/16ca5987cbf97d6bb54920bea6adde242d87e6 // we knew i’'t’s file2
.git/objects/a9
.git/objects/a9/36fc94abb57ef4d2dc396c509e92b166e04033

Let’s check the other two objects:

GDEV git # git show f9c36476895b0f9a475dfbaeb492332c63c148ec
tree f9c36476895b0f9a475dfbaeb492332c63c148ec  // Tree: a tree object represents one level of directory information. it records blob identifiers, and a bit of metadata for all the files in one directory. It can also recursively reference other (sub) tree objects and thus build a complete hierarchy of files and subdirectories;

GDEV git # git cat-file -p f9c36476895b0f9a475dfbaeb492332c63c148ec
100644 blob 257cc5642cb1a054f08cc83f2d943e56fd3ebe99    file1
100644 blob 5716ca5987cbf97d6bb54920bea6adde242d87e6    file2


 

GDEV git # git show a936fc94abb57ef4d2dc396c509e92b166e04033
commit a936fc94abb57ef4d2dc396c509e92b166e04033 // commit: holds metadata for each change introduced into the repository, including the author, committer, date,  log. each commit points to a tree object that captures in one complete snapshot, the state of the repository at the time the commit was performed. the initial commit, or root commit has no parent, most commits have one commit parent.
Author: guoliang <[email protected]>
Date:   Thu May 1 18:27:26 2014 +0800

    init commit

GDEV git # git cat-file -p a936fc94abb57ef4d2dc396c509e92b166e04033
tree f9c36476895b0f9a475dfbaeb492332c63c148ec  // refer to the tree
author guoliang <[email protected]> 1398940046 +0800
committer guoliang <[email protected]> 1398940046 +0800

init commit


 

Ok, so far, we ‘re very clear:

there’re two files in the repo, so there’re two blobs  object; because we committed once, so there’re one commit object and one tree object.  the tree object refer to the two blobs, and the commit refer to the tree;

Let’s add a new file: file3, with the same content as file1:

GDEV git # ls
file1  file2
GDEV git # echo "foo" > file3
GDEV git # git add file3
GDEV git # git commit -m "added file3 with 'foo'"

GDEV git # find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/79
.git/objects/79/38d59c58e759dcc1e009e7b8993bdb5c4899b1
.git/objects/25
.git/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99  // we knew it’s file1
.git/objects/info
.git/objects/f9
.git/objects/f9/c36476895b0f9a475dfbaeb492332c63c148ec // we knew it’s the tree refer to file1 and file2
.git/objects/57
.git/objects/57/16ca5987cbf97d6bb54920bea6adde242d87e6 // we knew i’'t’s file2
.git/objects/a9
.git/objects/a9/36fc94abb57ef4d2dc396c509e92b166e04033 // we knew it’s the commit referring to tree: f9/c36476895b0f9a475dfbaeb492332c63c148ec
.git/objects/af
.git/objects/af/37ca7dd1e1ceec921ed43e3272942166c8bfa0

Let’s check the two new objects:

GDEV git # git show 7938d59c58e759dcc1e009e7b8993bdb5c4899b1
tree 7938d59c58e759dcc1e009e7b8993bdb5c4899b1 // it’s the new tree refer to the three files;

GDEV git # git cat-file -p 7938d59c58e759dcc1e009e7b8993bdb5c4899b1
100644 blob 257cc5642cb1a054f08cc83f2d943e56fd3ebe99    file1
100644 blob 5716ca5987cbf97d6bb54920bea6adde242d87e6    file2
100644 blob 257cc5642cb1a054f08cc83f2d943e56fd3ebe99    file3

GDEV git # git show af37ca7dd1e1ceec921ed43e3272942166c8bfa0
commit af37ca7dd1e1ceec921ed43e3272942166c8bfa0 // it’s  the new commit
Author: guoliang [email protected]

GDEV git # git cat-file -p  af37ca7dd1e1ceec921ed43e3272942166c8bfa0
tree 7938d59c58e759dcc1e009e7b8993bdb5c4899b1
parent a936fc94abb57ef4d2dc396c509e92b166e04033 // the new commit refer to it’s parent commit;

author guoliang …

Where is file3?

When we created an object for file3, Git doesn’t care that the filename is file3. Git cares only about what’s inside the file. Git performs a few operations on this blob, calculates its SHA1 hash.  because file1 and file3 have same content, they SHA1 is same for them:  257cc5642cb1a054f08cc83f2d943e56fd3ebe99 ;

now, let add a tag:

GDEV git # git tag -m"Tag version 0.1" V0.1
GDEV git # find .git/objects/
.git/objects/
.git/objects/pack
.git/objects/79
.git/objects/79/38d59c58e759dcc1e009e7b8993bdb5c4899b1
.git/objects/25
.git/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99
.git/objects/d1
.git/objects/d1/b56741876c2dbe6d553028eb836011442b052c  // this is the new object.
.git/objects/info
.git/objects/f9
.git/objects/f9/c36476895b0f9a475dfbaeb492332c63c148ec
.git/objects/57
.git/objects/57/16ca5987cbf97d6bb54920bea6adde242d87e6
.git/objects/a9
.git/objects/a9/36fc94abb57ef4d2dc396c509e92b166e04033
.git/objects/af
.git/objects/af/37ca7dd1e1ceec921ed43e3272942166c8bfa0

GDEV git # git show d1b56
tag V0.1 // it’s a tag, a tag object assigns an commit.
Tagger: guoliang <[email protected]>
Date:   Thu May 1 19:03:55 2014 +0800

Tag version 0.1

commit af37ca7dd1e1ceec921ed43e3272942166c8bfa0 // refer to the commit
Author: guoliang ….

<->



// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.