Book Image

Git Version Control Cookbook - Second Edition

By : Kenneth Geisshirt, Emanuele Zattin(EUR), Aske Olsson, Rasmus Voss
Book Image

Git Version Control Cookbook - Second Edition

By: Kenneth Geisshirt, Emanuele Zattin(EUR), Aske Olsson, Rasmus Voss

Overview of this book

Git is one of the most popular tools for versioning. With over 100 practical, self-contained tutorials, this updated version of the bestselling Git Version Control Cookbook examines the common pain points and best practices to help you solve problems related to versioning. Each recipe addresses a specific problem and offers a proven, best-practice solution with insights into how it works. You’ll get started by learning about the Git data model and how it stores files, along with gaining insights on how to commit changes to a database. Using simple commands, you’ll also understand how to navigate through the database. Once you have accustomed yourself to the basics, you’ll explore techniques to configure Git with the help of comprehensive examples and configuration targets. Further into the book, you’ll get up to speed with branches and recovery from mistakes. You’ll also discover the features of Git rebase and how to use regular Git to merge other branches. The later chapters will guide you in exploring Git notes and learning to utilize the update, list, and search commands. Toward the concluding chapters, you’ll focus on repository maintenance, patching, and offline sharing. By the end of this book, you’ll have grasped various tips and tricks, and have a practical understanding of best-practice solutions for common problems related to versioning.
Table of Contents (19 chapters)
Title Page
Copyright and Credits
Packt Upsell
Contributors
Preface
Index

Extracting fixed issues


A common use case of creating a release is to create a release note, containing, among other things, the bugs fixed in the release. A good practice is to write in the commit message whether a bug is fixed by the commit. A better practice is to have a standard way of doing this—for example, a line with the string "Fixes-bug: ", followed by the bug identifier in the last part of the commit message. This makes it easy to compile a list of bugs fixed for a release note. The JGit project is a good example of this; their bug identifier in the commit messages is a simple "Bug: " string followed by the bug ID.

This recipe will show you how to limit the output of git log to only list the commits since the last release (tag), which contains a bug fix.

Getting ready

Clone the JGit repository using the following command lines:

$ git clone https://git.eclipse.org/r/jgit/jgit
$ cd jgit 

If you want the exact same output as in this example, reset your master branch to b14a93971837610156e815ae2eee3baaa5b7a44b:

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

How to do it...

You are now ready to look through the commit log for commit messages that describe the bugs fixed.

  1. First, let's limit the log to only look through the history since the last tag (release). To find the last tag, we can use git describe:
$ git describe 
v3.1.0.201310021548-r-96-gb14a939

The preceding output tells us three things:

    • The last tag was v3.1.0.201310021548-r
    • The number of commits since the tag was 96
    • The current commit in abbreviated form is b14a939

Now, the log can be parsed from HEAD to v3.1.0.201310021548-r. But just running git log 3.1.0.201310021548-r..HEAD will give us all 96 commits, and we just want the commits with the commit messages that contain "Bug: xxxxxx" for our release note. The xxxxxx is an identifier for the bug, and will be a number. We can use the --grep option with git log for this purpose, making the code phrase git log --grep "Bug: ". This will give us all the commits containing "Bug: " in the commit message; all we need to do now is just to format it to something that we can use for our release note.

  1. Now, let's say we want the release note format to look like the following template:
Commit-id: Commit subject Fixes-bug: xxx
  1. Our command line so far is as follows:
$ git log --grep "Bug: " v3.1.0.201310021548-r..HEAD

This gives us all the bug fix commits, but we can format this to a format that is easily parsed with the --pretty option.

  1. First, we will print the abbreviated commit ID (%h), followed by a separator of our choice (|), and then the commit subject (%s, the first line of the commit message), followed by a new line (%n), and the body (%b):
--pretty="%h|%s%n%b"

The output, of course, needs to be parsed, but that's easy with regular Linux tools, such as grep and sed.

  1. First, we just want the lines that contain "|" or "Bug: ":
grep -E "\||Bug: "
  1. Then, we replace these with sed:
sed -e 's/|/: /' -e 's/Bug:/Fixes-bug:/'
  1. The entire command put together is as follows:
$ git log --grep "Bug: " v3.1.0.201310021548-r..HEAD --pretty="%h|%s%n%b" | grep -E "\||Bug: " | sed -e 's/|/: /' -e 's/Bug:/Fixes-bug:/'
  1. The previous set of commands gives the following output:
f86a488: Implement rebase.autostash 
Fixes-bug: 422951 
7026658: CLI status should support --porcelain 
Fixes-bug: 419968 
e0502eb: More helpful InvalidPathException messages (include reason) 
Fixes-bug: 413915 
f4dae20: Fix IgnoreRule#isMatch returning wrong result due to missing reset 
Fixes-bug: 423039       
7dc8a4f: Fix exception on conflicts with recursive merge 
Fixes-bug: 419641 
99608f0: Fix broken symbolic links on Cygwin. 
Fixes-bug: 419494 
...  

Now, we can extract the bug information from the bug tracker and put the preceding code in the release note as well, if necessary.

How it works...

First, we limit the git log command to only show the range of commits we are interested in, and then we further limit the output by filtering the "Bug: " string in the commit message. We pretty print the string so we can easily format it to a style we need for the release note, and finally, find "Bug: " and replace it by "Fixes-bug: " using grep and sed to completely match the style of the release note.

There's more...

If we just wanted to extract the bug IDs from the commit messages and didn't care about the commit IDs, we could have just used grep after the git log command, still limiting the log to the last tag:

$ git log  v3.1.0.201310021548-r..HEAD | grep "Bug: "

If we just want the commit IDs and their subjects, but not the actual bug IDs, we can use the --oneline feature of git log combined with the --grep option:

$ git log --grep "Bug: " --oneline  v3.1.0.201310021548-r..HEAD