81

In order to diff binary files in git, I assume I need to set up a difftool.

What difftools work? How do you put the parameters in?

1
  • What kind of output are you expecting to get from a diff tool of a binary file? What kind of binary file is this? Is it something that can be rendered to a text format and then compared?
    – Zoredache
    Jan 24, 2014 at 1:04

6 Answers 6

68

If you want to force git to show binary files diff as a plain text diff use --text option like so:

git diff --text
2
  • I love this answer because it's so simple and quick! One thing that I'm noticing is that it seemingly doesn't work for a merge conflict. If anyone knows how to get that to work, I think that would be a great addition. Jan 12, 2021 at 19:04
  • Note that if you have an external diff (diff.external) set up, you may need to add --no-ext-diff to bypass it. May 29, 2023 at 2:24
44

You can set a textconv config option for a filetype. See "Performing text diffs of binary files" in gitattributes(5). What you should use depends on the filetype.

Example 1

Say you want to diff the contents of zip files. In that case you should put in one of the following files $XDG_CONFIG_HOME/git/config or $HOME/.gitconfig or $GIT_DIR/config .

[diff "zip"]
    textconv = unzip -v

Next time you ask for a diff on a zip file in a repo, it will call unzip -v on both version and diff the resulting text.

Example 2

For PDF files, you could use e.g. pdfinfo;

[diff "pdf"]
    textconv = pdfinfo

Example 3

If there is no specific information utility for a filetype, you could e.g. use hexdump (comes with FreeBSD and OSX, also available on Linux):

[diff "bin"]
    textconv = hexdump -v -C
13
  • I could diff it in hex. I'd be happy enough just knowing how many bytes are different, or at what positions the bytes differ. I ended up using Hex Fiend by cloning my git repository so I could check out both versions of the file, because I couldn't figure out how to get git to launch the program. Jan 25, 2014 at 6:09
  • 2
    I added Example 3 to my git config, but when I do "git diff" it still just gives me the same short message: "Binary files a/file and b/file differ" Jan 31, 2014 at 18:25
  • 1
    If you want to use libmagic, you'll have to look into the git source code to see if that works... Feb 8, 2014 at 20:50
  • 11
    I finally got this to work, after adding *.bin diff=bin to my .gitattributes Jan 7, 2015 at 13:09
  • 3
    @nilskp You need to both define a diff in your .gitconfig file and assign that attribute to a path in .gitattributes. Nov 20, 2016 at 10:53
34

The answer from Roland Smith was helpful but is currently incomplete (see the comments) - there are two parts to this.

You can define a new diff commands in your repository's .git/config file or your personal global $XDG_CONFIG_HOME/git/config/.gitconfig (usually $HOME/.gitconfig) file, for example a hex diff command using hexdump:

[diff "hex"]
    textconv = hexdump -v -C
    binary = true

Next, you need to use the repository's .gitattributes file to tell git which files should be used with this special diff command:

# Binary files (no line-ending conversions), diff using hexdump
*.bin binary diff=hex

Like the .gitignore file, the .gitattributes file should be checked into your repository.

In my case I have several different file extensions which I want to treat as binary (e.g. avoid any line ending conversions if using git on Windows), and also see any differences via hexdump:

https://github.com/peterjc/galaxy_blast/commit/5ec4695e6c3da3926fb100ca006f0f3e88c53c3d

See also https://github.com/resin-io/etcher/pull/1367 for another example defining a hexdump diff command for use with image files.

1
  • 5
    You can set the .gitattributes globally as well (to go along with the [diff] entries in your global .gitconfig). If you make the .gitattributes local to the repo, then the user will have to modify his local .gitconfig repo settings because for security reasons those will not be pushed to the remote. Either way, each user has to update their local files/config somehow to enable this behavior. In .gitconfig under [core] add attributesfile = c:/users/<username>/.gitattributes or wherever you want to store it if you make it global (note the forwardslashes, even in windows).
    – LightCC
    Nov 1, 2019 at 20:40
6

To create a binary patch, a patch that works for binaries instead of just saying "Binary files differ", use

git diff --binary file1 file2

This produces a "GIT binary patch" using only ASCII characters (unlike --text), suitable for emailing.

3

