Git Version Control Cookbook - Kenneth Geisshirt - E-Book

Git Version Control Cookbook E-Book

Kenneth Geisshirt

0,0
40,81 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

A series of practical recipes to simplify the Git learning experience and increase your productivity when using Git version control




Key Features



  • Explore practical recipes to use Git's most advanced features

  • Learn how Git references its objects and how history is recorded

  • Use reflog and git fsck to recover lost information




Book Description



Git is one of the most popular tools for versioning. Git Version Control Cookbook builds on the success of the previous edition and provides you with an up-to-date guide to solving problems related to versioning.






You'll start by learning about the Git data model and how it stores files and looks at commits. By using simple commands, you'll learn how to navigate through the database. Once you have accustomed yourself to the basics, you'll explore techniques to configure Git with comprehensive examples and configuration targets. You'll gain insights into improving your understanding of branches and recovery from mistakes — right from committing to a wrong branch to recovering lost commits or files. You'll then move on to discovering the features that Git rebase has to offer and use regular Git merge on other branches. You'll explore Git notes and learn how to utilize the update, list, and search commands. In addition to this, you'll learn how to extract metadata from repositories and automate your daily tasks using Git hooks. You'll then study in detail repository maintenance, patching, and offline sharing. By the end of the book, you'll have grasped various tips and tricks for everyday usage, while increasing your knowledge of Git providers, integrations, and clients.




What you will learn



  • Understand the Git data model and use commands to navigate the database

  • Find out how you can recover lost commits or files

  • Force a rebase on some branches and use regular Git to merge on the rest

  • Master the techniques required to extract metadata from repositories

  • Explore Git notes and learn about the various features that it offers

  • See how to decode different subcommands



Who this book is for



The Git Version Control Cookbook is for you if you are a developer or Build Release manager looking for a full-fledged practical guide that will take your Git knowledge to the next level. Basic knowledge of GNU tools and shell or bash scripting is needed.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB

Seitenzahl: 371

Veröffentlichungsjahr: 2018

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Git Version Control Cookbook
Second Edition

 

 

 

 

 

Leverage version control to transform your development workflow and boost productivity

 

 

 

 

 

 

 

 

Kenneth Geisshirt
Emanuele Zattin Aske Olsson Rasmus Voss

 

 

 

 

 

 

 

 

 

 

 

BIRMINGHAM - MUMBAI

Git Version Control Cookbook Second Edition

Copyright © 2018 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Commissioning Editor: Aaron LazarAcquisition Editor: Shriram ShekharContent Development Editor: Pooja ParvatkarTechnical Editor: Subhalaxmi NadarCopy Editor: Safis EditingProject Coordinator: Ulhas KambaliProofreader: Safis EditingIndexer: Rekha NairGraphics: Tania DuttaProduction Coordinator: Deepika Naik

First published: July 2014 Second edition: July 2018

Production reference: 1240718

Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.

ISBN 978-1-78913-754-5

www.packtpub.com

  
mapt.io

Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.

Why subscribe?

Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals

Improve your learning with Skill Plans built especially for you

Get a free eBook or video every month

Mapt is fully searchable

Copy and paste, print, and bookmark content

PacktPub.com

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.

Contributors

About the authors

Kenneth Geisshirt is a chemist, by education, and a strong free-software advocate. He spent his Christmas holidays in 1992 installing SLS Linux, and GNU/Linux has been his favorite operating system ever since. Currently, he does consultancy work in fields such as scientific computing and Linux clusters. He lives in Copenhagen, Denmark, with his partner and their two children.

As a programmer, I have used many versioning systems. I began with CVS, followed by Subversion and Telelogic Synergy. During the last 7 years, Git has become an integral part of my life. Over the years, many people have been kind with their support, especially my wife and children, who always let me be the geek I am.

 

Emanuele Zattin is the Continuous Integration Specialist at Realm Inc. with experience in software development and design. He is respected for his work in designing and developing a CM Synergy to Git history conversion tool and rolling out Git-Gerrit-Jenkins in several Nokia divisions.

I would like to thank my coauthor, Kenneth, for convincing me to embark on this adventure; my wife, Cecilie; and our children, Sebastian and Mia, for their patience and support. I would also like to thank Aske and Rasmus, the authors of the first edition of this book, whose work has proven to be an incredibly strong base for the current edition.

