Skip to content

Commit 968d881

Browse files
committed
Fix grepdiff --status by passing status as pointer
The grepdiff --status flag was not working correctly, particularly with --empty-files-as-absent. The issue was that status needed to be updated after empty file processing but before filename display. This commit refactors the code to pass status by pointer to the diff processing functions (do_unified, do_context, do_git_diff_no_hunks), allowing them to update the status value at the correct time. Changes: - Modified function signatures to accept char *status instead of char status - Added status update logic after empty file processing in each function - Updated all callers to pass &status instead of status - Removed duplicate status update logic that was previously done after the functions returned This ensures grepdiff -s displays the correct status (+/-/!) for all file types, including: - New files (show +) - Deleted files (show -) - Modified files (show !) - Empty files when --empty-files-as-absent is used All 187 tests pass. Assisted-by: Claude Code
1 parent 39b1051 commit 968d881

File tree

1 file changed

+41
-23
lines changed

1 file changed

+41
-23
lines changed

src/filterdiff.c

Lines changed: 41 additions & 23 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,6 +386,16 @@ 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+
389399
/* If this diff matches the filter, display it */
390400
if (match) {
391401
if (mode == mode_filter) {
@@ -394,7 +404,7 @@ do_git_diff_no_hunks (FILE *f, char **header, unsigned int num_headers,
394404
fputs (header[i], stdout);
395405
} else if (mode == mode_list && !displayed_filename) {
396406
if (!show_status) {
397-
display_filename (start_linenum, status,
407+
display_filename (start_linenum, *status,
398408
bestname, patchname);
399409
}
400410
displayed_filename = 1;
@@ -455,7 +465,7 @@ static int
455465
do_unified (FILE *f, char **header, unsigned int num_headers,
456466
int match, char **line,
457467
size_t *linelen, unsigned long *linenum,
458-
unsigned long start_linenum, char status,
468+
unsigned long start_linenum, char *status,
459469
const char *bestname, const char *patchname,
460470
int *orig_file_exists, int *new_file_exists)
461471
{
@@ -671,7 +681,7 @@ do_unified (FILE *f, char **header, unsigned int num_headers,
671681
if (!displayed_filename) {
672682
displayed_filename = 1;
673683
display_filename (start_linenum,
674-
status, bestname,
684+
*status, bestname,
675685
patchname);
676686
}
677687

@@ -746,14 +756,24 @@ do_unified (FILE *f, char **header, unsigned int num_headers,
746756
*new_file_exists = 0;
747757
}
748758

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+
749769
return ret;
750770
}
751771

752772
static int
753773
do_context (FILE *f, char **header, unsigned int num_headers,
754774
int match, char **line,
755775
size_t *linelen, unsigned long *linenum,
756-
unsigned long start_linenum, char status,
776+
unsigned long start_linenum, char *status,
757777
const char *bestname, const char *patchname,
758778
int *orig_file_exists, int *new_file_exists)
759779
{
@@ -1020,7 +1040,7 @@ do_context (FILE *f, char **header, unsigned int num_headers,
10201040
if (!displayed_filename) {
10211041
displayed_filename = 1;
10221042
display_filename(start_linenum,
1023-
status,
1043+
*status,
10241044
bestname,
10251045
patchname);
10261046
}
@@ -1150,6 +1170,16 @@ do_context (FILE *f, char **header, unsigned int num_headers,
11501170
*new_file_exists = 0;
11511171
}
11521172

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+
11531183
return ret;
11541184
}
11551185

@@ -1180,7 +1210,7 @@ static int filterdiff (FILE *f, const char *patchname)
11801210
int (*do_diff) (FILE *, char **, unsigned int,
11811211
int, char **, size_t *,
11821212
unsigned long *, unsigned long,
1183-
char, const char *, const char *,
1213+
char *, const char *, const char *,
11841214
int *, int *);
11851215

11861216
orig_file_exists = 0; // shut gcc up
@@ -1375,19 +1405,13 @@ static int filterdiff (FILE *f, const char *patchname)
13751405
/* Process the git diff (it will handle filename display) */
13761406
result = do_git_diff_no_hunks (f, header, num_headers,
13771407
match, &line, &linelen, &linenum,
1378-
start_linenum, status, p, patchname,
1408+
start_linenum, &status, p, patchname,
13791409
&orig_file_exists, &new_file_exists,
13801410
git_type);
13811411

13821412
/* Print filename with status if in list mode and matches */
1383-
if (match && show_status && mode == mode_list) {
1384-
if (!orig_file_exists)
1385-
status = '+';
1386-
else if (!new_file_exists)
1387-
status = '-';
1388-
1413+
if (match && show_status && mode == mode_list)
13891414
display_filename (start_linenum, status, p, patchname);
1390-
}
13911415

13921416
/* Clean up */
13931417
free (git_old_name);
@@ -1476,19 +1500,13 @@ static int filterdiff (FILE *f, const char *patchname)
14761500
result = do_diff (f, header, num_headers,
14771501
match, &line,
14781502
&linelen, &linenum,
1479-
start_linenum, status, p, patchname,
1503+
start_linenum, &status, p, patchname,
14801504
&orig_file_exists, &new_file_exists);
14811505

14821506
// print if it matches.
1483-
if (match && show_status && mode == mode_list) {
1484-
if (!orig_file_exists)
1485-
status = '+';
1486-
else if (!new_file_exists)
1487-
status = '-';
1488-
1507+
if (match && show_status && mode == mode_list)
14891508
display_filename (start_linenum, status,
14901509
p, patchname);
1491-
}
14921510

14931511
switch (result) {
14941512
case EOF:

0 commit comments

Comments
 (0)