Search code examples
gitgit-diff

Get added and deleted files from git diff output with HEAD


I'm using git diff to get the differences between a commit and his parent for a specific file. I'm using this command :

git diff parent-sha child-sha  -- file/to/path

Here is my problem : with this command I can get added, deleted and modified files for a specific commit. But when I try it on my current commit, I can only get modified/deleted files. I'm looking for a way to get deleted and added files for the current commit (comparing to his parent).

For instance here's my uncommitted changes : enter image description here

If I run git diff HEAD -- yarn.lock

I get this

diff --git a/yarn.lock b/yarn.lock
deleted file mode 100644
index c06acb9..0000000
--- a/yarn.lock
+++ /dev/null
@@ -1,10383 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"7zip-bin@~4.1.0":
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-4.1.0.tgz#33eff662a5c39c0c2061170cc003c5120743fff0"
-  integrity sha512-AsnBZN3a8/JcNt+KPkGGODaA4c7l3W5+WpeKgGSbstSLxqWtTXqd1ieJGBQ8IFCtRg8DmmKUcSkIkUc0A4p3YA==
-
-"@angular-devkit/architect@0.11.4":
-  version "0.11.4"
-  resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.11.4.tgz#f0cc3b4f1dd0128f6b41d3bb760bcf4c324cd063"
-  integrity sha512-2zi6S9tPlk52vyqN67IvFoeNgd0uxtrPlwl3TdvJ3wrH7sYGJnkQ+EzAE7cKUGWAV989BbNtx2YxhRDHnN21Fg==

But nothing on git diff -- src/app/models/DiffFileInformation.ts


Solution

  • The following 3 commands are not the same:

    git diff
    git diff HEAD
    git diff HEAD^ HEAD
    

    Suppose we have initialized a repo and made two commits and some extra uncommitted changes.

    git init foo
    cd foo
    touch a.txt b.txt
    git add .
    git commit -m 'first commit'
    
    echo hello >> a.txt
    echo hello >> b.txt
    git commit -m 'hello'
    
    echo world >> a.txt
    echo world >> b.txt
    # stage a.txt and leave b.txt alone
    git add a.txt
    
    1. What does git diff return?

    git diff compares the working tree and the index. The working tree has the modified version of a.txt and b.txt, and the index has only the modified version of a.txt. So the difference lies between the working tree's b.txt and the index's b.txt:

    hello
    world
    

    VS

    hello
    

    git diff returns:

    diff --git a/b.txt b/b.txt
    index ce01362..94954ab 100644
    --- a/b.txt
    +++ b/b.txt
    @@ -1 +1,2 @@
     hello
    +world
    
    1. What does git diff HEAD return?

    It compares the files in the revision of HEAD with the files in the working tree. a.txt in HEAD is

    hello
    

    a.txt in the working tree is

    hello
    world
    

    b.txt is the same with a.txt, so git diff HEAD returns:

    diff --git a/a.txt b/a.txt
    index ce01362..94954ab 100644
    --- a/a.txt
    +++ b/a.txt
    @@ -1 +1,2 @@
     hello
    +world
    diff --git a/b.txt b/b.txt
    index ce01362..94954ab 100644
    --- a/b.txt
    +++ b/b.txt
    @@ -1 +1,2 @@
     hello
    +world
    
    1. What does git diff HEAD^ HEAD return?

    It compares the files of the former revision with the files of the latter. In HEAD^, both a.txt and b.txt are empty. In HEAD, both are:

    hello
    

    So we get the output of git diff HEAD^ HEAD as:

    diff --git a/a.txt b/a.txt
    index e69de29..ce01362 100644
    --- a/a.txt
    +++ b/a.txt
    @@ -0,0 +1 @@
    +hello
    diff --git a/b.txt b/b.txt
    index e69de29..ce01362 100644
    --- a/b.txt
    +++ b/b.txt
    @@ -0,0 +1 @@
    +hello
    

    If we swap HEAD^ and HEAD, git diff HEAD HEAD^ returns:

    diff --git a/a.txt b/a.txt
    index ce01362..e69de29 100644
    --- a/a.txt
    +++ b/a.txt
    @@ -1 +0,0 @@
    -hello
    diff --git a/b.txt b/b.txt
    index ce01362..e69de29 100644
    --- a/b.txt
    +++ b/b.txt
    @@ -1 +0,0 @@
    -hello
    

    HEAD and HEAD^ could be any commits reachable in the repository. Instead of swapping the revisions, we can also get the reversed diff with the option -R, git diff -R HEAD^ HEAD.

    Not sure what your purpose exactly is. Maybe you can find the solution here. More syntaxes of git diff are described.