1. The .git directory

1.1. ls .git!

  • Create a new Git repository (wherever you want)

    git init repo && cd repo && git commit -m 'Initial' --allow-empty
  • List the .git directory content and have a look.

  • Create a branch newbranch

    git branch newbranch
  • Checkout that branch, then have a look inside .git/logs/ :

    • What is this directory used for?

    • Which git command does actually use that directory? (hint: use git help -a if needed to find out, then git help <COMMAND>)

  • Have a look inside .git/refs

ls -l .git/refs/*/*
  • What is this directory used for?

Correction

All actions performed by Git or loggued into the .git/logs/ sub-directory. The git reflog command permit to display all performed actions in the git repository (create a branch, commit, etc).

The .git/refs directory store all references of all remote and local branches, tags, etc. In the case of the lab, you should have something like this :

$> ls .git/refs/*/*
	-rw-r--r--. 1 git git 41 Jun 5 08:04 .git/refs/heads/master
	-rw-r--r--. 1 git git 41 Jun 5 08:04 .git/refs/heads/newbranch

Each file contains a SHA1 representing the commit it points to.

1.2. Playing with the data model

In a Git repository, execute precisely the following commands to create a commit with a new file:

echo "Hi Eclipse Con France 2015" > pof
git add pof
git commit -m "commit done"

If your OS is Linux/Mac based, execute the following command :

echo -e "blob 27\0Hi Eclipse Con France 2015" | shasum
Caution
For Windows and some Mac users, this command may not be available. No worries: for the record, it shows that git generates a SHA1 of the committed files to store them in the repository. This command should display 64e3fc24e6ed73f1af43ae4e0411d80c10c4d0f7. If you do not have the shasum command, don’t run the command above and just go ahead with the following.

Then execute :

git ls-tree newbranch
  • What’s the role of the ls-tree command?

  • Compare the ls-tree output and the echo command output above. Conclude about how Git stores blobs.

  • Create a new directory, copy the pof file inside it with pif name, git add the whole directory and commit it.

mkdir newdirectory
cp pof newdirectory/pif
git add newdirectory
git commit -m "Added the new subdirectory"
  • Use git ls-tree newbranch again to understand how the storage works (cf. slides)

  • Use git ls-tree on the subdirectory to display its content (hint: ls-tree takes a hash as parameter, not directory name).

    • What’s the sha of the pif file in that directory ?

Correction

Git stores each files in blobs, identifying them with the sha1 corresponding.

The ls-tree command displays all files (blobs) and trees SHA1 identifier calculated by Git.

When Git stores a same file located in two differents directories, it stores only a single blob for that file in the repository since it’s the same file with the same calculated SHA1,

Note
There’s two categories of Git commands: porcelain (example: git checkout) and plumbing (example: git ls-tree). These categories actually respectively relate to high-level (user-oriented) and low-level commands.
Tip
To remember which is one: just remember, in toilets, are you more in contact with the porcelain or the plumbing?