@@ -52,6 +52,7 @@ struct opts {
5252 git_diff_options diffopts ;
5353 git_diff_find_options findopts ;
5454 int color ;
55+ int no_index ;
5556 int cache ;
5657 int output ;
5758 git_diff_format_t format ;
@@ -66,14 +67,16 @@ static void parse_opts(struct opts *o, int argc, char *argv[]);
6667static int color_printer (
6768 const git_diff_delta * , const git_diff_hunk * , const git_diff_line * , void * );
6869static void diff_print_stats (git_diff * diff , struct opts * o );
70+ static void compute_diff_no_index (git_diff * * diff , struct opts * o );
6971
7072int lg2_diff (git_repository * repo , int argc , char * argv [])
7173{
7274 git_tree * t1 = NULL , * t2 = NULL ;
7375 git_diff * diff ;
76+
7477 struct opts o = {
7578 GIT_DIFF_OPTIONS_INIT , GIT_DIFF_FIND_OPTIONS_INIT ,
76- -1 , 0 , 0 , GIT_DIFF_FORMAT_PATCH , NULL , NULL , "."
79+ -1 , -1 , 0 , 0 , GIT_DIFF_FORMAT_PATCH , NULL , NULL , "."
7780 };
7881
7982 parse_opts (& o , argc , argv );
@@ -86,49 +89,54 @@ int lg2_diff(git_repository *repo, int argc, char *argv[])
8689 * * <sha1>
8790 * * --cached
8891 * * --nocache (don't use index data in diff at all)
92+ * * --no-index <file1> <file2>
8993 * * nothing
9094 *
9195 * Currently ranged arguments like <sha1>..<sha2> and <sha1>...<sha2>
9296 * are not supported in this example
9397 */
9498
95- if (o .treeish1 )
96- treeish_to_tree (& t1 , repo , o .treeish1 );
97- if (o .treeish2 )
98- treeish_to_tree (& t2 , repo , o .treeish2 );
99-
100- if (t1 && t2 )
101- check_lg2 (
102- git_diff_tree_to_tree (& diff , repo , t1 , t2 , & o .diffopts ),
103- "diff trees" , NULL );
104- else if (o .cache != CACHE_NORMAL ) {
105- if (!t1 )
106- treeish_to_tree (& t1 , repo , "HEAD" );
99+ if (o .no_index >= 0 ) {
100+ compute_diff_no_index (& diff , & o );
101+ } else {
102+ if (o .treeish1 )
103+ treeish_to_tree (& t1 , repo , o .treeish1 );
104+ if (o .treeish2 )
105+ treeish_to_tree (& t2 , repo , o .treeish2 );
107106
108- if (o .cache == CACHE_NONE )
107+ if (t1 && t2 )
108+ check_lg2 (
109+ git_diff_tree_to_tree (& diff , repo , t1 , t2 , & o .diffopts ),
110+ "diff trees" , NULL );
111+ else if (o .cache != CACHE_NORMAL ) {
112+ if (!t1 )
113+ treeish_to_tree (& t1 , repo , "HEAD" );
114+
115+ if (o .cache == CACHE_NONE )
116+ check_lg2 (
117+ git_diff_tree_to_workdir (& diff , repo , t1 , & o .diffopts ),
118+ "diff tree to working directory" , NULL );
119+ else
120+ check_lg2 (
121+ git_diff_tree_to_index (& diff , repo , t1 , NULL , & o .diffopts ),
122+ "diff tree to index" , NULL );
123+ }
124+ else if (t1 )
109125 check_lg2 (
110- git_diff_tree_to_workdir (& diff , repo , t1 , & o .diffopts ),
126+ git_diff_tree_to_workdir_with_index (& diff , repo , t1 , & o .diffopts ),
111127 "diff tree to working directory" , NULL );
112128 else
113129 check_lg2 (
114- git_diff_tree_to_index (& diff , repo , t1 , NULL , & o .diffopts ),
115- "diff tree to index" , NULL );
116- }
117- else if (t1 )
118- check_lg2 (
119- git_diff_tree_to_workdir_with_index (& diff , repo , t1 , & o .diffopts ),
120- "diff tree to working directory" , NULL );
121- else
122- check_lg2 (
123- git_diff_index_to_workdir (& diff , repo , NULL , & o .diffopts ),
124- "diff index to working directory" , NULL );
130+ git_diff_index_to_workdir (& diff , repo , NULL , & o .diffopts ),
131+ "diff index to working directory" , NULL );
125132
126- /** Apply rename and copy detection if requested. */
133+ /** Apply rename and copy detection if requested. */
127134
128- if ((o .findopts .flags & GIT_DIFF_FIND_ALL ) != 0 )
129- check_lg2 (
130- git_diff_find_similar (diff , & o .findopts ),
131- "finding renames and copies" , NULL );
135+ if ((o .findopts .flags & GIT_DIFF_FIND_ALL ) != 0 )
136+ check_lg2 (
137+ git_diff_find_similar (diff , & o .findopts ),
138+ "finding renames and copies" , NULL );
139+ }
132140
133141 /** Generate simple output using libgit2 display helper. */
134142
@@ -158,6 +166,38 @@ int lg2_diff(git_repository *repo, int argc, char *argv[])
158166 return 0 ;
159167}
160168
169+ static void compute_diff_no_index (git_diff * * diff , struct opts * o ) {
170+ git_patch * patch = NULL ;
171+ char * file1_str = NULL ;
172+ char * file2_str = NULL ;
173+ git_buf buf = {0 };
174+
175+ if (!o -> treeish1 || !o -> treeish2 ) {
176+ usage ("two files should be provided as arguments" , NULL );
177+ }
178+ file1_str = read_file (o -> treeish1 );
179+ if (file1_str == NULL ) {
180+ usage ("file cannot be read" , o -> treeish1 );
181+ }
182+ file2_str = read_file (o -> treeish2 );
183+ if (file2_str == NULL ) {
184+ usage ("file cannot be read" , o -> treeish2 );
185+ }
186+ check_lg2 (
187+ git_patch_from_buffers (& patch , file1_str , strlen (file1_str ), o -> treeish1 , file2_str , strlen (file2_str ), o -> treeish2 , & o -> diffopts ),
188+ "patch buffers" , NULL );
189+ check_lg2 (
190+ git_patch_to_buf (& buf , patch ),
191+ "patch to buf" , NULL );
192+ check_lg2 (
193+ git_diff_from_buffer (diff , buf .ptr , buf .size ),
194+ "diff from patch" , NULL );
195+ git_patch_free (patch );
196+ git_buf_dispose (& buf );
197+ free (file1_str );
198+ free (file2_str );
199+ }
200+
161201static void usage (const char * message , const char * arg )
162202{
163203 if (message && arg )
@@ -223,9 +263,10 @@ static void parse_opts(struct opts *o, int argc, char *argv[])
223263 o -> output |= OUTPUT_DIFF ;
224264 o -> format = GIT_DIFF_FORMAT_PATCH ;
225265 }
226- else if (!strcmp (a , "--cached" ))
266+ else if (!strcmp (a , "--cached" )) {
227267 o -> cache = CACHE_ONLY ;
228- else if (!strcmp (a , "--nocache" ))
268+ if (o -> no_index >= 0 ) usage ("--cached and --no-index are incompatible" , NULL );
269+ } else if (!strcmp (a , "--nocache" ))
229270 o -> cache = CACHE_NONE ;
230271 else if (!strcmp (a , "--name-only" ) || !strcmp (a , "--format=name" ))
231272 o -> format = GIT_DIFF_FORMAT_NAME_ONLY ;
@@ -238,7 +279,10 @@ static void parse_opts(struct opts *o, int argc, char *argv[])
238279 o -> format = GIT_DIFF_FORMAT_RAW ;
239280 o -> diffopts .id_abbrev = 40 ;
240281 }
241- else if (!strcmp (a , "--color" ))
282+ else if (!strcmp (a , "--no-index" )) {
283+ o -> no_index = 0 ;
284+ if (o -> cache == CACHE_ONLY ) usage ("--cached and --no-index are incompatible" , NULL );
285+ } else if (!strcmp (a , "--color" ))
242286 o -> color = 0 ;
243287 else if (!strcmp (a , "--no-color" ))
244288 o -> color = -1 ;
0 commit comments