An in-depth look on how we use Git. An analysis on it's architecture and our daily use with the goal to understand the what/why/how so we can better adapt to new situations and stop depending on memorized formulas.
nodes nodes and and directed edges directed edges that connect them. that connect them. n1 n2 n2 n2 n2 There is no way to start at some node N and cycle back again to N.
a tree is that . . A tree doesn't allow nodes to have multiple A tree doesn't allow nodes to have multiple parents. parents. odes in a DAG can have multiple parents odes in a DAG can have multiple parents
most common case of this in git is when you do a merge. when you do a merge. A merge commit will have all of the A merge commit will have all of the commits that were merged as parents. commits that were merged as parents.
of each file of each file Version 1 Version 2 Version 3 Version 4 Version 5 File A File B File C ∆1 Time A1 C1 A1 A2 A2 B B B1 B2 C2 C3 C2 Efficient: Efficient: If a file didn't change, a If a file didn't change, a link to the previous version link to the previous version is is stored. stored.
very simple key-value data key-value data store store. . You can give it anything, it will store it and You can give it anything, it will store it and give you back a key. give you back a key.
creates is called a blob blob. It is the . It is the zlib-deflated representation of any given zlib-deflated representation of any given content. content. Git uses blobs to save the different versions Git uses blobs to save the different versions of your files. of your files.
manually version a file. We will manually version a file. $ echo 'testing blobs' > some-file.txt $ git hash-object -w some-file.txt d675fa44e50606caa705c3f48de02cf129c7f9a2 $ find .git/objects .git/objects .git/objects/d6 .git/objects/d6/75fa44e50606caa705c3f48de02cf129c7f9a2 As we can see, git now has a blob with our file's content. This will be v1 of some-file.txt.
the file echo 'a new line' >> some-file.txt $ git hash-object -w some-file.txt 1aeaedbf4ee8dccec5bc2b1f1168efef19378ffd $ find .git/objects .git/objects .git/objects/1a .git/objects/1a/eaedbf4ee8dccec5bc2b1f1168efef19378ffd .git/objects/d6 .git/objects/d6/75fa44e50606caa705c3f48de02cf129c7f9a2 Now we have both versions of our file.
$ git cat-file d675fa4... > some-file.txt Now the second one $ git cat-file 1aeaedb... > some-file.txt Of course this is ridiculously impractical, but is (a really simplified version of) what Git does under the hood.
A tree tree references references other trees other trees and and blobs blobs. It . It also stores the also stores the filename filename that correspond to that correspond to each tree and blob it contains. each tree and blob it contains.
like a filesystem. filesystem. That's because That's because it's Git's representation of the files in the it's Git's representation of the files in the repository. repository. A A tree tree is a is a directory directory and a and a blob blob is a is a file file. .
blobs blobs and and trees trees are identified by a are identified by a hash hash. . This is not just a simple identifier This is not just a simple identifier
of some of some data data The purpose is to detect changes that may be introduced to a file. Willingly, by editing, or unwillingly, caused during data transmission or storage (file corruption).
of your local repository in some other machine. When you clone a repository you're downloading a copy of it. It will remember where's the original, to know where it should fetch from and push to. This will be called origin by default.
do we talk about when we talk about branches branches? ? A branch is simply a pointer to a commit. 96da0 f0dde d9ffe feature master Git will automatically point the current branch to new commits as you go.
does Git know which is the current current branch branch? ? There's a special pointer called HEAD. And it's just a pointer to the current branch. 96da0 f0dde d9ffe feature master HEAD
out '94a87f75a'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard commits you make in this state without impacting any branches performing another checkout. If you want to create a new branch to retain commits you you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at 94a87f7... Added readme Confusing, right? Confusing, right?
looks like than it looks like The detached HEAD state happens when you check out a commit or a tag that is not the latest in the branch, i.e. your HEAD no longer points to a branch. Git will let you make new commits, creating a tangent in history, which you can keep by creating a new branch, or discard, by checking out another branch.
the state of the branches in the remote(s). 96da0 f0dde d9ffe origin/master master HEAD They can't be moved, that is done automatically by Git when you push or fetch.
merge origin/master into master 1. merge hotfix into master 2. Rebase workflow Rebase workflow rebase master from origin/master 1. rebase hotfix from master 2. rebase master from hotfix 3.
ref>] $ git push <remote> <local ref>[:<remote ref>] ref is the path to the object as it is found in the .git/ directory, for example: refs/heads/master or refs/tags/some-tag.