Aske Olsson has more than 14 years of experience in the software industry. As an electrical engineer, he has been using every tool available for development, from a soldering iron over Assembly, C, Java Groovy, Python and various DSLs for programming to different SCMs and build-, CI- and issue-tracking systems. He has worked for Nokia for 6 years and, currently, works at Keylane. Aske has experience with Git; he has been teaching Git in regular training sessions, from basic Git to advanced usage.

 

 

 

Rasmus Voss has been working with continuous integration, continuous delivery, automatic testing, and DevOps, in various industries. He has always strived to ensure that where developers, testers, project leaders, and managers can work with the system instead of against the system. Typically, the processes and solutions he develops are clear, precise, and well documented, with relevant feedback to all parts of the software development process.

About the reviewer

Chen Mulong has been working on mobile development for over 10 years. He has coded for all different kinds of mobile devices, from the ancient feature phone platform, which is made of plain C, to the modern smart device platform, Android. Open source is his first choice for solving daily problems.

He has experienced the chaos of being part of a team of 100+ developers and the peace brought about by excellent SCM tools. He loves to tell others how good Git is at making every developer's life easier. He now works as a freelancer in Beijing, China.

Thanks to the writers for giving me the chance to review this book and learn so many things I hadn't tried before with Git. The book not only helped me to refresh my knowledge of Git basic, but also inspired me to get more work done by combining various simple Git commands into an automatic script. I enjoyed reading the tricks and examples contained in the book even as entertainment.

 

 

 

 

 

Packt is searching for authors like you

If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.

Table of Contents

Title Page

Copyright and Credits

Git Version Control Cookbook Second Edition

Packt Upsell

Why subscribe?

PacktPub.com

Contributors

About the authors

About the reviewer

Packt is searching for authors like you

Preface

Who this book is for

What this book covers

To get the most out of this book

Download the color images

Conventions used

Sections

Getting ready

How to do it…

How it works…

There's more…

See also

Get in touch

Reviews

Navigating Git

Introduction

Git's objects

Getting ready

How to do it...

The commit object

The tree object

The blob object

The branch object

The tag object

How it works...

There's more...

The three stages

Getting ready

How to do it...

How it works...

See also

Viewing the DAG

Getting ready

How to do it...

How it works...

Extracting fixed issues

Getting ready

How to do it...

How it works...

There's more...

Getting a list of the changed files

Getting ready

How to do it...

How it works...

There's more...

See also

Viewing the history with gitk

Getting ready

How to do it...

How it works...

There's more...

Finding commits in the history

Getting ready

How to do it...

How it works...

There's more...

Searching through the history code

Getting ready

How to do it...

How it works...

There's more...

Configuration

Introduction

Configuration targets

Getting ready

How to do it...

How it works...

There's more...

Querying the existing configuration

Getting ready

How to do it...

How it works...

There's more...

Templates

Getting ready

How to do it...

How it works...

A .git directory template

Getting ready

How to do it...

How it works...

See also

A few configuration examples

Getting ready

How to do it...

Rebase and merge setup

Expiry of objects

Autocorrect

How it works...

There's more...

Git aliases

Getting ready

How to do it...

How it works...

There's more...

The refspec exemplified

Getting ready

How to do it...

How it works...

Branching, Merging, and Options

Introduction

Managing your local branches

Getting ready

How to do it...

How it works...

There's more...

Branches with remotes

Getting ready

How to do it...

There's more...

Forcing a merge commit

Getting ready

How to do it...

There's more...

Using git reuse recorded resolution (rerere) to merge Git conflicts

How to do it...

There's more...

Compute the difference between branches

Getting ready

How to do it...

Orphan branches

Getting ready

How to do it...

There's more...

Rebasing Regularly and Interactively, and Other Use Cases

Introduction

Rebasing commits to another branch

Getting ready

How to do it...

How it works...

Continuing a rebase with merge conflicts

How to do it...

How it works...

There's more...

Rebasing selected commits interactively

Getting ready

How to do it...

There's more...

Squashing commits using an interactive rebase

Getting ready

How to do it...

There's more...

Changing the author of commits using a rebase

Getting ready

How to do it...

How it works...

Autosquashing commits

Getting ready

How to do it...

There's more...

Storing Additional Information in Your Repository

Introduction

Adding your first Git note

Getting ready

How to do it...

There's more...

Separating notes by category

Getting ready

How to do it...

How it works...

Retrieving notes from the remote repository

Getting ready

How to do it...

How it works...

Pushing Git notes to a remote repository

How to do it...

There's more...

Tagging commits in the repository

Getting ready

