How git works
GIT is one of the best-known SCM systems. It is as flexible as powerful and allows adaption to several workflows. But it is complex and there are many pitfalls for less experienced users. Behind the scenes GIT is a simple database with a lot of front end operations. Understanding GIT core concepts is prerequisite to understand higher level operations. This article explains how GIT works behind the scenes. In this way it gives you a basic understanding of GIT core concepts.
GIT is a key value store
GIT uses a database to store file artifacts. This database is a key value store and is the heart of GIT SCM. Files, directories and commit messages become archived to this store. But how does this work? GIT core concept is pretty simple. Adding a file to GIT means to add a key value pair to store. Keys are hex strings while values are file contents. Sounds simple and is simple!
Add single file to GIT key value store
A basic and fundamental operation is archiving a single file. GIT calculates a unique hash value for file content. At next step GIT creates a key value pair and adds it to key value store. The pair uses the hash as key and file content as value. At this point key value store holds one entry for the file. But up to here file name is missing. So file name GIT adds it in next step.
Add file names and directories to GIT key value store
Storing file names is pretty simple because GIT treads a directory as file. It is similar to list directory and pipe output into text file. In addition, GIT creates tuples by associating file name with hash value. Think of a text file with one line per file. Each line contains file name and corresponding hash value. The whole file is a snapshot of directory. It contains hash references to versioned files.
In this way GIT divides file names and their contents. An advantage is automatic detection of file movements. Moving a file to different directory has no effect to hash value. For GIT a file name does not matter because it has no effect to hash value. But moving a file or directory effects directory listing. In this way the file listings of source and target directory change. They require a new file with different hash values.
Add directories to GIT key value store
GIT recursively scans directory tree from leafs to root. It processes any directory in same way as described in last paragraph. Lets review the example step by step:
- archive file A.java with hash value a1
- archive file B.java with hash value b1
- archive ./src with file names A.java and B.java and use ash value c1
- archive ./reame.txt with hash value d1
- archive ./ with ./src and ./readme.txt and use hash value e1
Archive Commit to GIT key value store
Up to here archiving seems to be complete. But stop, an important detail is missing. What about commit operation and comments? It is not surprising, GIT creates a file for commit operation. At first the file contains commit message. At second file contains entries for author and time stamp. Not the least file contains reference to root directory.
Lets summarize the paragraphs:
- GIT stores unique contents and no duplicates
- Each key value pair entries contains a unique hash value as key. Hashing the value always results in same hash value.
- three types of values
- blobs for files
- tree for directories
- commit for commit messages