Skip to content

Commit 9f48be4

Browse files
committed
Merge branch '0.4.x'
# Conflicts: # Makefile.am
2 parents 6ce15dd + e8034e4 commit 9f48be4

File tree

3 files changed

+154
-47
lines changed

3 files changed

+154
-47
lines changed

doc/patchutils.xml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,11 +1280,14 @@ filterdiff -i 'b/*/newname' git-patch-with-renames.patch]]></screen></para>
12801280
</varlistentry>
12811281
<varlistentry>
12821282
<term><option>-E</option>,
1283+
<option>--empty-files-as-absent</option>,
12831284
<option>--empty-files-as-removed</option></term>
12841285
<listitem>
12851286
<para>Treat empty files as absent for the purpose of
12861287
displaying file additions, modifications and
1287-
removals.</para>
1288+
removals. For example, a file with an empty old version
1289+
and additions in the new version will be treated as a
1290+
file addition (+) rather than a modification (!).</para>
12881291
</listitem>
12891292
</varlistentry>
12901293
<varlistentry>
@@ -1646,12 +1649,15 @@ This is the same as gitdiff but uses git show instead of git diff.
16461649
</listitem>
16471650
</varlistentry>
16481651
<varlistentry>
1649-
<term><option>-E</option>,
1652+
<term>
1653+
<option>--empty-files-as-absent</option>,
16501654
<option>--empty-files-as-removed</option></term>
16511655
<listitem>
16521656
<para>Treat empty files as absent for the purpose of
16531657
displaying file additions, modifications and
1654-
removals.</para>
1658+
removals. For example, a file with an empty old version
1659+
and additions in the new version will be treated as a
1660+
file addition (+) rather than a modification (!). Note: For grepdiff, only the long form is available (<option>-E</option> means <option>--extended-regexp</option> for grepdiff).</para>
16551661
</listitem>
16561662
</varlistentry>
16571663
<varlistentry>

src/filterdiff.c

