5
5
#include "pathspec.h"
6
6
#include "parse-options.h"
7
7
8
- static int quiet , verbose , stdin_paths ;
8
+ static int quiet , verbose , stdin_paths , show_non_matching ;
9
9
static const char * const check_ignore_usage [] = {
10
10
"git check-ignore [options] pathname..." ,
11
11
"git check-ignore [options] --stdin < <list-of-paths>" ,
@@ -22,52 +22,55 @@ static const struct option check_ignore_options[] = {
22
22
N_ ("read file names from stdin" )),
23
23
OPT_BOOLEAN ('z' , NULL , & null_term_line ,
24
24
N_ ("input paths are terminated by a null character" )),
25
+ OPT_BOOLEAN ('n' , "non-matching" , & show_non_matching ,
26
+ N_ ("show non-matching input paths" )),
25
27
OPT_END ()
26
28
};
27
29
28
30
static void output_exclude (const char * path , struct exclude * exclude )
29
31
{
30
- char * bang = exclude -> flags & EXC_FLAG_NEGATIVE ? "!" : "" ;
31
- char * slash = exclude -> flags & EXC_FLAG_MUSTBEDIR ? "/" : "" ;
32
+ char * bang = ( exclude && exclude -> flags & EXC_FLAG_NEGATIVE ) ? "!" : "" ;
33
+ char * slash = ( exclude && exclude -> flags & EXC_FLAG_MUSTBEDIR ) ? "/" : "" ;
32
34
if (!null_term_line ) {
33
35
if (!verbose ) {
34
36
write_name_quoted (path , stdout , '\n' );
35
37
} else {
36
- quote_c_style (exclude -> el -> src , NULL , stdout , 0 );
37
- printf (":%d:%s%s%s\t" ,
38
- exclude -> srcpos ,
39
- bang , exclude -> pattern , slash );
38
+ if (exclude ) {
39
+ quote_c_style (exclude -> el -> src , NULL , stdout , 0 );
40
+ printf (":%d:%s%s%s\t" ,
41
+ exclude -> srcpos ,
42
+ bang , exclude -> pattern , slash );
43
+ }
44
+ else {
45
+ printf ("::\t" );
46
+ }
40
47
quote_c_style (path , NULL , stdout , 0 );
41
48
fputc ('\n' , stdout );
42
49
}
43
50
} else {
44
51
if (!verbose ) {
45
52
printf ("%s%c" , path , '\0' );
46
53
} else {
47
- printf ("%s%c%d%c%s%s%s%c%s%c" ,
48
- exclude -> el -> src , '\0' ,
49
- exclude -> srcpos , '\0' ,
50
- bang , exclude -> pattern , slash , '\0' ,
51
- path , '\0' );
54
+ if (exclude )
55
+ printf ("%s%c%d%c%s%s%s%c%s%c" ,
56
+ exclude -> el -> src , '\0' ,
57
+ exclude -> srcpos , '\0' ,
58
+ bang , exclude -> pattern , slash , '\0' ,
59
+ path , '\0' );
60
+ else
61
+ printf ("%c%c%c%s%c" , '\0' , '\0' , '\0' , path , '\0' );
52
62
}
53
63
}
54
64
}
55
65
56
- static int check_ignore (const char * prefix , const char * * pathspec )
66
+ static int check_ignore (struct dir_struct * dir ,
67
+ const char * prefix , const char * * pathspec )
57
68
{
58
- struct dir_struct dir ;
59
69
const char * path , * full_path ;
60
70
char * seen ;
61
71
int num_ignored = 0 , dtype = DT_UNKNOWN , i ;
62
72
struct exclude * exclude ;
63
73
64
- /* read_cache() is only necessary so we can watch out for submodules. */
65
- if (read_cache () < 0 )
66
- die (_ ("index file corrupt" ));
67
-
68
- memset (& dir , 0 , sizeof (dir ));
69
- setup_standard_excludes (& dir );
70
-
71
74
if (!pathspec || !* pathspec ) {
72
75
if (!quiet )
73
76
fprintf (stderr , "no pathspec given.\n" );
@@ -86,28 +89,26 @@ static int check_ignore(const char *prefix, const char **pathspec)
86
89
? strlen (prefix ) : 0 , path );
87
90
full_path = check_path_for_gitlink (full_path );
88
91
die_if_path_beyond_symlink (full_path , prefix );
92
+ exclude = NULL ;
89
93
if (!seen [i ]) {
90
- exclude = last_exclude_matching (& dir , full_path , & dtype );
91
- if (exclude ) {
92
- if (!quiet )
93
- output_exclude (path , exclude );
94
- num_ignored ++ ;
95
- }
94
+ exclude = last_exclude_matching (dir , full_path , & dtype );
96
95
}
96
+ if (!quiet && (exclude || show_non_matching ))
97
+ output_exclude (path , exclude );
98
+ if (exclude )
99
+ num_ignored ++ ;
97
100
}
98
101
free (seen );
99
- clear_directory (& dir );
100
102
101
103
return num_ignored ;
102
104
}
103
105
104
- static int check_ignore_stdin_paths (const char * prefix )
106
+ static int check_ignore_stdin_paths (struct dir_struct * dir , const char * prefix )
105
107
{
106
108
struct strbuf buf , nbuf ;
107
- char * * pathspec = NULL ;
108
- size_t nr = 0 , alloc = 0 ;
109
+ char * pathspec [2 ] = { NULL , NULL };
109
110
int line_termination = null_term_line ? 0 : '\n' ;
110
- int num_ignored ;
111
+ int num_ignored = 0 ;
111
112
112
113
strbuf_init (& buf , 0 );
113
114
strbuf_init (& nbuf , 0 );
@@ -118,23 +119,19 @@ static int check_ignore_stdin_paths(const char *prefix)
118
119
die ("line is badly quoted" );
119
120
strbuf_swap (& buf , & nbuf );
120
121
}
121
- ALLOC_GROW ( pathspec , nr + 1 , alloc ) ;
122
- pathspec [ nr ] = xcalloc ( strlen ( buf . buf ) + 1 , sizeof ( * buf . buf ) );
123
- strcpy ( pathspec [ nr ++ ], buf . buf );
122
+ pathspec [ 0 ] = buf . buf ;
123
+ num_ignored += check_ignore ( dir , prefix , ( const char * * ) pathspec );
124
+ maybe_flush_or_die ( stdout , "check-ignore to stdout" );
124
125
}
125
- ALLOC_GROW (pathspec , nr + 1 , alloc );
126
- pathspec [nr ] = NULL ;
127
- num_ignored = check_ignore (prefix , (const char * * )pathspec );
128
- maybe_flush_or_die (stdout , "attribute to stdout" );
129
126
strbuf_release (& buf );
130
127
strbuf_release (& nbuf );
131
- free (pathspec );
132
128
return num_ignored ;
133
129
}
134
130
135
131
int cmd_check_ignore (int argc , const char * * argv , const char * prefix )
136
132
{
137
133
int num_ignored ;
134
+ struct dir_struct dir ;
138
135
139
136
git_config (git_default_config , NULL );
140
137
@@ -156,13 +153,24 @@ int cmd_check_ignore(int argc, const char **argv, const char *prefix)
156
153
if (verbose )
157
154
die (_ ("cannot have both --quiet and --verbose" ));
158
155
}
156
+ if (show_non_matching && !verbose )
157
+ die (_ ("--non-matching is only valid with --verbose" ));
158
+
159
+ /* read_cache() is only necessary so we can watch out for submodules. */
160
+ if (read_cache () < 0 )
161
+ die (_ ("index file corrupt" ));
162
+
163
+ memset (& dir , 0 , sizeof (dir ));
164
+ setup_standard_excludes (& dir );
159
165
160
166
if (stdin_paths ) {
161
- num_ignored = check_ignore_stdin_paths (prefix );
167
+ num_ignored = check_ignore_stdin_paths (& dir , prefix );
162
168
} else {
163
- num_ignored = check_ignore (prefix , argv );
169
+ num_ignored = check_ignore (& dir , prefix , argv );
164
170
maybe_flush_or_die (stdout , "ignore to stdout" );
165
171
}
166
172
173
+ clear_directory (& dir );
174
+
167
175
return !num_ignored ;
168
176
}
0 commit comments