Tips and Tricks

Git can do a lot more things than we have seen during this training. This section will cover some of the more interesting things you can do with git.

git grep

The git grep command is useful for searching through all of the files that are under revision control. Files that are not under revision control are ignored.

References:

git add -i

The git add -i command makes the git add command interactive. You can select which files to add, update or patch. It is quite powerful and well worth learning how to use.

I also find git add -p to be quite useful.

For more information:

$ git help add

gitk

The gitk tool provides a graphic display of the history of the repository. To use gitk, you may need to install the gitk package (using apt-get, yum or whatever your system uses to manage packages).

gitk shows a very dense view of the history of the repository by showing the following:

  • Branches (local and remote).
  • Which commit is currently checked out.
  • Tags (and associated meta data).
  • Commit relationships.
  • Commit meta data.

To view the history for all branches at once:

$ gitk --all

Sometimes it is useful to pull down changes from a remote, but review them before merging locally:

$ git checkout master
$ git fetch origin
$ gitk origin/master
$ git merge origin/master

Another useful operation is to view the history of a specific file or directory:

$ gitk -- path/to/file
$ gitk -- path/to/directory

Right clicking on the subject line of a commit in gitk will bring a context menu that will allow you to before some basic git operations.

I often leave gitk running in the background as I work through changes and then use the File->Reload menu option to refresh the view of the repository.

Using gitk as part of this workflow can greatly improve the quality of your commits and make your fellow developers lives easier as you will be able to find and fix bad commits before you push them to other:

$ git checkout -b feature/cool-stuff master
$ vim <files>           # do some work
$ git status            # see what you changed
$ git diff              # review your work
$ git diff --check      # Check for white space errors in your changes
$ gitk                  # review you work WRT to history
$ git add <files>       # stage your changes
$ gitk                  # more review WRT to history
$ git ci                # commit locally

Iterate on the above to generate a series of commits and get ready to push:

$ gitk                  # Review the patchset you have generated locally
$ git rebase -i <ref>   # Cleanup your ugly or embarressing commits
$ gitk                  # More review (are you starting to see pattern developing?)
$ git push origin feature/cool-stuff    # publish your changes to the world for peer-review

Now, you may be asking yourself, that seems like a lot of extra work? Yes, it is, but asking for peer-review of your code for things that you should have fixed before pushing is extra work for you and the reviewer later. And then if the review misses a bug that manifests a year later, how much extra work will it be to fix that bug then?

git diff --check

You can have git check for white space errors in your changes before you commit them with the git diff --check or git diff --cached --check. You should strive to use these commands before every commit.

Many Open Source project maintainers get grumpy if merge requests contain white space issues.

git describe

Todo

Discuss git describe and how it can be used to automate versioning.

Showing the Git Branch in your Prompt

If you are using bash as your shell, you can modify the command prompt using the PS1 environment variable. If you install git and bash_completion, you will have a /etc/bash_completion.d/git-prompt file installed on your system. The git-prompt script should get sourced by your shell at login and will provide a __git_ps1 shell function.

Using the __git_ps1 shell function in your PS1 variable will show the currently checked out branch in your prompt.

Here’s what my prompt looks like (except for colorization):

### [11:35:29 am][Ubuntu-16.04] Branch: master
### [troth@example:~/git/git-train/git-training/source]
>--> $

And here’s the code from my ~/.bash_profile to generate that prompt:

OS_REL=$(lsb_release -irs | tr '\n' ' ' | tr ' ' '-' | sed -e 's/-$//')
export OS_REL

_BLK_ ()
{
    printf -- "\033[0m"
}
_RED_ ()
{
    printf -- "\033[31m"
}
_GRN_ ()
{
    printf -- "\033[32m"
}
_BLU_ ()
{
    printf -- "\033[34m"
}
_CYN_ ()
{
    printf -- "\033[36m"
}

PS1='\n$(_GRN_)### $(_BLU_)[\T \D{%P}]$(_CYN_)[${OS_REL}]'\
'$(__git_ps1 "$(_RED_) Branch: %s")\n'\
'$(_GRN_)### [\u@\h:\w]$(_BLK_)\n>--> \$ '

export PS1

Showing the currently checked out branch in the prompt saves you from constantly having to run git branch to see which branch you are working on.

Writing Good Commit Messages

Writing a good commit message is an art and takes practice, but is crucial to the sanity of future developers looking at your commit (your future self included).

The following is probably one of the best articles on writing git commit messages:

Crafting a Good Commit

Todo

Discuss what makes a good commit and/or commit series.