How to do it...

There's more...

Extracting Data from the Repository

Introduction

Extracting the top contributor

Getting ready

How to do it...

There's more...

Finding bottlenecks in the source tree

Getting ready

How to do it...

There's more...

Grepping the commit messages

Getting ready

How to do it...

The contents of the releases

How to do it...

How it works...

Finding what has been achieved in the repository in the last period

How to do it...

How it works...

There's more...

Enhancing Your Daily Work with Git Hooks, Aliases, and Scripts

Introduction

Using a branch description in a commit message

Getting ready

How to do it...

Creating a dynamic commit message template

Getting ready

How to do it...

There's more...

Using external information in a commit message

Getting ready

How to do it...

Preventing the push of specific commits

Getting ready

How to do it...

There's more...

Configuring and using Git aliases

How to do it...

How it works...

Configuring and using Git scripts

How to do it...

Setting up and using a commit template

Getting ready

How to do it...

Recovering from Mistakes

Introduction

Undo – Remove a commit completely

Getting ready

How to do it...

How it works...

Undo – Remove a commit and retain changes to files

Getting ready

How to do it...

How it works...

Undo – Remove a commit and retain changes in the staging area

Getting ready

How to do it...

How it works...

Undo – Working with a dirty area

Getting ready

How to do it...

How it works...

Redo – Recreate the latest commit with new changes

Getting ready

How to do it...

How it works...

There's more...

Revert – Undo the changes introduced by a commit

Getting ready

How to do it...

How it works...

There's more...

Reverting a merge

Getting ready

How to do it...

How it works...

There's more...

See also

Viewing past Git actions with git reflog

Getting ready

How to do it...

How it works...

Finding lost changes with git fsck

Getting ready

How to do it...

How it works...

Repository Maintenance

Introduction

Pruning remote branches

Getting ready

How to do it...

How it works...

There's more...

Running garbage collection manually

Getting ready

How to do it...

How it works...

Turning off automatic garbage collection

Getting ready

How to do it...

Splitting a repository

Getting ready

How to do it...

How it works...

There's more...

Rewriting history – changing a single file

Getting ready

How to do it...

How it works...

Creating a backup of your repositories as mirror repositories

Getting ready

How to do it...

How it works...

There's more...

A quick "how-to" submodule

Getting ready

How to do it...

There's more...

Subtree merging

Getting ready

How to do it...

How it works...

See also

Submodule versus subtree merging

Patching and Offline Sharing

Introduction

Creating patches

Getting ready

How to do it...

How it works...

There's more...

Creating patches from branches

Getting ready

How to do it...

How it works...

There's more...

Applying patches

Getting ready

How to do it...

How it works...

There's more...

Sending patches

Getting ready

How to do it...

How it works...

There's more...

Creating Git bundles

Getting ready

How to do it...

How it works...

Using a Git bundle

Getting ready

How to do it...

There's more...

Creating archives from a tree

Getting ready

How to do it...

There's more...

Tips and Tricks

Introduction

Using git stash

Getting ready

How to do it...

How it works...

There's more...

Saving and applying stashes

Getting ready

How to do it...

There's more...

Debugging with git bisect

Getting ready

How to do it...

There's more...

Using the blame command

Getting ready

How to do it...

There's more...

Coloring the UI in the prompt

Getting ready

How to do it...

There's more...

Autocompletion

Getting ready

Linux

Mac

Windows

How to do it...

How it works...

There's more...

Bash prompt with status information

Getting ready

How to do it...

How it works...

There's more...

See also

More aliases

Getting ready

How to do it...

Interactive add

Getting ready

How to do it...

There's more...

Interactive add with Git gui

Getting ready

How to do it...

Ignoring files

Getting ready

How to do it...

There's more...

See also

Showing and cleaning ignored files

Getting ready

How to do it...

There's more...

Git Providers, Integrations, and Clients

Introduction

Setting up an organization at GitHub

Getting ready

How to do it...

How it works...

There's more...

See also

Creating a repository at GitHub

Getting ready

How to do it...

How it works...

There's more...

Adding templates for issues and pull requests

Getting ready

How to do it...

How it works...

Creating a GitHub API key

Getting ready

How to do it...

How it works...

See also

Using GitHub to authenticate at Jenkins

Getting ready

How to do it...

How it works...

There's more...

See also

Triggering Jenkins builds

Getting ready

How to do it...

How it works...

There's more...

See also

Using Jenkinsfiles

Getting ready

How to do it...

