4 static char *diff_cmd
= "diff -L 'k/%s' -L 'l/%s' ";
5 static char *diff_opts
= "-p -u";
6 static char *diff_arg_forward
= " - '%s'";
7 static char *diff_arg_reverse
= " '%s' -";
9 void prepare_diff_cmd(void)
12 * Default values above are meant to match the
13 * Linux kernel development style. Examples of
14 * alternative styles you can specify via environment
17 * GIT_DIFF_CMD="diff -L '%s' -L '%s'"
20 diff_cmd
= getenv("GIT_DIFF_CMD") ? : diff_cmd
;
21 diff_opts
= getenv("GIT_DIFF_OPTS") ? : diff_opts
;
24 /* Help to copy the thing properly quoted for the shell safety.
25 * any single quote is replaced with '\'', and the caller is
26 * expected to enclose the result within a single quote pair.
29 * original sq_expand result
30 * name ==> name ==> 'name'
31 * a b ==> a b ==> 'a b'
32 * a'b ==> a'\''b ==> 'a'\''b'
34 static char *sq_expand(const char *src
)
36 static char *buf
= NULL
;
41 /* count bytes needed to store the quoted string. */
42 for (cnt
= 1, cp
= src
; *cp
; cnt
++, cp
++)
46 if (! (buf
= malloc(cnt
)))
49 while ((c
= *src
++)) {
53 bp
= strcpy(bp
, "'\\''");
61 void show_differences(const char *name
, /* filename on the filesystem */
62 const char *label
, /* diff label to use */
63 void *old_contents
, /* contents in core */
64 unsigned long long old_size
, /* size in core */
65 int reverse
/* 0: diff core file
69 char *name_sq
= sq_expand(name
);
70 const char *label_sq
= (name
!= label
) ? sq_expand(label
) : name_sq
;
71 char *diff_arg
= reverse
? diff_arg_reverse
: diff_arg_forward
;
72 int cmd_size
= strlen(name_sq
) + strlen(label_sq
) * 2 +
73 strlen(diff_cmd
) + strlen(diff_opts
) + strlen(diff_arg
);
74 char *cmd
= malloc(cmd_size
);
78 next_at
= snprintf(cmd
, cmd_size
, diff_cmd
, label_sq
, label_sq
);
79 next_at
+= snprintf(cmd
+next_at
, cmd_size
-next_at
, "%s", diff_opts
);
80 next_at
+= snprintf(cmd
+next_at
, cmd_size
-next_at
, diff_arg
, name_sq
);
83 fwrite(old_contents
, old_size
, 1, f
);
85 if (label_sq
!= name_sq
)
86 free((void*)label_sq
); /* constness */
91 void show_diff_empty(const unsigned char *sha1
,
96 unsigned long int size
;
97 unsigned char type
[20];
99 old
= read_sha1_file(sha1
, type
, &size
);
101 error("unable to read blob object for %s (%s)", name
,
105 show_differences("/dev/null", name
, old
, size
, reverse
);