Posts tagged 'diff'

Compare files across branches

published on January 21, 2020.

After some bigger rebases in git, I have to compare a file between two branches, most often master and the current branch.

git diff master my-branch -- file/to/diff

The diff will show what was added to the file in my-branch, as well what was removed. Helps a lot with fixing conflicts during rebases gone bad.

Happy hackin’!

Tags: git, diff, branches.
Categories: Development.

Filter git diff by type of change

published on January 02, 2020.

Yesterday I was looking at a rather large diff, but for the type of change I was after, I wanted to look only at the newly added files. Turns out, git diff has a filtering option with --diff-filter.

The possible values for the --diff-filter are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), type changed (T), Unmerged (U), Unknown (X), and some kind of a Broken (B) file(?).

Running git diff --diff-filter=A will show the diff only for the added files.

These filtering options can also be provided with lowercase, in which case it will behave as an exclude filter. git diff --diff-filter=a will show the diff for all files, except for added ones.

Happy hackin’ and a happy new year!

Versions used for examples: git 2.17.
Tags: git, diff, filter.
Categories: Development, Software.

Anatomy of a git diff

published on December 20, 2016.

I'm looking at git diffs every day, all day. Diffs hold a lot of information that can be valuable, and I think it's a good thing to know how to fully read a git diff.

A simple diff looks something like this:

diff --git a/example.php b/example.php
index a5174a9..11aeb84 100644
--- a/example.php
+++ b/example.php
@@ -11,7 +11,10 @@ class Greeter
         $this->name = $name;
     }
 
-    public function greet()
+    /**
+     * Return the greeting message.
+     */
+    public function greet() : string
     {
         return sprintf("Hello %s" . PHP_EOL, $this->name);
     }

This simple example holds most of the information that is needed from a diff.

The first line tells that the diff is in the git format and the filename(s) before and after the changes.

The second line tells about the type of file and its permissions (100644) and the two hashes are just that - shortened hashes of the pre- and post-images. AFAIK, this line is used when
doing 3-way merges.

The lines 3 and 4 again deal with the name of the file(s). If it's a new file, the source - --- - is /dev/null, and if an existing file was deleted, the target - +++ - will be /dev/null.

I'll skip line 5 for a moment and come back to it later.

The next part, the actuall diff, shows what lines in the current hunk were added and what lines were removed:

         $this->name = $name;
     }
 
-    public function greet()
+    /**
+     * Return the greeting message.
+     */
+    public function greet() : string
     {
         return sprintf("Hello %s" . PHP_EOL, $this->name);
     }

Lines that start with a + sign were added, and lines with a - sign were removed. Lines with no + or - are here just to give us some context of the code. Looking at this diff we
see that one line was removed and 4 lines were added.

Now back to line 5 as this is probably the hardest part to understand:

@@ -11,7 +11,10 @@ class Greeter

These numbers always seemed random to me.

This line is, I belive, called “unified diff hunk identifier”, and the format of this line is:

@@ from-file-range to-file-range @@ [header]

which to be honest, isn't that helpful. The @ signs are just delimiters.

The first pair of numbers, -11,7, means that the current hunk in the source file starts at line 11 and has a total of 7 lines.

The starting line can be confirmed in any editor: $this->name = $name; really is the 11th line in the edited file. That's easy.

The number 7 means that there are 7 lines in total that have a - sign or no sign at all (contextual lines). If we count the number of contextual lines and lines with a -,
skipping the lines with the + at the beginning, we see the total is 7.

The second pair of numbers, +11,10 means that the current hunk in the target file starts at line 11 and has a total of 10 lines.

The number 10 means that there are 10 lines in total that have a + sign or no sign at all (contextual lines). If we count the number of contextual lines and lines with a +,
skipping the lines with the - at the beginning, we see the total is 10.

Finally, class Greeter, the [header] part of this line, tells us were did the change happen. This may, or may not, be present.

This example is a simple one, but I think it covers most of the use cases of a git diff output, and it helps us understand the unified diff hunk identifier line (the line with @@s),
which is useful to know, especially when editing git hunks manually.

Happy hackin’!

Tags: git, diff, hunk.
Categories: Development, Software.

Verbose commiting

published on December 12, 2016.

One thing I recently learned about git, is the -v or --verbose flag for the git commit command. It shows the diff of what is being commited in $EDITOR below the commit message
template. Taken directly from man git commit:

Show unified diff between the HEAD commit and what would be committed at the bottom of the commit message template to help the user describe the commit by reminding what
changes the commit has. Note that this diff output doesn’t have its lines prefixed with #. This diff will not be a part of the commit message.

I keep double checking the code that I commit, so prior to discovering this flag, I was constantly switching between writing the commit message and seeing what's in the diff. This now
gives me the diff inside vim, as that is my specified $EDITOR. I can navigate the diff using vim motions, use search, etc, which greatly improves my workflow.

Happy hackin’!

Tags: git, message, verbose, diff.
Categories: Software, Development.
Robert Basic

Robert Basic

Software developer making web applications better.

Let's work together!

I would like to help you make your web application better.

Robert Basic © 2008 — 2020
Get the feed