How it works...

There's more...

See also

Other Books You May Enjoy

Leave a review - let other readers know what you think

Preface

Git is increasingly becoming the de facto standard for Source Control Management (SCM) in modern software development. 

Originally developed by Linus Torvalds as an SCM system for the Linux kernel to replace the proprietary SCM BitKeeper, Git has since conquered most of the open source world and is also used by lots of organizations for their private/proprietary projects.

This book is designed to give you practical recipes for everyday Git usage. The recipes can be used directly or as inspiration. The book will cover the Git data model through practical recipes and in-depth explanations so you get a deeper understanding of the internal workings of Git. This book will show you the following topics:

Working with the history. With Git, all the history is stored locally. You cansearch through the history, view the history, find the last commit on a certain branch, and more.Using branches effectively with options and strategies to push, pull, and merge them.Storing and extracting additional metadata in the Git repository.Disaster recovery: local and global.

Git Version Control Cookbookgives you precise, step-by-step instructions for various common and uncommon Git operations. The book will make your daily work with Git easier by providingrecipes for common issues, useful tips and tricks, and in-depth clarifications of why andhow they work.

Who this book is for

This book targets developers, professional build/release managers, and DevOps practitioners who want a practical guide for the next level of Git. Starting with the Git data model and advancing through branching to metadata and hooks, all through an easy-to-read recipe structure, the transition from simple, everyday use cases to advanced repository handling is smooth. The book can be easily read and understood by readers from the target audience. You need basic knowledge of common GNU/Linux tools and Shell/Bash scripting to get the most from this book.

What this book covers

Chapter 1,Navigating Git, shows how Git stores files and commits. Examples will visually showyou the data model and how to navigate the history and database with simple commands.

Chapter 2,Configuration, shows how a lot can be configured in Git, how configuration targets are set, the different configuration levels, and some useful targets.

Chapter 3,Branching, Merging, and Options, will give you a deeper understanding of branching and the options for easy push/pull targets. It also shows you the different merge strategies and some tips on how to record merge resolutions.

Chapter 4,Rebasing Regularly and Interactively, and Other Use Cases, shows you how rebasing can be used instead of merging, along with a lot of other use cases of rebasing, such as cleaning up the history before publishing, and testing single commits.

Chapter 5,Storing Additional Information in Your Repository, takes you on a tour of Git notes. It will show you how to tie additional information to a commit, and how to use and see this information again.

Chapter 6,Extracting Data from the Repository, shows you how to extract statistics and other metadata from the repository.

Chapter 7,Enhancing Your Daily Work with Git Hooks, Aliases, and Scripts, contains a collection of recipes that will help you automate much of the tedious daily work.

Chapter 8,Recovering from Mistakes, walks you through several recovery scenarios, from local undo, to where-is-my-old-commit, to global recovery scenarios.

Chapter 9,Repository Maintenance, is a collection of recipes that relate to the maintenance and management of repositories, from forcing garbage collection, over-splitting, and joining repositories, to completely rewriting history.

Chapter 10,Patching and Offline Sharing, shows you how to work offline with Git and sharethe work by means other than pushing and pulling.

Chapter 11,Tips and Tricks, is a collection of recipes that cover various topics, from simple tips to displaying the current branch in your prompt to advanced Git tools, such as bisect and stash.

Chapter 12, Git Providers, Integrations, and Clients, introduces the largest Git-hosting site, GitHub. Moreover, the chapter will discuss how to integrate Jenkins for automated builds and tests.

To get the most out of this book

To follow and recreate the recipes from this book, you will need a computer preferably running a *nix operating system. You will need Git installed, preferably Git Version 2.x or later.

If you are a Windows user, we recommend the Git Extensions package, which ships both a graphical and textual (Bash) Git interface. The latter is required for the recipes in this book.

 

Download the color images

We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/GitVersionControlCookbookSecondEdition_ColorImages.pdf.

Conventions used

There are a number of text conventions used throughout this book.

CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "The most recent commit is the 3061dc6 Adds Java version of 'hello world'commit."

Any command-line input or output is written as follows:

$ git checkout master && git reset --hard b14a939

Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "Select System info from the Administration panel."

Warnings or important notes appear like this.
Tips and tricks appear like this.

Sections

