Advanced Git Tips and Tricks

Improve your daily workflow.

Supporting with GUI tools (know how to read the graphs). GUI tools are always limited.

Recommendation: Use the command line tool to learn use git and its advanced concepts.

Git Fundamentals

Mandatory to understand these concepts:

  • Commits
  • Snapshots
  • References

Object Model: It is the foundation of Git that uses the three concepts before.

When I commit changes:

  • Git creates a Commit Object (Object Model). It contains a Reference to its parent, the author and a timestamp.
  • A snapshot is a representation of the state of the directories and files in the repository at the time the Commit was made.
  • Internally the directory is represented by Git using an object called a Tree (which contains other Trees and Blobs).
  • Internally every object in Git (commit, tree, blob) has a unique ID (SHA-1 hash of its object's contents)
  • Reference is the user-friendly naming used by Git to easy its use.
  • In Git there are three types of References: Tag, Branch, HEAD
  • Tag is a fixed reference to a specific commit. Never changes. It is used as a Mark. to points a certain version in the repository.
  • Branch is a reference to the latest commit in the line of history. With every commit, the branch reference is updated to point to it. Its history is recreated from latest commit to track backwards.
  • HEAD is a special reference managed by Git to keep track of the branch or the commits.

Git - Command Line

In Windows

Git from PowerShell. Install a module called posh-git. Clone it from Github. Install it from a PowerShell command.

git clone https://github.com/dahlbyk/posh-git.git
cd posh-git
.\install.ps1
Import-Module posh-git

Import-Module from Windows PowerShell could throw an error.

Import-Module : No se puede cargar el archivo C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\PsGet\PsGet.psm1
porque la ejecución de scripts está deshabilitada en este sistema. Para obtener más información, vea el tema
about_Execution_Policies en http://go.microsoft.com/fwlink/?LinkID=135170.

This is fixed by executing:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

Now:

PS C:\ISBAN\workspaces\git-architecture\posh-git> Import-Module PsGet
PS C:\ISBAN\workspaces\git-architecture\posh-git> Import-Module posh-git
PS C:\ISBAN\workspaces\git-architecture\posh-git> .\install.ps1
C:\ISBAN\workspaces\git-architecture\posh-git [master ≡]>

Aliases (git config)

These are shortcut for Git commands useful for accelerate tool management.

Examples (one command):

git config alias.mialias status
# Means
git mialias
git config --global alias.miglobalalias status
# Means
git miglobalalias

Where they are located: cat .git/config | grep -A 1 "\[alias\]".

There are commands which applies to Repo, User or System level. Where the aliases are located using --global option is: ~/.gitconfig.

Examples (more than one command and options):

git config --global alias.qm  '!git checkout $1; git merge @{-1}'
git config --global alias.qm

# A serie of commands
git co work
echo "Here" >> nuevo.txt
git cma "Mas cambios"
git qm master

Aliases are used spreadly because simplify command execution in few steps.

Formatted and Pretty logs

Using git log command.

http://git-scm.com/docs/pretty-formats

Examples:

$ git log --pretty=oneline
$ git log --pretty='%h | %d %s  (%cr) [%an]'
# Using colors
$ git log --pretty='%Cred%h%Creset | %C(yellow)%d%Creset %s  %Cred(%cr)%Creset %C(cyan)[%an]%Creset'
# Using tree graph
$ git config --global alias.lg "log --pretty='%Cred%h%Creset | %C(yellow)%d%Creset %s  %Cred(%cr)%Creset %C(cyan)[%an]%Creset'
 --graph"

diffs

Based on Unified Diff Specification.

First configure Git to limit pagination in command results (avoid press q all the time).

$ git config --global core.pager 'less -RFX'
# Where core.pager is a command to setup pagination, F and X tells less to exit immediately
# if the output fits in a single screen. R option is for raw output. S option to wrap text line

When just a part of a line was modified, we need to tell Git to show only that difference.

git diff --word-diff

By default diff shows only 3 lines after and 3 lines after the difference found. To change that,

git diff --word-diff --unified=10

##
git config --global alias.dp 'diff --word-diff --unified=10'
git dp

Git uses different diff algorithms.

# It takes its time to find the complete block added, deleted, etc, instead of do it separately
$ git diff --patience

# Used to make a more readable/understandable format
$ git diff --histogram
# Or added to the config to apply all commands
$ git config --global  diff.algorithm histogram
$ git diff

diff in commits

Showing differences in commits (snapshots) between the commit referenced and its parent

# Show head diff
$ git show head

# Show head parent parent
git show head~2

# Show pretty formated
git show head --pretty='parent %p commit  %h  %d %n%n%w(72,2,2)%s%n%n%w(72,0,0) %an %ar'

# Show with alias
git config --global alias.so "show head --pretty='parent %p commit  %h  %d %n%n%w(72,2,2)%s%n%n%w(72,0,0) %an %ar'"
git so head

# Show without metadata (diff area)
git show head --no-patch

# Show a simplified metadata
git show head --stat

Git could show information about: Tree / Blob / Commits

# Low-level content, plumbing, raw content of the object pointed by the specific reference (commit)
git cat-file -p head

# Using the sha-1 of the tree object got in previous command
git cat-file -p 9f4545 

# Using the sha-1 of the blob object got in previous command
git cat-file -p 9fbbd

# This blob object does not contain diff content, it shows only file content

Delta chains: Git only stores (in storage subsystem) delta chains calculated on the fly when comparing commits.

Diffs between commits using ..: Using git diff head..head~2 --stat

Diffs between files: Using git diff head~3:README.md..head:README.md

Using diff with command line is not compared using GUI.

References

https://app.pluralsight.com/library/courses/git-advanced-tips-tricks/table-of-contents

results matching ""

    No results matching ""