
Project, GitLab creates a default branch (whichĬannot be deleted) for your repository.

For instance it has a message, tagger, and a tag date. git/refs/tags directory, and just like branches the file name is the name of the tag and the file contains a SHA of a commit 3.Īn annotated tag is an actual object that Git creates and that carries some information. Lightweight tags are just a reference to a commit, exactly like a branch. Git distinguishes between two types of tags: annotated tags and lightweight tags. A tag will never change unless you explicitly tell Git to do so. The only difference is that when you check out a branch, git will remember that and move the branch along when you create new commits, while checking out a tag simply means you check out the commit that tag references. $ git commit -a -m 'Awesome commit' Awesome commitġ file changed, 1 insertion (+ ), 1 deletion (- ) Switched to a new branch 'my-awesome-branch' $ echo 'Awesome Hello World!?' > README

This is what the contents of that file are: git/refs/heads, so far it only contains a master file. git directory we discussed in the first part? Branches are also stored in there. Let us take a look at what the master branch looks like. Internally, they are nothing more than a reference to a commit. This is what we can use both branches and tags for: to have an easy reference to commits. Once we have hundreds or even thousands of commits, it will become impossible to keep track of all commits. While this works, it is not very convenient even for such a small repository. If we can do branching without having branches, what do these branches add? So far, we have referenced every commit by its SHA.

In fact, to get to this point, we did not create a new branch. Notice how there are absolutely no branches in this picture. The latest commit, ec9c76d3 merges these two branches, so that now the changes made in 00e9f1c4 and 3bf75bf3 are both applied.Īnd this is essentially what branching is. This is where the branching has happened, there are now two distinct histories from this point on. There are now two commits with 5b5f50ad as parent. The trees and blobs are no longer shown to make the graph simpler.Īgain, the top commit is the latest. The merge commit also has a tree that contains the state of the repository after the merge, including the resolution of the merge conflicts. So now we have created three new commits, two simple changes and one merge commit. $ git commit -a -no-edit Merge commit '3bf75bf' Let’s see what happens when we try to add a new file to the repository we created in part one:ĬONFLICT (content ): Merge conflict in READMEĪutomatic merge failed fix conflicts and then commit the result

All this history should take up a lot of space, right?Ĭontent based addressing helps a lot with this. If we have thousands of commits, that means we have thousands of snapshots of the repository. The commit is essentially a snapshot of the repository.
#GIT CHECKOUT TAG WITHOUT BRANCH FULL#
Think about how commits contain a reference to a tree and this tree contains the full directory structure for the repository at the moment of the commit. This matters for two reasons: repository size and performance. This goes for all types of object: blobs, trees, commits, and tags. The contents (the thing you see when you use git cat-file -p) of the object are the only factor that determines the hash. So how is this hash determined? Git uses a technique that is called content based addressing. Let’s find out how these hashes are determined, and why it matters. We also learned that objects are referenced by a hash, but we have not learned a lot about these hashes. A commit references a tree and a tree references other trees and blobs. We learned that a commit it is a type of object, as are blobs, trees and tags. In part one of this series, we looked at the object database.