In this book, you will find several headings that appear frequently (Getting ready, How to do it..., How it works..., There's more..., and See also).

To give clear instructions on how to complete a recipe, use these sections as follows:

Getting ready

This section tells you what to expect in the recipe and describes how to set up any software or anypreliminary settings required for the recipe.

How to do it…

This section contains the steps required to follow the recipe.

How it works…

This section usually consists of a detailed explanation of what happened in the previous section.

There's more…

This section consists of additional information about the recipe in order to make you more knowledgeable about the recipe.

See also

This section provides helpful links to other useful information for the recipe.

Get in touch

Feedback from our readers is always welcome.

General feedback: Email [email protected] and mention the book title in the subject of your message. If you have questions about any aspect of this book, please email us at [email protected].

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.

Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Reviews

Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!

For more information about Packt, please visit packtpub.com.

Navigating Git

In this chapter, we will cover the following topics:

Git's objects

The three stages

Viewing the DAG

Extracting fixed issues

Getting a list of the changed files

Viewing the history with gitk

Finding commits in the history

Searching through the history code

Introduction

In this chapter, we will take a look at Git's data model. We will learn how Git references its objects and how the history is recorded. We will learn how to navigate the history, from finding certain text snippets in commit messages, to the introducing a particular string in the code.

The data model of Git is different from other common version control systems (VCSs) in the way Git handles its data. Traditionally, a VCS will store its data as an initial file, followed by a list of patches for each new version of the file:

Git is different: Instead of the regular file and patches list, Git records a snapshot of all the files tracked by Git and their paths relative to the repository root—that is, the files tracked by Git in the filesystem tree. Each commit in Git records the full tree state. If a file does not change between commits, Git will not store the file again. Instead, Git stores a link to the file. This is shown in the diagram below where you see how the files will be after every commit/version.

This is what makes Git different from most other VCSs, and, in the following chapters, we will explore some of the benefits of this powerful model.

The way Git references files and directories is directly built into the data model. In short, the Git data model can be summarized as shown in the following diagram:

The commit object points to the root tree. The root tree points to subtrees and files.

Branches and tags point to a commit object and the HEAD object points to the branch that is currently checked out. So, for every commit, the full tree state and snapshot are identified by the root tree.

Git's objects

Now, since you know that Git stores every commit as a full tree state or snapshot, let's take a closer look at the object's Git store in the repository.

Git's object storage is a key-value storage, the key being the ID of the object and the value being the object itself. The key is an SHA-1 hash of the object, with some additional information, such as size. There are four types of objects in Git, as well as branches (which are not objects, but which are important) and the special HEAD pointer that refers to the branch/commit currently being checked out. The four object types are as follows:

Files, or blobs as they are also called in the Git context

Directories, or trees in the Git context

Commits

Tags

We will start by looking at the most recent commit object in the repository we just cloned, keeping in mind that the special HEAD pointer points to the branch that is currently being checked out.

Getting ready

To view the objects in the Git database, we first need a repository to be examined. For this recipe, we will clone an example repository in the following location:

$ git clone https://github.com/PacktPublishing/Git-Version-Control-Cookbook-Second-Edition.git

$ cd

Git-Version-Control-Cookbook-Second-Edition

Now you are ready to look at the objects in the database. We will start by looking first at the commit object, followed by the trees, the files, and finally, the branches and tags.

How to do it...

Let's take a closer look at the object's Git stores in the repository.

The commit object

The Git's specialHEAD object always points to the current snapshot/commit, so we can use that as the target for our request of the commit that we want to have a look at:

$ git cat-file -p HEAD

tree 34fa038544bcd9aed660c08320214bafff94150b

parent 5c662c018efced42ca5e9cce709787c40a849f34

author John Doe <[email protected]> 1386933960 +0100

committer John Doe <[email protected]> 1386941455 +0100

This is the subject line of the commit message. It should be followed by a blank line and then the body, which is this text. Here, you can use multiple paragraphs to explain your commit. It's like an email with a subject and a body to try to attract people's attention to the subject.

The cat-file command with the -p option prints the object given on the command line; in this case, HEAD, points to master, which, in turn, points to the most recent commit on the branch.

We can now see the commit object, consisting of the root tree (tree), the parent commit object's ID (parent), the author and timestamp information (author), the committer and timestamp information (committer), and the commit message.

The tree object

To see the tree object, we can run the same command on the tree, but with the tree ID (34fa038544bcd9aed660c08320214bafff94150b) as the target:

$ git cat-file -p 34fa038544bcd9aed660c08320214bafff94150b

100644 blob f21dc2804e888fee6014d7e5b1ceee533b222c15 README.md

040000 tree abc267d04fb803760b75be7e665d3d69eeed32f8 a_sub_directory

100644 blob b50f80ac4d0a36780f9c0636f43472962154a11a another-file.txt

100644 blob 92f046f17079aa82c924a9acf28d623fcb6ca727 cat-me.txt

100644 blob bb2fe940924c65b4a1cefcbdbe88c74d39eb23cd hello_world.c

We can also specify that we want the tree object from the commit pointed to by HEAD by specifying git cat-file -p HEAD^{tree}, which would give the same results as the previous command. The special notation HEAD^{tree} means that from the reference given, HEAD recursively dereferences the object at the reference until a tree object is found.

The first tree object is the root tree object found from the commit pointed to by the master branch, which is pointed to by HEAD. A generic form of the notation is <rev>^<type>, and will return the first object of <type>, searching recursively from <rev>.

From the tree object, we can see what it contains: the file type/permissions, type (tree/blob), ID, and pathname:

Type/

Permissions

Type

ID/SHA-1

Pathname

100644

blob

f21dc2804e888fee6014d7e5b1ceee533b222c15

README.md

040000

tree

abc267d04fb803760b75be7e665d3d69eeed32f8

a_sub_directory

100644

blob

b50f80ac4d0a36780f9c0636f43472962154a11a

another-file.txt

100644

blob

92f046f17079aa82c924a9acf28d623fcb6ca727

cat-me.txt

100644

blob

bb2fe940924c65b4a1cefcbdbe88c74d39eb23cd

hello-world.c

The blob object

Now, we can investigate the blob (file) object. We can do this using the same command, giving the blob ID as the target for the cat-me.txt file:

$ git cat-file -p 92f046f17079aa82c924a9acf28d623fcb6ca727

The content of the file is cat-me.txt.

Not really that exciting, huh?

This is simply the content of the file, which we can also get by running a normal cat cat-me.txt command. So, the objects are tied together, blobs to trees, trees to other trees, and the root tree to the commit object, all connected by the SHA-1 identifier of the object.

The branch object

The branch object is not really like any other Git objects; you can't print it using the cat-file command as we can with the others (if you specify the -p pretty print, you'll just get the commit object it points to), as shown in the following code:

