Saturday, January 30, 2016

Unleashing the Git - part 2 - git log and git stat

This is the 2nd part of the Git posts I'm currently blogging on. You can find the fist part here. This part focuses on the git logging and its various outputs and statistics generation in git. These information are vital for developers. Some of the uses are to see the recent changes, diffs in recent commits, who made what change etc. Let's dive into these commands and see what they have to offer us.
$ git shortlog

Shazni Nazeer (10):
      First commit
      Removing compliled files
      Removing log files
      Verifying folder existence
      create directory called logs
      Data loading from DB
      More logging configurations and message parsing
      adding MessageProcessor.py
      Handling of few user requests
      Bug fixes and Items ID is changed to VARCHAR from INT
Above command arranges all the users who were involved in building the repository data in alphabetical order, showing number of commits they have made along with descriptions. Of course if you have only one user contributing, only that users information is listed. If you specify a -n parameter to the same command it will order the users by number of commits.

With -e parameter we can get the email address of the user, whereas the -s parameter gives a summary of each users stages/commits.

git log command as I stated earlier gives git commit ID and other meta information. If you specify --skip=<number> it will omit last <number> of commits and show only others. Following are handful of git log examples that you may find useful in your day to day development work.
$ git log -p // Shows the commit changes
$ git log -1 -p HEAD   // To see the latest commit
$ git log -p -2 // Limit the output to only last two commits, also shows the diffs
$ git log -5 // Shows only the last 5 commit without diffs.
$ git log HEAD^^..HEAD   // Same as git log -2
$ git log --skip=4   // Skips the last 4 commit details
$ git log --since=2014-02-27 --until=2014-03-10   // Only get commit details between the specified dates
$ git log --since=2.days // Find commit of last 2 days - If 3.months - Since three month before
$ git log --since="1 week" == git log --after="7 days" == git log --since="168 hours"
$ git log --before="1 week" == git log --until="7 days" == git log --before="168 hours"
$ git log --author="some user"
$ git log --grep="user" // Finds all the commits with a descrpition having the word user. -i paramter at the end ensures case insensitive search
$ git log --stat  // Gives details with files changed
$ git log --pretty=oneline
$ git log --pretty=format:"%h - %an, %ar : %s"
$ git log --pretty=format:"%h %s" --graph
$ git log --oneline // first seven characters of the commit id and the commit message shown
$ git log -- some/path/
$ git log -- somefile

It's often the case while developing that you add few files to your repository mistakenly or for testing which you never intent to commit. You can use git clean command to remove those. Let's assume we need to remove all the text file with extension .txt

Following two commands will do it.
$ git clean -f -e*.txt
$ git clean -f
Getting information in git is not limited to git log command. We often need to know more information on individual files changes and other useful information. git diff command have plethora of options to provide you with required information about your repository. Let's check some of the commands that you might find useful.

$ git diff // The diff between the working tree and the staged area
$ git diff --staged // View the difference between staged changes and the repository

View the differences between the working tree and a commit in the repository
$ git diff HEAD
$ git diff <Commit ID>
$ git diff <first commit id> <second commit id>    or $ git diff <first commit id>..<second commit if>  // View the differences between two commits.
$ git diff -- path/ // Limit the diff output to a specific path
$ git diff-tree -p COMMIT // Where COMMIT is your commit number to see what was changed in that commit

Generating stats
 
git diff can also be used to get some statistics output in addition to differences in the source code. Some of the examples are as shown below.

$ git diff --stat HEAD~5  or git diff --stat HEAD~5 HEAD  // Show change stats between last 5 commits
$ git diff --stat <first_commit_id> <second_commit_id> // Stats between two commits 
$ git diff --shortstat HEAD~5 // Shows number of files changed, insertions and deletions.
$ git diff --numstat HEAD~5 // Shaows the stat in more 
$ git diff --stat -p HEAD^  // also shows the oatch in addion to stats
$ git log --stat  // Shows full stats along with logs
$ git log --shortstat // Shows Cumulative stats only along with usual log

There is a command that can used to give information on invidividual user responsible for changes in source file by line number. git blame displays all or a portion of a file with annotations showing when
the change was made, by whom, and, more importantly, in what revision the
change was made.

git blame outputs the following information:
• Short commit ID
• Author’s name
• Date and time of commit
• Line number

$ git blame <some_file> // To show the entire file with line by line info on above
$ git blame -L 20 <some_file>  // Starts blaming of the beginning from line 20
$ git blame -L 100,120 <some_file>  // Limit the blame to lines 100 to 120 
$ git blame -L 5,+20 <some_file>   // Limit the blame starting from line number 5 to 20 lines
$ git blame -L 30,-13 <some_file>  // Get the blame of the file from line number 30 to 13 lines behind
$ git blame -L "<POSIX Reg Ex>",+20 <some_file> // Get the blame of the specified file from the line matching to regex to 20 lines ahead

Git can track content that moves around in a file or is copied from one file to
another. You can use git blame to show content that has moved around by
adding the -M parameter.

$ git blame -M <some_file>     // To see which part has got moved around in the specified file

You can also track changes copied from another file by using the -C
parameter. It checks the changes in the file against other changes in the
repository to see whether it was copied from somewhere else. 

$ git blame -C <some_file>     // To see which part has got copied from another file in the specified file