@@ -32,6 +32,13 @@ static int read_directory(const char *path, struct string_list *list)
3232 return 0 ;
3333}
3434
35+ /*
36+ * This should be "(standard input)" or something, but it will
37+ * probably expose many more breakages in the way no-index code
38+ * is bolted onto the diff callchain.
39+ */
40+ static const char file_from_standard_input [] = "-" ;
41+
3542static int get_mode (const char * path , int * mode )
3643{
3744 struct stat st ;
@@ -42,7 +49,7 @@ static int get_mode(const char *path, int *mode)
4249 else if (!strcasecmp (path , "nul "))
4350 * mode = 0 ;
4451#endif
45- else if (! strcmp ( path , " - ") )
52+ else if (path == file_from_standard_input )
4653 * mode = create_ce_mode (0666 );
4754 else if (lstat (path , & st ))
4855 return error ("Could not access '%s '", path);
@@ -51,6 +58,36 @@ static int get_mode(const char *path, int *mode)
5158 return 0 ;
5259}
5360
61+ static int populate_from_stdin (struct diff_filespec * s )
62+ {
63+ struct strbuf buf = STRBUF_INIT ;
64+ size_t size = 0 ;
65+
66+ if (strbuf_read (& buf , 0 , 0 ) < 0 )
67+ return error ("error while reading from stdin %s" ,
68+ strerror (errno ));
69+
70+ s -> should_munmap = 0 ;
71+ s -> data = strbuf_detach (& buf , & size );
72+ s -> size = size ;
73+ s -> should_free = 1 ;
74+ s -> is_stdin = 1 ;
75+ return 0 ;
76+ }
77+
78+ static struct diff_filespec * noindex_filespec (const char * name , int mode )
79+ {
80+ struct diff_filespec * s ;
81+
82+ if (!name )
83+ name = "/dev/null" ;
84+ s = alloc_filespec (name );
85+ fill_filespec (s , null_sha1 , mode );
86+ if (name == file_from_standard_input )
87+ populate_from_stdin (s );
88+ return s ;
89+ }
90+
5491static int queue_diff (struct diff_options * o ,
5592 const char * name1 , const char * name2 )
5693{
@@ -137,15 +174,8 @@ static int queue_diff(struct diff_options *o,
137174 tmp_c = name1 ; name1 = name2 ; name2 = tmp_c ;
138175 }
139176
140- if (!name1 )
141- name1 = "/dev/null" ;
142- if (!name2 )
143- name2 = "/dev/null" ;
144- d1 = alloc_filespec (name1 );
145- d2 = alloc_filespec (name2 );
146- fill_filespec (d1 , null_sha1 , mode1 );
147- fill_filespec (d2 , null_sha1 , mode2 );
148-
177+ d1 = noindex_filespec (name1 , mode1 );
178+ d2 = noindex_filespec (name2 , mode2 );
149179 diff_queue (& diff_queued_diff , d1 , d2 );
150180 return 0 ;
151181 }
@@ -155,9 +185,10 @@ void diff_no_index(struct rev_info *revs,
155185 int argc , const char * * argv ,
156186 int nongit , const char * prefix )
157187{
158- int i ;
188+ int i , prefixlen ;
159189 int no_index = 0 ;
160190 unsigned options = 0 ;
191+ const char * paths [2 ];
161192
162193 /* Were we asked to do --no-index explicitly? */
163194 for (i = 1 ; i < argc ; i ++ ) {
@@ -207,26 +238,19 @@ void diff_no_index(struct rev_info *revs,
207238 }
208239 }
209240
210- if (prefix ) {
211- int len = strlen (prefix );
212- const char * paths [3 ];
213- memset (paths , 0 , sizeof (paths ));
214-
215- for (i = 0 ; i < 2 ; i ++ ) {
216- const char * p = argv [argc - 2 + i ];
241+ prefixlen = prefix ? strlen (prefix ) : 0 ;
242+ for (i = 0 ; i < 2 ; i ++ ) {
243+ const char * p = argv [argc - 2 + i ];
244+ if (!strcmp (p , "-" ))
217245 /*
218- * stdin should be spelled as '-' ; if you have
219- * path that is '-' , spell it as ./-.
246+ * stdin should be spelled as "-" ; if you have
247+ * path that is "-" , spell it as " ./-" .
220248 */
221- p = (strcmp (p , "-" )
222- ? xstrdup (prefix_filename (prefix , len , p ))
223- : p );
224- paths [i ] = p ;
225- }
226- diff_tree_setup_paths (paths , & revs -> diffopt );
249+ p = file_from_standard_input ;
250+ else if (prefixlen )
251+ p = xstrdup (prefix_filename (prefix , prefixlen , p ));
252+ paths [i ] = p ;
227253 }
228- else
229- diff_tree_setup_paths (argv + argc - 2 , & revs -> diffopt );
230254 revs -> diffopt .skip_stat_unmatch = 1 ;
231255 if (!revs -> diffopt .output_format )
232256 revs -> diffopt .output_format = DIFF_FORMAT_PATCH ;
@@ -240,8 +264,7 @@ void diff_no_index(struct rev_info *revs,
240264 setup_diff_pager (& revs -> diffopt );
241265 DIFF_OPT_SET (& revs -> diffopt , EXIT_WITH_STATUS );
242266
243- if (queue_diff (& revs -> diffopt , revs -> diffopt .pathspec .raw [0 ],
244- revs -> diffopt .pathspec .raw [1 ]))
267+ if (queue_diff (& revs -> diffopt , paths [0 ], paths [1 ]))
245268 exit (1 );
246269 diff_set_mnemonic_prefix (& revs -> diffopt , "1/" , "2/" );
247270 diffcore_std (& revs -> diffopt );
0 commit comments