$ git cat-file master

usage: git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>

or: git cat-file (--batch|--batch-check) < <list_of_objects>

<type> can be one of: blob, tree, commit, tag.

...

$ git cat-file -p master

tree 34fa038544bcd9aed660c08320214bafff94150b

parent a90d1906337a6d75f1dc32da647931f932500d83

...

Instead, we can take a look at the branch inside the .git folder where the whole Git repository is stored. If we open the text file .git/refs/heads/master, we can actually see the commit ID that the master branch points to. We can do this using cat, as follows:

$ cat .git/refs/heads/master

13dcada077e446d3a05ea9cdbc8ecc261a94e42d

We can verify that this is the latest commit by running git log -1:

$ git log -1

commit 34acc370b4d6ae53f051255680feaefaf7f7850d (HEAD -> master, origin/master, origin/HEAD)

Author: John Doe <[email protected]>

Date: Fri Dec 13 12:26:00 2013 +0100

This is the subject line of the commit message

...

We can also see that HEAD is pointing to the active branch by using cat with the .git/HEAD file:

$ cat .git/HEAD

ref: refs/heads/master

The branch object is simply a pointer to a commit, identified by its SHA-1 hash.

The tag object

The last object to be analyzed is the tag object. There are three different kinds of tag: a lightweight (just a label) tag, an annotated tag, and a signed tag. In the example repository, there are two annotated tags:

$ git tag

v0.1

v1.0

Let's take a closer look at the v1.0 tag:

$ git cat-file -p v1.0

object f55f7383b57ad7c11cf56a7c55a8d738af4741ce

type commit

tag v1.0

tagger John Doe <[email protected]> 1526017989 +0200

We got the hello world C program merged, let's call that a release 1.0

As you can see, the tag consists of an object—which, in this case, is the latest commit on the master branch—the object's type (commits, blobs, and trees can be tagged), the tag name, the tagger and timestamp, and finally the tag message.

How it works...

The Git command git cat-file -p will print the object given as an input. Normally, it is not used in everyday Git commands, but it is quite useful to investigate how it ties the objects together.

We can also verify the output of git cat-file by rehashing it with the Git command git hash-object; for example, if we want to verify the commit object at HEAD (34acc370b4d6ae53f051255680feaefaf7f7850d), we can run the following command:

