Search code examples
bashgitshellgit-diff

Filter response from "git diff" command to get only the difference in Shell - Dynamic Solution


I am trying automate a redundant deployment process in my project. In order to achieve that I am trying to get the difference between two branches using "git diff" -- Someway and I am able to achieve that using the following command.

git diff <BRANCH_NAME1> -- common_folder_name/ <BRANCH_NAME2> -- common_folder_name/ > toStoreResponse.txt`

Now the response that I get, looks something like below:

diff --git a/cmc-database/common/readme.txt b/cmc-database/common/readme.txt

index 7820f3d..5a0e484 100644

--- a/cmc-database/common/readme.txt

+++ b/cmc-database/common/readme.txt

@@ -1 +1,5 @@

-This folder contains common database scripts.

\ No newline at end of file

+This folder contains common database scripts.

+TEST STTESA

\ No newline at end of file

So here in the above response only line/text that is a new line or the difference between the two branches is TEST STTESA and I want to store only that much of text in some different text file using shell / git way.

i.e a file named readme.txt which will only contain TEST STTESA content.

Work around Solution:

I have found a workaround to filter the response - but however it is not 100% what I am looking for. Command looks like below:

git diff <Branch_Name1> -- common-directory/ <Branch_Name2> -- common-directory/ | grep -v common-directory | grep -v index | grep -v @ | grep -v \\

The above command returns below response:

-This folder contains common database scripts.

+This folder contains common database scripts.

+TEST STTESA

But I want to be able to store only the difference which is TEST STTESA


Solution

  • As you can easily realize, your solution won't work every time. The grep -v parts make it unportable.

    Here is a "step0" solution : You want to match lines that start with a "+" or a "-" and then neither a "+" nor a "-". Use grep for that !

    git diff ... | grep  "^+[^+]\|^-[^-]"
    

    Some explanation : First, the \| part in the middle is an "or" statement. Then, each side starts with a ^ which refers to the beginning of the line. And finally, after the first character, we want to reject some characters, using the [^...] syntax.

    The line above translates to English as "Run the diff, and find all the lines that either start with a +, followed by something that is not a +, OR start with a -, followed by something that is not a -.

    This will not work properly if you remove a line that started with a -. Nor if you add a line that starts with a +. For such scenarii, I would tinkle with git diff --color and grep some [32m for the fun.