6 static void check(int error
, const char *message
)
9 fprintf(stderr
, "%s (%d)\n", message
, error
);
14 static int resolve_to_tree(
15 git_repository
*repo
, const char *identifier
, git_tree
**tree
)
18 git_object
*obj
= NULL
;
20 if (git_revparse_single(&obj
, repo
, identifier
) < 0)
23 switch (git_object_type(obj
)) {
25 *tree
= (git_tree
*)obj
;
28 err
= git_commit_tree(tree
, (git_commit
*)obj
);
42 "\033[32m", /* green */
47 const git_diff_delta
*delta
,
48 const git_diff_range
*range
,
54 int *last_color
= data
, color
= 0;
56 (void)delta
; (void)range
; (void)line_len
;
58 if (*last_color
>= 0) {
60 case GIT_DIFF_LINE_ADDITION
: color
= 3; break;
61 case GIT_DIFF_LINE_DELETION
: color
= 2; break;
62 case GIT_DIFF_LINE_ADD_EOFNL
: color
= 3; break;
63 case GIT_DIFF_LINE_DEL_EOFNL
: color
= 2; break;
64 case GIT_DIFF_LINE_FILE_HDR
: color
= 1; break;
65 case GIT_DIFF_LINE_HUNK_HDR
: color
= 4; break;
68 if (color
!= *last_color
) {
69 if (*last_color
== 1 || color
== 1)
70 fputs(colors
[0], stdout
);
71 fputs(colors
[color
], stdout
);
80 static int check_uint16_param(const char *arg
, const char *pattern
, uint16_t *val
)
82 size_t len
= strlen(pattern
);
85 if (strncmp(arg
, pattern
, len
))
87 strval
= strtoul(arg
+ len
, &endptr
, 0);
94 static int check_str_param(const char *arg
, const char *pattern
, const char **val
)
96 size_t len
= strlen(pattern
);
97 if (strncmp(arg
, pattern
, len
))
99 *val
= (const char *)(arg
+ len
);
103 static void usage(const char *message
, const char *arg
)
106 fprintf(stderr
, "%s: %s\n", message
, arg
);
108 fprintf(stderr
, "%s\n", message
);
109 fprintf(stderr
, "usage: diff [<tree-oid> [<tree-oid>]]\n");
113 int main(int argc
, char *argv
[])
115 git_repository
*repo
= NULL
;
116 git_tree
*t1
= NULL
, *t2
= NULL
;
117 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
119 int i
, color
= -1, compact
= 0, cached
= 0;
120 char *a
, *dir
= ".", *treeish1
= NULL
, *treeish2
= NULL
;
122 /* parse arguments as copied from git-diff */
124 for (i
= 1; i
< argc
; ++i
) {
128 if (treeish1
== NULL
)
130 else if (treeish2
== NULL
)
133 usage("Only one or two tree identifiers can be provided", NULL
);
135 else if (!strcmp(a
, "-p") || !strcmp(a
, "-u") ||
136 !strcmp(a
, "--patch"))
138 else if (!strcmp(a
, "--cached"))
140 else if (!strcmp(a
, "--name-status"))
142 else if (!strcmp(a
, "--color"))
144 else if (!strcmp(a
, "--no-color"))
146 else if (!strcmp(a
, "-R"))
147 opts
.flags
|= GIT_DIFF_REVERSE
;
148 else if (!strcmp(a
, "-a") || !strcmp(a
, "--text"))
149 opts
.flags
|= GIT_DIFF_FORCE_TEXT
;
150 else if (!strcmp(a
, "--ignore-space-at-eol"))
151 opts
.flags
|= GIT_DIFF_IGNORE_WHITESPACE_EOL
;
152 else if (!strcmp(a
, "-b") || !strcmp(a
, "--ignore-space-change"))
153 opts
.flags
|= GIT_DIFF_IGNORE_WHITESPACE_CHANGE
;
154 else if (!strcmp(a
, "-w") || !strcmp(a
, "--ignore-all-space"))
155 opts
.flags
|= GIT_DIFF_IGNORE_WHITESPACE
;
156 else if (!strcmp(a
, "--ignored"))
157 opts
.flags
|= GIT_DIFF_INCLUDE_IGNORED
;
158 else if (!strcmp(a
, "--untracked"))
159 opts
.flags
|= GIT_DIFF_INCLUDE_UNTRACKED
;
160 else if (!check_uint16_param(a
, "-U", &opts
.context_lines
) &&
161 !check_uint16_param(a
, "--unified=", &opts
.context_lines
) &&
162 !check_uint16_param(a
, "--inter-hunk-context=",
163 &opts
.interhunk_lines
) &&
164 !check_str_param(a
, "--src-prefix=", &opts
.old_prefix
) &&
165 !check_str_param(a
, "--dst-prefix=", &opts
.new_prefix
))
166 usage("Unknown arg", a
);
171 check(git_repository_open_ext(&repo
, dir
, 0, NULL
),
172 "Could not open repository");
175 check(resolve_to_tree(repo
, treeish1
, &t1
), "Looking up first tree");
177 check(resolve_to_tree(repo
, treeish2
, &t2
), "Looking up second tree");
180 /* <sha1> --cached */
186 check(git_diff_tree_to_tree(&diff
, repo
, t1
, t2
, &opts
), "Diff");
187 else if (t1
&& cached
)
188 check(git_diff_tree_to_index(&diff
, repo
, t1
, NULL
, &opts
), "Diff");
190 git_diff_list
*diff2
;
191 check(git_diff_tree_to_index(&diff
, repo
, t1
, NULL
, &opts
), "Diff");
192 check(git_diff_index_to_workdir(&diff2
, repo
, NULL
, &opts
), "Diff");
193 check(git_diff_merge(diff
, diff2
), "Merge diffs");
194 git_diff_list_free(diff2
);
197 check(resolve_to_tree(repo
, "HEAD", &t1
), "looking up HEAD");
198 check(git_diff_tree_to_index(&diff
, repo
, t1
, NULL
, &opts
), "Diff");
201 check(git_diff_index_to_workdir(&diff
, repo
, NULL
, &opts
), "Diff");
204 fputs(colors
[0], stdout
);
207 check(git_diff_print_compact(diff
, printer
, &color
), "Displaying diff");
209 check(git_diff_print_patch(diff
, printer
, &color
), "Displaying diff");
212 fputs(colors
[0], stdout
);
214 git_diff_list_free(diff
);
217 git_repository_free(repo
);