$ git cat-file -p HEAD | git hash-object -t commit --stdin

13dcada077e446d3a05ea9cdbc8ecc261a94e42d

If you see the same commit hash as HEAD pointing towards you, you can verify whether it is correct using git log -1.

There's more...

There are many ways to see the objects in the Git database. The git ls-tree command can easily show the content of trees and subtrees, and git show can show the Git objects, but in a different way.

The three stages

We have seen the different objects in Git, but how do we create them? In this example, we'll see how to create a blob, tree, and commit object in the repository. We'll also learn about the three stages of creating a commit.

Getting ready

We'll use the same Git-Version-Control-Cookbook-Second-Edition repository that we saw in the last recipe:

$ git clone https://github.com/PacktPublishing/Git-Version-Control-Cookbook-Second-Edition.git

$ cd

Git-Version-Control-Cookbook-Second-Edition

How to do it...

First, we'll make a small change to the file and check

git status

:

$ echo "Another line" >> another-file.txt

$ git status

On branch master

Your branch is up-to-date with 'origin/master'.

Changes not staged for commit:

(use "git add <file>..." to update what will be committed)

(use "git checkout -- <file>..." to discard changes in working directory)

modified: another-file.txt

no changes added to commit (use "git add" and/or "git commit -a")

This, of course, just tells us that we have modified another-file.txt and we need to use git add to stage it.

Let's add the

another-file.txt

file and run

git status

again:

$ git add another-file.txt

$ git status

On branch master

Your branch is up-to-date with 'origin/master'.

Changes to be committed:

(use "git reset HEAD <file>..." to unstage)

modified: another-file.txt

The file is now ready to be committed, just as you have probably seen before. But what happens during the add command? The add command, generally speaking, moves files from the working directory to the staging area; however, this is not all that actually happens, though you don't see it. When a file is moved to the staging area, the SHA-1 hash of the file is created and the blob object is written to Git's database. This happens every time a file is added, but if nothing changes for a file, it means that it is already stored in the database. At first, this might seem that the database will grow quickly, but this is not the case. Garbage collection kicks in at times, compressing, and cleaning up the database and keeping only the objects that are required.

We can edit the file again and run

git status

:

$ echo 'Whoops almost forgot this' >> another-file.txt

$ git status

On branch master

Your branch is up-to-date with 'origin/master'.

Changes to be committed:

(use "git reset HEAD <file>..." to unstage)

modified: another-file.txt

Changes not staged for commit:

(use "git add <file>..." to update what will be committed)

(use "git checkout -- <file>..." to discard changes in working directory)

modified: another-file.txt

Now, the file shows up in both the Changes to be committed and Changes not staged for commit sections. This looks a bit weird at first, but there is, of course, a reason for this. When we added the file the first time, the content of it was hashed and stored in Git's database. The changes arising from the second change to the file have not yet been hashed and written to the database; it only exists in the working directory. Therefore, the file shows up in both the Changes to be committed and Changes not staged for commit sections; the first change is ready to be committed, the second is not. Let's also add the second change:

$ git add another-file.txt

$ git status

On branch master

Your branch is up-to-date with 'origin/master'.

Changes to be committed:

(use "git reset HEAD <file>..." to unstage)

modified: another-file.txt

Now, all the changes we have made to the file are ready to be committed, and we can record a commit:

$ git commit -m 'Another change to another file'

[master 99fac83] Another change to another file

1 file changed, 2 insertions(+)

How it works...

As we learned previously, the add command creates the blob, tree, and commit objects; however, they are also created when we run the commit command. We can view these objects using the cat-file command, as we saw in the previous recipe:

$ git cat-file -p HEAD

tree 162201200b5223d48ea8267940c8090b23cbfb60

parent 13dcada077e446d3a05ea9cdbc8ecc261a94e42d

author John Doe <[email protected]> 1524163792 +0200

committer John Doe <[email protected]> 1524163792 +0200

Making changes to another file.

The root-tree object from the commit is as follows:

$ git cat-file -p HEAD^{tree}

100644 blob f21dc2804e888fee6014d7e5b1ceee533b222c15 README.md

040000 tree abc267d04fb803760b75be7e665d3d69eeed32f8 a_sub_directory

100644 blob 35d31106c5d6fdb38c6b1a6fb43a90b183011a4b another-file.txt

100644 blob 92f046f17079aa82c924a9acf28d623fcb6ca727 cat-me.txt