I liked @qwr's answer above, however I wanted to see it in hexdump mode, rather than deflated(compressed) base85 "Git binary patch" format. If I use @peterjc's answer from above, then I get the diff between two hexdumps which is like concat-ing two hexdumps, so not very useful.

As such, I've decided to patch git(v2.37.3 on Gentoo) to add --hexdump argument to git diff which works only in --binary mode, and now it looks like in this example:

$ git diff --hexdump --binary  HEAD~1  "./dated/sheet0005_older/2006/sheet0620/20000809_1118(3)..JPG"
diff --git a/txt/papersheets/dated/sheet0005_older/2006/sheet0620/20000809_1118(3)..JPG b/txt/papersheets/dated/sheet0005_older/2006/sheet0620/20000809_1118(3)..JPG
index 263d047bf61e2104157d4b1feda5b77a01000847..c78a9a1ddddd0267dc490711eaf1723e38767b09 100644
GIT binary hexdump (non-reusable, for human eyes only) patch
delta 34
CC A0 18 C7 FD 17 02 FF  D8 83 87 11 87 87 11 01   |................|
87 87 11 02 87 87 11 03  87 87 11 04 B7 87 11 05   |................|
C5 FE                                              |..              |

delta 4140
C7 FD 17 CC A0 18 7F FF  D8 FF E1 11 83 45 78 69   |.............Exi|
66 00 00 49 49 2A 00 08  00 00 00 0A 00 0F 01 02   |f..II*..........|
00 0E 00 00 00 86 00 00  00 10 01 02 00 06 00 00   |................|
00 A6 00 00 00 12 01 03  00 01 00 00 00 01 00 00   |................|
00 1A 01 05 00 01 00 00  00 DE 00 00 00 1B 01 05   |................|
00 01 00 00 00 E6 00 00  00 28 01 03 00 01 00 00   |.........(......|
00 02 00 00 00 31 01 02  00 26 00 00 00 B6 00 00   |.....1...&......|
00 32 01 02 00 14 00 00  00 EE 00 00 00 13 02 03   |.2..............|
00 01 00 00 00 02 7F 00  00 00 69 87 04 00 01 00   |..........i.....|
00 00 02 01 00 00 76 02  00 00 53 6F 6E 79 20 45   |......v...Sony E|
72 69 63 73 73 6F 6E 00  00 00 00 00 00 00 00 00   |ricsson.........|
00 00 00 00 00 00 00 00  00 00 57 38 30 30 69 00   |..........W800i.|
00 00 00 00 00 00 00 00  00 00 52 31 42 43 30 30   |..........R1BC00|
32 20 20 20 20 20 70 72  67 43 58 43 31 32 35 30   |2     prgCXC1250|
30 39 32 5F 45 55 5F 31  5F 43 41 20 34 2E 35 00   |092_EU_1_CA 4.5.|
00 00 48 00 00 00 01 00  00 00 48 00 00 00 01 00   |..H.......H.....|
00 00 32 30 30 30 7F 3A  30 38 3A 30 39 20 31 31   |..2000.:08:09 11|
3A 31 38 3A 32 32 00 16  00 9A 82 05 00 01 00 00   |:18:22..........|
00 10 02 00 00 9D 82 05  00 01 00 00 00 18 02 00   |................|
00 27 88 03 00 01 00 00  00 64 00 00 00 00 90 07   |.'.......d......|
00 04 00 00 00 30 32 32  30 03 90 02 00 14 00 00   |.....0220.......|
00 20 02 00 00 04 90 02  00 14 00 00 00 34 02 00   |. ...........4..|
00 01 91 07 00 04 00 00  00 01 02 03 00 04 92 0A   |................|
00 01 00 00 00 48 02 00  00 07 92 03 00 01 00 00   |.....H..........|
00 02 00 00 00 08 7F 92  03 00 01 00 00 00 00 00   |................|
00 00 09 92 03 00 01 00  00 00 00 00 00 00 00 A0   |................|
07 00 04 00 00 00 30 31  30 30 01 A0 03 00 01 00   |......0100......|
00 00 01 00 00 00 02 A0  04 00 01 00 00 00 60 06   |..............`.|
00 00 03 A0 04 00 01 00  00 00 C8 04 00 00 05 A0   |................|
04 00 01 00 00 00 58 02  00 00 01 A4 03 00 01 00   |......X.........|
00 00 00 00 00 00 02 A4  03 00 01 00 00 00 00 00   |................|
00 00 03 A4 03 00 01 00  00 00 00 00 00 00 04 A4   |................|
05 00 01 00 00 00 7F 50  02 00 00 06 A4 03 00 01   |.......P........|
00 00 00 03 00 00 00 0C  A4 03 00 01 00 00 00 03   |................|
00 00 00 00 00 00 00 01  00 00 00 3C 00 00 00 1C   |...........<....|
00 00 00 0A 00 00 00 32  30 30 30 3A 30 38 3A 30   |.......2000:08:0|
39 20 31 31 3A 31 38 3A  32 32 00 32 30 30 30 3A   |9 11:18:22.2000:|
30 38 3A 30 39 20 31 31  3A 31 38 3A 32 32 00 00   |08:09 11:18:22..|
00 00 00 0A 00 00 00 64  00 00 00 64 00 00 00 02   |.......d...d....|
00 01 00 02 00 04 00 00  00 52 39 38 00 02 00 07   |.........R98....|
00 04 00 00 00 30 7F 31  30 30 00 00 00 00 07 00   |.....0.100......|
...

8B 38 FC B5 92 51 F3 79  D6 8E F1 B2 E0 E4 12 08   |.8...Q.y........|
03 F1 3F CC 55 88 A1 86  DA 15 86 DD 22 8A 31 9C   |..?.U.......".1.|
22 49 85 1D F8 02 97 52  AD 64 7F FF D9 FF C4 01   |"I.....R.d......|
A2 00 00 01 05 01 01 01  01 81 0E 85 0E 01 85 0E   |................|
02 85 0E 03 85 0E 04 B5  0E 05 B9 FE               |............    |

lines 219-269/269 (END)

rather than the normal way, which is this:

$ git diff --binary  HEAD~1  "./dated/sheet0005_older/2006/sheet0620/20000809_1118(3)..JPG"
diff --git a/txt/papersheets/dated/sheet0005_older/2006/sheet0620/20000809_1118(3)..JPG b/txt/papersheets/dated/sheet0005_older/2006/sheet0620/20000809_1118(3)..JPG
index 263d047bf61e2104157d4b1feda5b77a01000847..c78a9a1ddddd0267dc490711eaf1723e38767b09 100644
GIT binary patch
delta 34
lcmX@JK;rmcai;$_n%f22+XWecm<foPftY1`yCCb)e*gxY4e<Z~

