The Mijingo Blog

Latest news, updates, free tutorials, and more from Mijingo.

What is a bare Git repository?

by Ryan Irelan

The standard way of initializing a new Git repository is to run git init. The directory in which you do this will be become the Working Tree for the repository.

As part of the initialization process, Git creates a .git directory (which his hidden by default because of the . in the name) that contains the repository itself. This is brains of the repository; it's where Git tracks your changes, stores commit objects, refs, etc. You probably only rarely interact with that hidden directory.

Okay, so all of this is to lay the groundwork for understanding a bare Git repository. What the heck is it?

A bare Git repository is a repository that is created without a Working Tree. Go ahead and create one to see.

git init --bare .

Run ls on that directory and you won't see a Working Tree but just the contents of what is typically in the .git directory.

Why this setup?

A bare Git repository is typically used as a Remote Repository that is sharing a repository among several different people. You don't do work right inside the remote repository so there's no Working Tree (the files in your project that you edit), just bare repository data.

And that's it.

Git the Essentials

Learn everything you need to be proficient in Git. 40+ videos, 6 hours of learning, a better understanding of Git.

Get Git Essentials

What is a Git Remote Repository?

by Ryan Irelan

By default Git is completely local to your computer. You can optionally have remote copies of the repository (either on a central server or service—like Github—or on a co-workers computer).

To get your copy of the repository up to a remote server you use the command git-push. If you want to retrieve others’ changes to the repository you use git-pull.

A Remote Repository in Git is a special type of repository in that it doesn't have a Working Tree. This is different than your local repository, which has your project files and then a hidden .git directory.

You can host your own Git remote repository or use one the popular online services, like Github, Gitlab, or Bitbucket.

Git the Essentials

Learn everything you need to be proficient in Git. 40+ videos, 6 hours of learning, a better understanding of Git.

Get Git Essentials

What is the Working Tree in Git?

by Ryan Irelan

Th Working Tree in Git is a directory (and its files and subdirectories) on your file system that is associated with a repository.

It's full of the files you edit, where you add new files, and from which you remove unneeded files. Any changes to the Working Tree are noted by the Index (see below), and show up as modified files.

When you open the files for a project that is being managed as a Git repository then you are access the Working Tree.

Git the Essentials

Learn everything you need to be proficient in Git. 40+ videos, 6 hours of learning, a better understanding of Git.

Get Git Essentials

Using Git Hooks

by Ryan Irelan

Git hooks are similar to SVN hooks; you can execute a script at a point in the Git routine. Git hooks are both local and server-side. The local hooks pertain to local activities, like committing, merging, checking out, etc. The server-side hooks deal with receiving pushes from a local client.

The scripts that Git hooks execute are stored in the .git/hooks directory of your project. In every repository there are a collection of sample hooks that you can rename and use as inspiration for your own.

The scripts can be in any language that support executable scripts. The samples are mostly shell scripts, but you can use Perl, Ruby, Python, or something else that is familiar to you.

Here are all the hooks available in Git:

  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • applypatch-msg
  • pre-applypatch
  • post-applypath
  • pre-rebase
  • post-rewrite
  • post-checkout
  • post-merge
  • pre-push
  • pre-receive
  • update
  • post-receive

Local Git Hooks

Local Git hooks reside in the .git/hooks directory and are not treated as project files. They are not tracked in the Index and because of that they are not included when someone clones a repository.

Because of this there are some limitations to keep in mind while working with Git hooks. First and foremost: local hooks are not a reliable way to enforce policies, like a commit message structure. And, because you are unable to include the contents of the .git/hooks directory in version control, you will need to consider a way to share hooks that you’d like your team to use.

Here are the local hooks:

  • pre-commit
  • prepare-commit-msg
  • commit-msg
  • post-commit
  • applypatch-msg
  • pre-applypatch
  • post-applypath
  • pre-rebase
  • post-rewrite
  • post-checkout
  • post-merge
  • pre-push

Server-side Hooks

Server-side hooks are set up to kick off scripts when a typical remote repository actions takes place.

There are only three server-side hooks:

  • pre-receive
  • update
  • post-receive

They all operate around when the server receives a git-push from a client. These are reliable methods for enforcing some sort of repository or standard. You can run checks, kick of an integration script, testing, etc.

Implement a Git Hook

For our example we’re going to implement a local hook. We’d like to display a message after each commit, reminding us to push our commits to the remote repository.

The setup for this message will be to use the post-commit hook. This hook is triggered after each successful commit. For our implementation, we want the hook to trigger and display a message for us. 
There isn’t a sample file for post-commit already in place. That’s okay, we can create it.

Create a new file called post-commit in .git/hooks.

I’m going to use Ruby as the scripting language. Remember, Git Hooks can use any executable script. But I like Ruby so we’ll use that. This Ruby code is as simple as it comes, with just a single puts statement.

Add this code to the post-commit file:


#!/usr/local/bin
puts "======================="
puts "Please remember to push your commits!"
puts "======================="

With the code in place, we can then save the hook file and set it as executable.


$ chmod +x post-commit

Test it by making a change to our project and creating a commit. If you see the message, it worked!

If you didn’t, check your code, that the hook file is executable, and that you have it properly named.

In another article I’ll talk about triggering hooks on the server.

Git the Essentials

Learn everything you need to be proficient in Git. 40+ videos, 6 hours of learning, a better understanding of Git.

Get Git Essentials

Git Merge Therapy

by Ryan Irelan

Have a seat on the sofa for a moment, please. I want share something important with you.

Ready?

Git merge conflicts are normal and okay.

They are supposed to happen and, most likely, will happen regularly. They don’t happen because you did something wrong. They happen because Git is trying to protect you from losing your hard work.

If you’re new to Git or haven’t done extensive work with it in a team environment then you probably haven’t had the experience of a lot of merge conflicts.

In a future article I will share how you can resolve conflicts but right now, let’s talk about prevention.

We can do some things to prevent conflicts; here’s a list of a few:

  • Ignore generated files
  • Ignore cache or other runtime directories and files
  • Have a good branching strategy
  • Avoid whitespace errors

I’ll go into each one in detail in future articles.

Until then: Git conflicts are okay!

Git the Essentials

Learn everything you need to be proficient in Git. 40+ videos, 6 hours of learning, a better understanding of Git.

Get Git Essentials