100644 blob bb2fe940924c65b4a1cefcbdbe88c74d39eb23cd hello_world.c

From the previous recipe, we know that the SHA-1 of the root tree was 34fa038544bcd9aed660c08320214bafff94150b and the SHA-1 of the another-file.txt file was b50f80ac4d0a36780f9c0636f43472962154a11a, and, as expected, they changed in our latest commit when we updated the another-file.txt file. We added the same file, another-file.txt, twice before we created the commit, recording the changes to the history of the repository. We also learned that the add command creates a blob object when called. So, in the Git database, there must have been an object similar to the content of another-file.txt the first time we added the file to the staging area. We can use the git fsck command to check for dangling objects—that is, objects that are not referred to by other objects or references:

$ git fsck --dangling

Checking object directories: 100% (256/256), done.

dangling blob ad46f2da274ed6c79a16577571a604d3281cd6d9

Let's check the content of the blob using the following command:

$ git cat-file -p ad46f2da274ed6c79a16577571a604d3281cd6d9

This is just another file

Another line

The blob was, as expected, similar to the content of another-file.txt when we added it to the staging area the first time.

The following diagram describes the tree stages and the commands used to move between the stages:

See also

For more examples and information on the cat-file and fsck commands, please consult the Git documentation at https://git-scm.com/docs/git-cat-file and https://git-scm.com/docs/git-fsck.

Viewing the DAG

The history in Git is formed from the commit objects; as development advances, branches are created and merged, and the history will create a directed acyclic graph, the DAG, because of the way that Git ties a commit to its parent commit. The DAG makes it easy to see the development of a project based on the commits.

Please note that the arrows in the following diagram are dependency arrows, meaning that each commit points to its parent commit(s), which is why the arrows point in the opposite direction to the normal flow of time:

A graph of the example repository with abbreviated commit IDs

You can view the history (the DAG) in Git by using its git log command. There are also a number of visual Git tools that can graphically display the history. This section will show some features of git log.

Getting ready

We will use the example repository from the last section and ensure that the master branch is pointing to 34acc37:

$ git checkout master && git reset --hard 34acc37

In the previous command, we only use the first seven characters (34acc37) of the commit ID; this is fine as long as the abbreviated ID that is used is unique in the repository.

How to do it...

The simplest way to see the history is to use the

git log

command; this will display the history in reverse chronological order. The output is paged through

less

and can be further limited, for example, by providing only the number of commits in the history to be displayed:

$ git log -3

This will display the following result:

commit 34acc370b4d6ae53f051255680feaefaf7f7850d

Author:

John Doe <[email protected]

>

Date: Fri Dec 13 12:26:00 2013 +0100

This is the subject line of the commit message.

It should be followed by a blank line then the body, which is this text. Here

you can have multiple paragraphs etc. and explain your commit. It's like an

email with subject and body, so try to get people's attention in the subject

commit a90d1906337a6d75f1dc32da647931f932500d83

Author:

John Doe <[email protected]

>

Date: Fri Dec 13 12:17:42 2013 +0100

Instructions for compiling hello_world.c

commit 485884efd6ac68cc7b58c643036acd3cd208d5c8

Merge: 44f1e05 0806a8b

Author: John Doe <[email protected]>

Date: Fri Dec 13 12:14:49 2013 +0100

Merge branch 'feature/1'

Adds a hello world C program.

Turn on colors in the Git output by running git config --global color.ui auto.

By default,

git log

prints the commit, author's name and email ID, timestamp, and the commit message. However, the information isn't very graphical, especially if you want to see branches and merges. To display this information and limit some of the other data, you can use the following options with

git log

:

$ git log --decorate --graph --oneline --all

The previous command will show one commit per line (

--oneline

), identified by its abbreviated commit ID, and the commit message subject. A graph will be drawn between the commits depicting their dependency (

--graph

). The

--decorate

option shows the branch names after the abbreviated commit ID, and the

--all

option shows all the branches, instead of just the current one(s):

$ git log --decorate --graph --oneline --all

* 34acc37 (HEAD, tag: v1.0, origin/master, origin/HEAD, master) This is the sub...

* a90d190 Instructions for compiling hello_world.c

* 485884e Merge branch 'feature/1'

...

This output, however, gives neither the timestamp nor the author information, because of the way the --oneline option formats the output.

Fortunately, the

log

command gives us the ability to create our own output format. So, we can make a history view similar to the previous one. The colors are made with the

%C<color-name>text-be-colored%Creset