delta 4140
zcmb7Hc{o&U8$UCHv5cLv3?`I_-kFJ-8K#jU#=fSKWXVzyvQ2Tazh#UydNm>Y5-PGJ
zp@mUdK4eLjB1=RDsc3x1oA>&<zU%wvyRYka-M{mk`@Wy&{+;`e=d}LZ{yJL<+!)w+
zFB+*I?0FUdjEvL(UH}020bv*%5Q10?1QCeyK)wKi7z_cxAioJ2828_P1mdz=d=lcj
zw_@NB$3eNfAYTmu4{-^|&qEN0|EdEAp$E@cuD=Vxp{jvUmbH&}2u9z})5YK4#~XV8
z-*$|E#d`j>Xob@|jK$(Hn|9I9{jmLE99|2HCE`!(+n&aqK70tHxmOE{H-xZx@P9lW
zi^YN@EP;e2VsJPTjzGfWfo(uW#IL?YprhR0;!+S-`SaJAT{pK*L;_rp!{YH+MB=Z$
zFi;HF7T1J0Ea_Ja4C<9Dng7?;&^j`Ct9K}$7u<T-tjYHq2eP*|z+thl?Ei=k&;F&A
z6ZAz8Tbu=*gnNtIZ*H9TD}J*k{5OvHjdSJwY7(@75_q;=AfN=)Z+x@BreHb{&=B|`
zY>M{Zn*FaeDD?06O|>=whbqDU*361XfY?@hAk^PxC=x(yjSbY;{~WU}=%D|M*#N|U
zA2S&Imnvh>I(&=Y+MHj={`uPfcxd2<fGB{MhX={S%?l!tNIpJZew2hDN<aW5Eha83
zAt$3CFDHXWW0d!*U=-Dr(CFO<RMoLKO-)S&6(X5{*V(&I6A$C#<3kCcqyz<}@H@~u
z@c*}MGy$T#LO?K(jescva8VdS6m}n;4+Gx<C<G*yC_)sV01^69a$fLUWW|Y^-P6R9
zInvKhU(1R=ICv=FX7!fkXx6dTt0k&#Y)b`KIv?;^T505}a_jwBvuX1aopBZ#*!Y}u
z-znL!=}xepUB<J}mm(mf5FAjFB2e)VXRA%R<3N+AkgBtS1B!)}as#sUgXKY&`c8T_
zp_RBUJYyGHS7gWt@Mu$SXd-)Nor!`AXB<)<W3>+Tzs)KV%Pl_=qWv{8!H2!u-IARW
zLq?8UXwWq(e>(Ap^GMNQ9Me4~^wlq;UmjK3$)HXBuvnG5MlZV3Bzt2l!ECp(i*gcU
zxwqy>bgspa;e6<QOD+0&zjlz=;fIQC95;x#m*o-Tk(xhfT3VZ`l+=^q8{^_r<sdlr
z<)ilE+Z<EH{+ID^g1*I_!!F^>OFw#NJ$dyVi2Ot88ccMT&<ksKoOAau+@D?0T;<!M
zJ()~!<7f3Brx#E~@K3&%_UNLEN7Zg{W@cAP&J{$t(?v9feX9`l6mY?tlZq=ivPgZk
zBkd!;N$9aqFvmFyb0&{f|IDyf{n)gZd-vT5g~yR0WMgz@9p_R(hwO#@?=f`6u`iTi
...
z(Ts<g0S%htr2K@R8^Gzs+%<O-6^>pt1*Fd!+G!~e93M&((FohUZ$pbEi~~`zJRVmb
zxJaWDN4w-XZ`2A{Z;sd81GeLsHFYiAdp>RJo~W$GIFY@weVC!D>2!xU!urEx%cYP$
z#^Qsq2{B&8BIUL1pLb&3O2!N;UdJ&NjiTkg!PBkET)~aOjpwi&=wFW;23fdJv=A&>
R2p%njh!)~{D8yaI`8U9_qG|vD

lines 32-82/82 (END)

(I used ... above to redact/snip most output lines)

Here's the patch:

Index: /var/tmp/portage/dev-vcs/git-2.37.3/work/git-2.37.3/diff.c
===================================================================
--- git-2.37.3/diff.c
+++ git-2.37.3/diff.c
@@ -743,7 +743,8 @@ enum diff_symbol {
    DIFF_SYMBOL_NO_LF_EOF,
    DIFF_SYMBOL_CONTEXT_FRAGINFO,
    DIFF_SYMBOL_CONTEXT_MARKER,
-   DIFF_SYMBOL_SEPARATOR
+   DIFF_SYMBOL_SEPARATOR,
+  DIFF_SYMBOL_BINARY_HEXDUMP_DIFF_HEADER,
 };
 /*
  * Flags for content lines:
@@ -1472,6 +1473,9 @@ static void emit_diff_symbol_from_struct
    case DIFF_SYMBOL_BINARY_DIFF_HEADER:
        fprintf(o->file, "%sGIT binary patch\n", diff_line_prefix(o));
        break;
+   case DIFF_SYMBOL_BINARY_HEXDUMP_DIFF_HEADER:
+       fprintf(o->file, "%sGIT binary hexdump (non-reusable, for human eyes only) patch\n", diff_line_prefix(o));
+       break;
    case DIFF_SYMBOL_BINARY_DIFF_HEADER_DELTA:
        fprintf(o->file, "%sdelta %s\n", diff_line_prefix(o), line);
        break;
@@ -3237,10 +3241,11 @@ static void emit_binary_diff_body(struct
                  mmfile_t *one, mmfile_t *two)
 {
    void *cp;
-   void *delta;
+   void *delta,*plaindelta;
+  char *hexdump_ptr;
    void *deflated;
    void *data;
-   unsigned long orig_size;
+   unsigned long orig_size,hexdump_size;
    unsigned long delta_size;
    unsigned long deflate_size;
    unsigned long data_size;
@@ -3249,20 +3254,31 @@ static void emit_binary_diff_body(struct
     * whichever is smaller.
     */
    delta = NULL;
+  plaindelta=NULL;
+  hexdump_ptr=NULL;
+  hexdump_size=0;
    deflated = deflate_it(two->ptr, two->size, &deflate_size);
    if (one->size && two->size) {
-       delta = diff_delta(one->ptr, one->size,
+       plaindelta = diff_delta(one->ptr, one->size,
                   two->ptr, two->size,
                   &delta_size, deflate_size);
-       if (delta) {
-           void *to_free = delta;
+       if (plaindelta) {
+           //void *to_free = plaindelta;
            orig_size = delta_size;
-           delta = deflate_it(delta, delta_size, &delta_size);
-           free(to_free);
+           delta = deflate_it(plaindelta, delta_size, &delta_size);
+           //free(to_free);
+      if (!(o->output_format & DIFF_FORMAT_HEXDUMP)) {
+        free(plaindelta);
+        plaindelta=NULL;
+      }
        }
    }
 
    if (delta && delta_size < deflate_size) {
+    //using delta (z packed aka deflated)
+    // show plaindelta & orig_size
+    hexdump_ptr=plaindelta;
+    hexdump_size=orig_size;
        char *s = xstrfmt("%"PRIuMAX , (uintmax_t)orig_size);
        emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_HEADER_DELTA,
                 s, strlen(s), 0);
@@ -3271,6 +3287,10 @@ static void emit_binary_diff_body(struct
        data = delta;
        data_size = delta_size;
    } else {
+    //using deflated two (the second file, z packed ie. gzipped or similar)
+    // show two->ptr & two->size
+    hexdump_ptr=two->ptr;
+    hexdump_size=two->size;
        char *s = xstrfmt("%lu", two->size);
        emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_HEADER_LITERAL,
                 s, strlen(s), 0);
@@ -3280,6 +3300,64 @@ static void emit_binary_diff_body(struct
        data_size = deflate_size;
    }
 
+  if (o->output_format & DIFF_FORMAT_HEXDUMP) {
+#define LINELEN 16
+#define LINELENPLUSZERO (LINELEN+1)
+#define UNPRINTABLECHAR '.'
+    char line[LINELENPLUSZERO];
+    memset(line,'\0',LINELENPLUSZERO);
+    //line[LINELEN]=0;
+    assert(0 == line[LINELEN]);
+    int i=0;
+    const unsigned long origlen=hexdump_size;
+    for (; i<origlen; i++) {
+      const char c=hexdump_ptr[i];
+      const int mod=i%16;
+      if (isprint(c)) {
+        line[mod]=c;
+      } else {
+        line[mod]=UNPRINTABLECHAR;
+      }
+      fprintf(o->file,"%02X ", c & 0xff);
+      if (i>0){
+        if ((i+1) % 8==0) {
+          fprintf(o->file," ");
+        }
+        if ((i+1) % 16==0) {
+          assert(0 == line[16]);
+          fprintf(o->file," |%s|\n",line);
+        }
+      }
+    }
+    int weat=i%16;
+    if (weat != 0) {
+      line[weat]=0;
+      if (weat<8){
+        fprintf(o->file," ");
+      }
+      for (int i=weat;i<16;i++) {
+        fprintf(o->file,"   ");
+      }
+      fprintf(o->file," ");
+      fprintf(o->file," |%s",line);
+      for (int i=weat;i<16;i++) {
+        fprintf(o->file," ");
+      }
+      fprintf(o->file,"|\n");
+    }
+    //for (int i=0; i<origlen; i++) {
+    //  printf("%02X ",fp[i] & 0xff);
+    //}
+    //fprintf(o->file,"\n");//this is FOOTER below
+    //emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_BODY,
+    //      line, len, 0);
+
+    if (plaindelta) {
+      free(plaindelta);
+      plaindelta=NULL;
+    }
+  } else { //not re-indenting the below, for an easier-on-the-eyes patch.
+
    /* emit data encoded in base85 */
    cp = data;
    while (data_size) {
@@ -3301,6 +3379,7 @@ static void emit_binary_diff_body(struct
        emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_BODY,
                 line, len, 0);
    }
+  }
    emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_FOOTER, NULL, 0, 0);
    free(data);
 }
@@ -3308,7 +3387,11 @@ static void emit_binary_diff_body(struct
 static void emit_binary_diff(struct diff_options *o,
                 mmfile_t *one, mmfile_t *two)
 {
-   emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_HEADER, NULL, 0, 0);
+  if (o->output_format & DIFF_FORMAT_HEXDUMP) {
+    emit_diff_symbol(o, DIFF_SYMBOL_BINARY_HEXDUMP_DIFF_HEADER, NULL, 0, 0);
+  } else {
+    emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_HEADER, NULL, 0, 0);
+  }
    emit_binary_diff_body(o, one, two);
    emit_binary_diff_body(o, two, one);
 }
@@ -4710,7 +4793,7 @@ void diff_setup_done(struct diff_options
                      DIFF_FORMAT_NAME_STATUS |
                      DIFF_FORMAT_CHECKDIFF |
                      DIFF_FORMAT_NO_OUTPUT))
-       options->output_format &= ~(DIFF_FORMAT_RAW |
+       options->output_format &= ~(DIFF_FORMAT_RAW | DIFF_FORMAT_HEXDUMP | //this clears these bits
                        DIFF_FORMAT_NUMSTAT |
                        DIFF_FORMAT_DIFFSTAT |
                        DIFF_FORMAT_SHORTSTAT |
@@ -5389,6 +5472,9 @@ static void prep_parse_options(struct di
        OPT_BIT_F(0, "raw", &options->output_format,
              N_("generate the diff in raw format"),
              DIFF_FORMAT_RAW, PARSE_OPT_NONEG),
+       OPT_BIT_F(0, "hexdump", &options->output_format,
+             N_("generate the diff in hexdump format for human eyes only(ie. can't git apply it!)"),
+             DIFF_FORMAT_PATCH | DIFF_FORMAT_HEXDUMP, PARSE_OPT_NONEG),
        OPT_BITOP(0, "patch-with-raw", &options->output_format,
              N_("synonym for '-p --raw'"),
              DIFF_FORMAT_PATCH | DIFF_FORMAT_RAW,
@@ -6755,7 +6841,7 @@ void diffcore_std(struct diff_options *o
 {
    int output_formats_to_prefetch = DIFF_FORMAT_DIFFSTAT |
        DIFF_FORMAT_NUMSTAT |
-       DIFF_FORMAT_PATCH |
+       DIFF_FORMAT_PATCH | //DIFF_FORMAT_HEXDUMP | //we don't use hexdump here because it implies DIFF_FORMAT_PATCH.
        DIFF_FORMAT_SHORTSTAT |
        DIFF_FORMAT_DIRSTAT;
 
Index: /var/tmp/portage/dev-vcs/git-2.37.3/work/git-2.37.3/diff.h
===================================================================
--- git-2.37.3/diff.h
+++ git-2.37.3/diff.h
@@ -103,6 +103,7 @@ typedef struct strbuf *(*diff_prefix_fn_
 #define DIFF_FORMAT_PATCH  0x0010
 #define DIFF_FORMAT_SHORTSTAT  0x0020
 #define DIFF_FORMAT_DIRSTAT    0x0040
+#define DIFF_FORMAT_HEXDUMP    0x0080
 
 /* These override all above */
 #define DIFF_FORMAT_NAME   0x0100
$ git diff -h
usage: git diff --no-index [<options>] <path> <path>

Diff output format options
    -p, --patch           generate patch
    -s, --no-patch        suppress diff output
    -u                    generate patch
    -U, --unified[=<n>]   generate diffs with <n> lines context
    -W, --function-context
                          generate diffs with <n> lines context
    --raw                 generate the diff in raw format
    --hexdump             generate the diff in hexdump format for human eyes only(ie. can't git apply it!)
    --patch-with-raw      synonym for '-p --raw'
    --patch-with-stat     synonym for '-p --stat'

It doesn't seem very helpful to force text files to be seen as binary for git diff purposes:

$ cat .gitattributes                                                                                                                                              
*.log -diff

That is needed, else it will be force seen as text even if --binary is specified. Seen man 5 gitattributes section Marking files as binary.

$ GIT_PAGER=cat

ie. tell git to not use less.

$ git diff
diff --git a/genkernel-boot.log b/genkernel-boot.log
index 85ebc17..3d89503 100644
Binary files a/genkernel-boot.log and b/genkernel-boot.log differ
$ git diff --binary
diff --git a/genkernel-boot.log b/genkernel-boot.log
index 85ebc177502e392a41183f9baa730e01180b647d..3d89503b6824c39d7c70f446aa2fe1d400ab72f0 100644
GIT binary patch
delta 49
zcmV-10M7rgi2;U*0kFdsv-%c+6tlD|!V8m7LJpH20tb`eLI{&8LlFcZb75<f(Gf1Q
HkT)O==e`m1

delta 42
wcmZqcWZVEmhsBtSD|06^3Yly^EY>K(nvt2DpSM{+`y2OU0WPV{Y32&N08T9qbN~PV

This is why I said it doesn't seem useful, because what is this?:

$ git diff --binary --hexdump
diff --git a/genkernel-boot.log b/genkernel-boot.log
index 85ebc177502e392a41183f9baa730e01180b647d..3d89503b6824c39d7c70f446aa2fe1d400ab72f0 100644
GIT binary hexdump (non-reusable, for human eyes only) patch
delta 49
B0 89 01 86 89 01 B0 C3  16 B3 FA 16 81 14 B3 B4   |................|
2B C2 0B 93 50 42 0E 93  1E 02 07 93 E0 42 08 93   |+...PB.......B..|
2A 43 11 04 20 73 61 6B  93 D1 11 2E B3 90 37 20   |*C.. sak......7 |
0D                                                 |.               |

delta 42
86 89 01 B0 89 01 B0 C3  16 03 73 79 6D 93 01 12   |..........sym...|
34 B3 C3 16 81 14 05 68  69 63 6F 6E B3 10 2B F6   |4......hicon..+.|
0B 93 10 0A 1A B3 66 37  20 0D                     |......f7 .      |

$ git diff --text
diff --git a/genkernel-boot.log b/genkernel-boot.log
index 85ebc17..3d89503 100644
--- a/genkernel-boot.log
+++ b/genkernel-boot.log
@@ -95,7 +95,6 @@
 [2020-11-23 14:52:20] Failed (1): 'modprobe u14-34f'
 [2020-11-23 14:52:20] Failed (1): 'modprobe ultrastor'
 [2020-11-23 14:52:20] Failed (1): 'modprobe wd7000'
-[2020-11-23 14:52:20] Failed (1): 'modprobe sym53c8xx'
 [2020-11-23 14:52:20] Failed (1): 'modprobe dmx3191d'
 [2020-11-23 14:52:20] Failed (1): 'modprobe imm'
 [2020-11-23 14:52:20] Failed (1): 'modprobe in2000'
@@ -190,7 +189,6 @@
 [2020-11-23 14:52:20] Failed (1): 'modprobe hid-apple'
 [2020-11-23 14:52:20] Failed (1): 'modprobe hid-belkin'
 [2020-11-23 14:52:20] Failed (1): 'modprobe hid-cherry'
-[2020-11-23 14:52:20] Failed (1): 'modprobe hid-chicony'
 [2020-11-23 14:52:20] Failed (1): 'modprobe hid-cypress'
 [2020-11-23 14:52:20] Failed (1): 'modprobe hid-dummy'
 [2020-11-23 14:52:20] Failed (1): 'modprobe hid-ezkey'
@@ -244,6 +242,7 @@
 [2020-11-23 14:52:20] Failed (1): 'modprobe btrfs'
 [2020-11-23 14:52:20] Failed (1): 'modprobe reiserfs'
 [2020-11-23 14:52:20] Failed (1): 'modprobe jfs'
+[2020-11-23 14:52:21] Executed: 'mount -o move /sys /newroot/sys' sak
 [2020-11-23 14:52:20] Failed (1): 'modprobe nfs'
 [2020-11-23 14:52:20] Failed (1): 'modprobe xfs'
 [2020-11-23 14:52:20] Failed (1): 'modprobe zfs'
-1

The above are comprehensive ways to do so.. however, if you just need to do it for a few files, the following method is what I use:

git checkout HEAD -- /path/to/file > ~/file
vimdiff ~/file /path/to/file

Here I am using vimdiff but you can use any other tool. The above can be also combined into a small script if you need to do this over and over again.

1
  • 1
    This appears to have discarded the changes to my file (and created an empty file where I wanted the committed version to be).
    – Erhannis
    Dec 6, 2018 at 2:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .