Git Version Control Cookbook
Starting with the Git data model, you will learn how Git stores files and how it looks at commits. You will then learn how you can recover from mistakes; from committing on the wrong branch to recovering lost commits/files. Next, you will discover how you can force rebase on some branches and use regular Git merge on other branches. You will also learn how to extract information from the repository.
As you progress through this book, you will learn how you can automate the usual Git processes by utilizing the hook system built into Git. The book also covers advanced repository management, including different options to rewrite the history of a Git repository. Finally, you will discover how you can work offline with Git, how to track what is going on behind the scenes, and how to use the stash for different purposes.
Read an Extract from the book
A .git directory template
Sometimes, having a global configuration isn't enough. You will also need to trigger the execution of scripts (also known as Git hooks), exclude files, and so on. It is possible to achieve this with the template option set to git init. It can be given as a command-line option to git clone and git init, or as the $GIT_TEMPLATE_DIR environment variable, or as the configuration option init.templatedir. It defaults to /usr/share/git-core/templates. The template option works by copying files in the template directory to the .git ($GIT_DIR) folder after it has been created. The default directory contains sample hooks and some suggested exclude patterns. In the following example, we'll see how we can set up a new template directory, and add a commit message hook and exclude file.
First, we will create the template directory. We can use any name we want, and we'll use ~/.git_template, as shown in the following command:
Now, we need to populate the directory with some template files. This could be a hook or
To keep the sample hooks provided by the default template directory (the Git installation),
We'll use the commit-msg hook as the example hook:
The hook is very simple and will just add Hi from the template commit-msg hook to the end of the commit message. Save it as commit-msg in the ~/.git_template/hooks directory and make it executable by using the following command:
Now that the commit message hook is done, let's also add an exclude file to the example. The exclude file works like the .gitignore file, but is not tracked in the repository. We'll create an exclude file that excludes all the *.txt files, as follows:
Now, our template directory is ready for use.
How to do it...
Our template directory is ready and we can use it, as described earlier, as a command-line option, an environment variable or, as in this example, to be set as a configuration:
Now, all Git repositories we create using init or clone will have the default files of the template directory. We can test if it works by creating a new repository as follows:
Let's try to create a .txt file and see what git status tells us. It should be ignored by the exclude file from the template directory:
The exclude file worked! You can put in the file endings yourself or just leave it blank and keep to the .gitignore files.
To test if the commit-msg hook also works, let's try to create a commit. First, we need a file to commit. So, let's create that and commit it as follows:
We can now check the history with git log:
How it works...
When Git creates a new repository, either via init or clone, it will copy the files from the template directory to the new repository when creating the directory structure. The template directory can be defined either by a command-line argument, environment variable, or configuration option. If nothing is specified, the default template directory will be used (distributed with the Git installation). By setting the configuration as a --global option, the template directory defined will apply to all of the user's (new) repositories. This is a very nice way to distribute the same hooks across repositories, but it also has some drawbacks. As the files in the template directory are only copied to the Git repositories, updates to the template directory do not affect the existing repositories. This can be solved by running git init in each existing repository to reinitialize the repository, but this can be quite cumbersome. Also, the template directory can enforce hooks on some repositories where you don't want them. This is quite easily solved by simply deleting the hook files in .git/hooks of that repository.
|Course Length||10 hours 12 minutes|
|Date Of Publication||23 Jul 2014|
|Undo – remove a commit completely|
|Undo – remove a commit and retain the changes to files|
|Undo – remove a commit and retain the changes in the staging area|
|Undo – working with a dirty area|
|Redo – recreate the latest commit with new changes|
|Revert – undo the changes introduced by a commit|
|Reverting a merge|
|Viewing past Git actions with git reflog|
|Finding lost changes with git fsck|