Lines changed: 71 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ static int
359359
do_git_diff_no_hunks (FILE *f, char **header, unsigned int num_headers,
360360
int match, char **line, size_t *linelen,
361361
unsigned long *linenum, unsigned long start_linenum,
362-
char *status, const char *bestname, const char *patchname,
362+
char status, const char *bestname, const char *patchname,
363363
int *orig_file_exists, int *new_file_exists,
364364
enum git_diff_type git_type)
365365
{
@@ -386,16 +386,6 @@ do_git_diff_no_hunks (FILE *f, char **header, unsigned int num_headers,
386386
break;
387387
}
388388

389-
/* Update status based on file existence (do this early so returns below have correct status) */
390-
if (status != NULL && mode != mode_filter && show_status &&
391-
orig_file_exists != NULL && new_file_exists != NULL) {
392-
if (!*orig_file_exists)
393-
*status = '+';
394-
else if (!*new_file_exists)
395-
*status = '-';
396-
/* else: keep existing '!' value for modifications */
397-
}
398-
399389
/* If this diff matches the filter, display it */
400390
if (match) {
401391
if (mode == mode_filter) {
@@ -404,7 +394,7 @@ do_git_diff_no_hunks (FILE *f, char **header, unsigned int num_headers,
404394
fputs (header[i], stdout);
405395
} else if (mode == mode_list && !displayed_filename) {
406396
if (!show_status) {
407-
display_filename (start_linenum, *status,
397+
display_filename (start_linenum, status,
408398
bestname, patchname);
409399
}
410400
displayed_filename = 1;
@@ -465,7 +455,7 @@ static int
465455
do_unified (FILE *f, char **header, unsigned int num_headers,
466456
int match, char **line,
467457
size_t *linelen, unsigned long *linenum,
468-
unsigned long start_linenum, char *status,
458+
unsigned long start_linenum, char status,
469459
const char *bestname, const char *patchname,
470460
int *orig_file_exists, int *new_file_exists)
471461
{
@@ -679,9 +669,28 @@ do_unified (FILE *f, char **header, unsigned int num_headers,
679669
!regexecs (regex, num_regex, *line + 1, 0, NULL, 0)) {
680670
if (output_matching == output_none) {
681671
if (!displayed_filename) {
672+
char display_status = status;
673+
/* Update status based on file existence for grepdiff -s */
674+
if (show_status) {
675+
int orig_absent = orig_file_exists && !*orig_file_exists;
676+
int new_absent = new_file_exists && !*new_file_exists;
677+
678+
/* Check for empty files if --empty-files-as-absent is set */
679+
if (empty_files_as_absent) {
680+
if (orig_file_exists && *orig_file_exists && orig_is_empty)
681+
orig_absent = 1;
682+
if (new_file_exists && *new_file_exists && new_is_empty)
683+
new_absent = 1;
684+
}
685+
686+
if (orig_absent)
687+
display_status = '+';
688+
else if (new_absent)
689+
display_status = '-';
690+
}
682691
displayed_filename = 1;
683692
display_filename (start_linenum,
684-
*status, bestname,
693+
display_status, bestname,
685694
patchname);
686695
}
687696

@@ -756,24 +765,14 @@ do_unified (FILE *f, char **header, unsigned int num_headers,
756765
*new_file_exists = 0;
757766
}
758767

759-
/* Update status based on final file existence after empty file processing */
760-
if (status != NULL && mode != mode_filter && show_status &&
761-
orig_file_exists != NULL && new_file_exists != NULL) {
762-
if (!*orig_file_exists)
763-
*status = '+';
764-
else if (!*new_file_exists)
765-
*status = '-';
766-
/* else: keep existing '!' value for modifications */
767-
}
768-
769768
return ret;
770769
}
771770

772771
static int
773772
do_context (FILE *f, char **header, unsigned int num_headers,
774773
int match, char **line,
775774
size_t *linelen, unsigned long *linenum,
776-
unsigned long start_linenum, char *status,
775+
unsigned long start_linenum, char status,
777776
const char *bestname, const char *patchname,
778777
int *orig_file_exists, int *new_file_exists)
779778
{
@@ -1038,9 +1037,28 @@ do_context (FILE *f, char **header, unsigned int num_headers,
10381037
0, NULL, 0)) {
10391038
if (output_matching == output_none) {
10401039
if (!displayed_filename) {
1040+
char display_status = status;
1041+
/* Update status based on file existence for grepdiff -s */
1042+
if (show_status) {
1043+
int orig_absent = orig_file_exists && !*orig_file_exists;
1044+
int new_absent = new_file_exists && !*new_file_exists;
1045+
1046+
/* Check for empty files if --empty-files-as-absent is set */
1047+
if (empty_files_as_absent) {
1048+
if (orig_file_exists && *orig_file_exists && orig_is_empty)
1049+
orig_absent = 1;
1050+
if (new_file_exists && *new_file_exists && new_is_empty)
1051+
new_absent = 1;
1052+
}
1053+
1054+
if (orig_absent)
1055+
display_status = '+';
1056+
else if (new_absent)
1057+
display_status = '-';
1058+
}
10411059
displayed_filename = 1;
10421060
display_filename(start_linenum,
1043-
*status,
1061+
display_status,
10441062
bestname,
10451063
patchname);
10461064
}
@@ -1170,16 +1188,6 @@ do_context (FILE *f, char **header, unsigned int num_headers,
11701188
*new_file_exists = 0;
11711189
}
11721190

1173-
/* Update status based on final file existence after empty file processing */
1174-
if (status != NULL && mode != mode_filter && show_status &&
1175-
orig_file_exists != NULL && new_file_exists != NULL) {
1176-
if (!*orig_file_exists)
1177-
*status = '+';
1178-
else if (!*new_file_exists)
1179-
*status = '-';
1180-
/* else: keep existing '!' value for modifications */
1181-
}
1182-
11831191
return ret;
11841192
}
11851193

@@ -1210,7 +1218,7 @@ static int filterdiff (FILE *f, const char *patchname)
12101218
int (*do_diff) (FILE *, char **, unsigned int,
12111219
int, char **, size_t *,
12121220
unsigned long *, unsigned long,
1213-
char *, const char *, const char *,
1221+
char, const char *, const char *,
12141222
int *, int *);
12151223

12161224
orig_file_exists = 0; // shut gcc up
@@ -1405,13 +1413,19 @@ static int filterdiff (FILE *f, const char *patchname)
14051413
/* Process the git diff (it will handle filename display) */
14061414
result = do_git_diff_no_hunks (f, header, num_headers,
14071415
match, &line, &linelen, &linenum,
1408-
start_linenum, &status, p, patchname,
1416+
start_linenum, status, p, patchname,
14091417
&orig_file_exists, &new_file_exists,
14101418
git_type);
14111419

14121420
/* Print filename with status if in list mode and matches */
1413-
if (match && show_status && mode == mode_list)
1421+
if (match && show_status && mode == mode_list) {
1422+
if (!orig_file_exists)
1423+
status = '+';
1424+
else if (!new_file_exists)
1425+
status = '-';
1426+
14141427
display_filename (start_linenum, status, p, patchname);
1428+
}
14151429

14161430
/* Clean up */
14171431
free (git_old_name);
@@ -1500,13 +1514,19 @@ static int filterdiff (FILE *f, const char *patchname)
15001514
result = do_diff (f, header, num_headers,
15011515
match, &line,
15021516
&linelen, &linenum,
1503-
start_linenum, &status, p, patchname,
1517+
start_linenum, status, p, patchname,
15041518
&orig_file_exists, &new_file_exists);
15051519

15061520
// print if it matches.
1507-
if (match && show_status && mode == mode_list)
1521+
if (match && show_status && mode == mode_list) {
1522+
if (!orig_file_exists)
1523+
status = '+';
1524+
else if (!new_file_exists)
1525+
status = '-';
1526+
15081527
display_filename (start_linenum, status,
15091528
p, patchname);
1529+
}
15101530

15111531
switch (result) {
15121532
case EOF:
@@ -1617,6 +1637,8 @@ const char * syntax_str =
16171637
#endif
16181638
" -E, --empty-files-as-absent (lsdiff)\n"
16191639
" treat empty files as absent (lsdiff)\n"
1640+
" --empty-files-as-absent (grepdiff)\n"
1641+
" treat empty files as absent (grepdiff)\n"
16201642
" -f FILE, --file=FILE (grepdiff)\n"
16211643
" read regular expressions from FILE (grepdiff)\n"
16221644
" --filter run as 'filterdiff' (grepdiff, patchview, lsdiff)\n"
@@ -1840,7 +1862,7 @@ int main (int argc, char *argv[])
18401862
{"remove-timestamps", 0, 0, 1000 + 'r'},
18411863
{"with-filename", 0, 0, 'H'},
18421864
{"no-filename", 0, 0, 'h'},
1843-
{"empty-files-as-absent", 0, 0, 'E'},
1865+
{"empty-files-as-absent", 0, 0, 1000 + 'E'},
18441866
{"number-files", 0, 0, 'N'},
18451867
{"clean", 0, 0, 1000 + 'c'},
18461868
{"strip-match", 1, 0, 'p'},
@@ -1853,7 +1875,7 @@ int main (int argc, char *argv[])
18531875
{"strip-match", 1, 0, 'p'},
18541876
{"status", 0, 0, 's'},
18551877
{"extended-regexp", 0, 0, 'E'},
1856-
{"empty-files-as-removed", 0, 0, 'E'},
1878+
{"empty-files-as-removed", 0, 0, 1000 + 'E'},
18571879
{"file", 1, 0, 'f'},
18581880
{"in-place", 0, 0, 1000 + 'w'},
18591881
{"git-prefixes", 1, 0, 1000 + 'G'},
@@ -1883,6 +1905,12 @@ int main (int argc, char *argv[])
18831905
empty_files_as_absent = 1;
18841906
else syntax (1);
18851907
break;
1908+
case 1000 + 'E':
1909+
/* Long form --empty-files-as-absent or --empty-files-as-removed */
1910+
if (mode == mode_grep || mode == mode_list)
1911+
empty_files_as_absent = 1;
1912+
else syntax (1);
1913+
break;
18861914
case 'f':
18871915
if (mode == mode_grep) {
18881916
regex_file_specified = 1;

tests/grepdiff-status/run-test

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ cat << EOF | cmp - output2 || exit 1
4949
! another-modified
5050
EOF
5151

52-
# Test with --empty-files-as-absent
52+
# Test with --empty-files-as-absent for file addition
5353
# File with only additions should be treated as new file
5454
cat << EOF > diff3
5555
--- emptyfile
@@ -67,3 +67,76 @@ ${GREPDIFF} -s --empty-files-as-absent 'content' diff3 2>errors >output3 || exit
6767
cat << EOF | cmp - output3 || exit 1
6868
+ emptyfile
6969
EOF
70+
71+
# Test with --empty-files-as-absent for file deletion
72+
# File with only deletions should be treated as deleted
73+
cat << EOF > diff4
74+
--- deletedfile
75+
+++ deletedfile
76+
@@ -1 +0,0 @@
77+
-content
78+
@@ -60 +60 @@
79+
-old
80+
+new
81+
EOF
82+
83+
${GREPDIFF} -s --empty-files-as-absent 'content' diff4 2>errors >output4 || exit 1
84+
[ -s errors ] && exit 1
85+
86+
cat << EOF | cmp - output4 || exit 1
87+
- deletedfile
88+
EOF
89+
90+
# Test with context diff format
91+
cat << EOF > diff5
92+
*** /dev/null
93+
--- newfile-ctx
94+
***************
95+
*** 0 ****
96+
--- 1 ----
97+
+ content
98+
*** oldfile-ctx
99+
--- /dev/null
100+
***************
101+
*** 1 ****
102+
- content
103+
--- 0 ----
104+
*** modified-ctx
105+
--- modified-ctx
106+
***************
107+
*** 1 ****
108+
! old content
109+
--- 1 ----
110+
! new content
111+
EOF
112+
113+
${GREPDIFF} -s 'content' diff5 2>errors >output5 || exit 1
114+
[ -s errors ] && exit 1
115+
116+
cat << EOF | cmp - output5 || exit 1
117+
+ newfile-ctx
118+
- oldfile-ctx
119+
! modified-ctx
120+
EOF
121+
122+
# Test context diff with --empty-files-as-absent
123+
cat << EOF > diff6
124+
*** emptyfile-ctx
125+
--- emptyfile-ctx
126+
***************
127+
*** 0 ****
128+
--- 1 ----
129+
+ content
130+
***************
131+
*** 60 ****
132+
! old
133+
--- 60 ----
134+
! new
135+
EOF
136+
137+
${GREPDIFF} -s --empty-files-as-absent 'content' diff6 2>errors >output6 || exit 1
138+
[ -s errors ] && exit 1
139+
140+
cat << EOF | cmp - output6 || exit 1
141+
+ emptyfile-ctx
142+
EOF

0 commit comments

Comments
 (0)