Tutorial Git Diff

From HaFrWiki
Jump to: navigation, search

Shows the git diff command in detail.
The example is a written example from Version Control with Git [1]

Introduction

A diff is a compact summary of the differences (hence the name “diff”) between two items.
For example, given two files, the Unix and Linux diff command compares the files line by line and summarizes the deviations in a diff. <syntaxhighlight lang="bash"> $ cat initial Now is the time For all good men To come to the aid Of their country.

$ cat rewrite Today is the time For all good men And women To come to the aid Of their country.

$ diff -u initial rewrite --- initial 1867-01-02 11:22:33.000000000 -0500 +++ rewrite 2000-01-02 11:23:45.000000000 -0500 @@ -1,4 +1,5 @@ -Now is the time +Today is the time

 For all good men

+And women

 To come to the aid 
 Of their country.

</syntaxhighlight> In details:

  • In the header, the original file is denoted by ---
  • In the header, the new file is denoted by +++
  • A line prefixed with a minus sign (-) must be removed from the original file to produce the new file.
  • A line with a leading plus sign (+) must be added to the original file to produce the new file.
  • A line that begins with a space is the same in both files and is provided by the -u option as context.

Git diff

Git has its own diff facility and can likewise produce a digest of differences.
The command git diff can compare files much akin to Unix’s diff command.

There are three basic sources for tree or treelike objects to use with git diff:

  • Any tree object anywhere within the entire commit graph
  • Your working directory
  • The index

The git diff command can perform four fundamental comparisons using various combinations of those three sources.

  • git diff shows the difference between your working directory and the index.
    It exposes what is dirty in your working directory and is thus a candidate to stage for your next commit.
    This command does not reveal differences between what’s in your index and what’s permanently stored in the repository (not to mention remote repositories you might be working with).
  • git diff commit summarizes the differences between your working directory and the given commit.
    Common variants of this command name HEAD or a particular branch name as the commit.
  • git diff --cached commit shows the differences between the staged changes in the index and the given commit.
    A common commit for the comparison — and the default if no commit is specified — is HEAD.
    With HEAD, this command shows you how your next commit will alter the current branch.
    If the option --cached doesn’t make sense to you, perhaps the synonym --staged will.
  • git diff commit1 commit2 displays the differences between the two.
    This command ignores the index and working directory, and it is the workhorse for arbitrary comparisons between two trees that are already in your object store.

Git diff example

<syntaxhighlight lang="bash"> $ mkdir /gitdiff $ cd /gitdiff

$ git init Initialized empty Git repository in /gitdiff/.git/

$ echo "foo" > file1 $ echo "bar" > file2

$ git add file1 file2 $ git commit -m "Add file1 and file2"

[master (root-commit) d1b90fd] Add file1 and file2
 2 files changed, 2 insertions(+)
 create mode 100644 file1
 create mode 100644 file2
  1. Next, let’s edit file1 by replacing the word “foo” with “quux.”

$ echo "quux" > file1

  1. Working directory versus index

$ git diff diff --git a/file1 b/file1 index 257cc56..d90bda0 100644 --- a/file1 +++ b/file1 @@ -1 +1 @@ -foo +quux

  1. Working directory versus HEAD

$ git diff HEAD diff --git a/file1 b/file1 index 257cc56..d90bda0 100644 --- a/file1 +++ b/file1 @@ -1 +1 @@ -foo +quux

  1. Index vs HEAD, identical still

$ git diff --cached $

  1. There is a difference, so let's stage file1

$ git add file1 $ git status On branch master Changes to be committed:

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

modified: file1

  1. Working directory versus index.

$ git diff $

  1. Working directory versus HEAD

$ git diff HEAD diff --git a/file1 b/file1 index 257cc56..d90bda0 100644 --- a/file1 +++ b/file1 @@ -1 +1 @@ -foo +quux

  1. Index vs HEAD

$ git diff --cached diff --git a/file1 b/file1 index 257cc56..d90bda0 100644 --- a/file1 +++ b/file1 @@ -1 +1 @@ -foo +quux </syntaxhighlight>

If you ran git commit now, the new commit would capture the staged changes shown by the last command, git diff --cached (which, as mentioned before, has the new synonym git diff --staged).


Git Diff Commit

Now, to throw a monkey wrench in the works, what would happen if you edited file1 before making a commit? Let’s see! <syntaxhighlight lang="bash"> $ echo "baz" > file1

  1. Working Directory versus index

$ git diff diff --git a/file1 b/file1 index d90bda0..7601807 100644 --- a/file1 +++ b/file1 @@ -1 +1 @@ -quux +baz

  1. Working directory versus HEAD

$ git diff HEAD diff --git a/file1 b/file1 index 257cc56..7601807 100644 --- a/file1 +++ b/file1 @@ -1 +1 @@ -foo +baz

  1. Index vs HEAD

$ git diff --cached diff --git a/file1 b/file1 index 257cc56..d90bda0 100644 --- a/file1 +++ b/file1 @@ -1 +1 @@ -foo +quux </syntaxhighlight>

All three diff operations show some form of difference now! But which version will be committed?
Remember, git commit captures the state present in the index.
And what’s in the index?
It’s the content revealed by git diff --cached or git diff --staged command, or the version of file1 that contains the word “quux”! <syntaxhighlight lang="bash"> $ git commit -m "quux uber alles" [master]: created f8ae1ec: "quux uber alles" 1 files changed, 1 insertions(+), 1 deletions(-)

  1. Previous HEAD version versus current HEAD

$ git diff HEAD^ HEAD diff --git a/file1 b/file1 index 257cc56..d90bda0 100644 --- a/file1 +++ b/file1 @@ -1 +1 @@ -foo +quux </syntaxhighlight>


Finally

So is everything synchronized now? No. The working directory copy of file1 contains “baz.” <syntaxhighlight lang="bash"> $ git diff diff --git a/file1 b/file1 index d90bda0..7601807 100644 --- a/file1 +++ b/file1 @@ -1 +1 @@ -quux +baz </syntaxhighlight>


See also

top

Reference

top

  1. Version Control with Git, Powerful Tools and Techniques for Collaborative Software Development, Jon Loeniger & Matthew McCullough, O'Reilly, 2012 Second Edition, isbn: 9781449316389.