88
99static int detect_rename = 0 ;
1010static int diff_score_opt = 0 ;
11- static int generate_patch = 1 ;
1211static const char * pickaxe = NULL ;
12+ static int diff_output_style = DIFF_FORMAT_PATCH ;
13+ static int line_termination = '\n' ;
14+ static int inter_name_termination = '\t' ;
1315
14- static int parse_oneside_change (const char * cp , int * mode ,
15- unsigned char * sha1 , char * path )
16+ static int parse_diff_raw (char * buf1 , char * buf2 , char * buf3 )
1617{
17- int ch , m ;
18+ char old_path [PATH_MAX ];
19+ unsigned char old_sha1 [20 ], new_sha1 [20 ];
20+ char * ep ;
21+ char * cp = buf1 ;
22+ int ch , old_mode , new_mode ;
1823
19- m = 0 ;
20- while ((ch = * cp ) && '0' <= ch && ch <= '7' ) {
21- m = (m << 3 ) | (ch - '0' );
24+ old_mode = new_mode = 0 ;
25+ while ((ch = * cp ) && ('0' <= ch && ch <= '7' )) {
26+ old_mode = (old_mode << 3 ) | (ch - '0' );
27+ cp ++ ;
28+ }
29+ if (* cp ++ != ' ' )
30+ return -1 ;
31+ while ((ch = * cp ) && ('0' <= ch && ch <= '7' )) {
32+ new_mode = (new_mode << 3 ) | (ch - '0' );
2233 cp ++ ;
2334 }
24- * mode = m ;
25- if (strncmp (cp , "\tblob\t" , 6 ) && strncmp (cp , " blob " , 6 ) &&
26- strncmp (cp , "\ttree\t" , 6 ) && strncmp (cp , " tree " , 6 ))
35+ if (* cp ++ != ' ' )
2736 return -1 ;
28- cp += 6 ;
29- if (get_sha1_hex (cp , sha1 ))
37+ if (get_sha1_hex (cp , old_sha1 ))
3038 return -1 ;
3139 cp += 40 ;
32- if (( * cp != '\t' ) && * cp != ' ' )
40+ if (* cp ++ != ' ' )
3341 return -1 ;
34- strcpy (path , ++ cp );
35- return 0 ;
36- }
37-
38- static int parse_diff_raw_output (const char * buf )
39- {
40- char path [PATH_MAX ];
41- unsigned char old_sha1 [20 ], new_sha1 [20 ];
42- const char * cp = buf ;
43- int ch , old_mode , new_mode ;
44-
45- switch (* cp ++ ) {
46- case 'U' :
47- diff_unmerge (cp + 1 );
48- break ;
49- case '+' :
50- if (parse_oneside_change (cp , & new_mode , new_sha1 , path ))
51- return -1 ;
52- diff_addremove ('+' , new_mode , new_sha1 , path , NULL );
53- break ;
54- case '-' :
55- if (parse_oneside_change (cp , & old_mode , old_sha1 , path ))
56- return -1 ;
57- diff_addremove ('-' , old_mode , old_sha1 , path , NULL );
58- break ;
59- case '*' :
60- old_mode = new_mode = 0 ;
61- while ((ch = * cp ) && ('0' <= ch && ch <= '7' )) {
62- old_mode = (old_mode << 3 ) | (ch - '0' );
63- cp ++ ;
64- }
65- if (strncmp (cp , "->" , 2 ))
66- return -1 ;
67- cp += 2 ;
68- while ((ch = * cp ) && ('0' <= ch && ch <= '7' )) {
69- new_mode = (new_mode << 3 ) | (ch - '0' );
70- cp ++ ;
71- }
72- if (strncmp (cp , "\tblob\t" , 6 ) && strncmp (cp , " blob " , 6 ) &&
73- strncmp (cp , "\ttree\t" , 6 ) && strncmp (cp , " tree " , 6 ))
74- return -1 ;
75- cp += 6 ;
76- if (get_sha1_hex (cp , old_sha1 ))
77- return -1 ;
78- cp += 40 ;
79- if (strncmp (cp , "->" , 2 ))
80- return -1 ;
81- cp += 2 ;
82- if (get_sha1_hex (cp , new_sha1 ))
83- return -1 ;
84- cp += 40 ;
85- if ((* cp != '\t' ) && * cp != ' ' )
86- return -1 ;
87- strcpy (path , ++ cp );
88- diff_change (old_mode , new_mode , old_sha1 , new_sha1 , path , NULL );
89- break ;
90- default :
42+ if (get_sha1_hex (cp , new_sha1 ))
9143 return -1 ;
92- }
44+ cp += 40 ;
45+ if (* cp ++ != inter_name_termination )
46+ return -1 ;
47+ if (buf2 )
48+ cp = buf2 ;
49+ ep = strchr (cp , inter_name_termination );
50+ if (!ep )
51+ return -1 ;
52+ * ep ++ = 0 ;
53+ strcpy (old_path , cp );
54+ diff_guif (old_mode , new_mode , old_sha1 , new_sha1 ,
55+ old_path , buf3 ? buf3 : ep );
9356 return 0 ;
9457}
9558
9659static const char * diff_helper_usage =
9760 "git-diff-helper [-z] [-R] [-M] [-C] [-S<string>] paths..." ;
9861
9962int main (int ac , const char * * av ) {
100- struct strbuf sb ;
101- int reverse = 0 ;
102- int line_termination = '\n' ;
63+ struct strbuf sb1 , sb2 , sb3 ;
64+ int reverse_diff = 0 ;
10365
104- strbuf_init (& sb );
66+ strbuf_init (& sb1 );
67+ strbuf_init (& sb2 );
68+ strbuf_init (& sb3 );
10569
10670 while (1 < ac && av [1 ][0 ] == '-' ) {
10771 if (av [1 ][1 ] == 'R' )
108- reverse = 1 ;
72+ reverse_diff = 1 ;
10973 else if (av [1 ][1 ] == 'z' )
110- line_termination = 0 ;
74+ line_termination = inter_name_termination = 0 ;
11175 else if (av [1 ][1 ] == 'p' ) /* hidden from the help */
112- generate_patch = 0 ;
76+ diff_output_style = DIFF_FORMAT_HUMAN ;
77+ else if (av [1 ][1 ] == 'P' ) /* hidden from the help */
78+ diff_output_style = DIFF_FORMAT_MACHINE ;
11379 else if (av [1 ][1 ] == 'M' ) {
11480 detect_rename = 1 ;
11581 diff_score_opt = diff_scoreopt_parse (av [1 ]);
@@ -127,19 +93,38 @@ int main(int ac, const char **av) {
12793 }
12894 /* the remaining parameters are paths patterns */
12995
130- diff_setup (reverse , ( generate_patch ? -1 : line_termination ) );
96+ diff_setup (reverse_diff , diff_output_style );
13197 while (1 ) {
13298 int status ;
133- read_line (& sb , stdin , line_termination );
134- if (sb .eof )
99+ read_line (& sb1 , stdin , line_termination );
100+ if (sb1 .eof )
135101 break ;
136- status = parse_diff_raw_output (sb .buf );
102+ switch (sb1 .buf [0 ]) {
103+ case 'U' :
104+ diff_unmerge (sb1 .buf + 2 );
105+ continue ;
106+ case ':' :
107+ break ;
108+ default :
109+ goto unrecognized ;
110+ }
111+ if (!line_termination ) {
112+ read_line (& sb2 , stdin , line_termination );
113+ if (sb2 .eof )
114+ break ;
115+ read_line (& sb3 , stdin , line_termination );
116+ if (sb3 .eof )
117+ break ;
118+ status = parse_diff_raw (sb1 .buf + 1 , sb2 .buf , sb3 .buf );
119+ }
120+ else
121+ status = parse_diff_raw (sb1 .buf + 1 , NULL , NULL );
137122 if (status ) {
123+ unrecognized :
138124 diff_flush (av + 1 , ac - 1 );
139- printf ("%s%c" , sb .buf , line_termination );
125+ printf ("%s%c" , sb1 .buf , line_termination );
140126 }
141127 }
142-
143128 if (detect_rename )
144129 diff_detect_rename (detect_rename , diff_score_opt );
145130 if (pickaxe )
0 commit comments