@@ -103,17 +103,39 @@ struct archiver_context {
103
103
struct directory * bottom ;
104
104
};
105
105
106
+ static const struct attr_check * get_archive_attrs (const char * path )
107
+ {
108
+ static struct attr_check * check ;
109
+ if (!check )
110
+ check = attr_check_initl ("export-ignore" , "export-subst" , NULL );
111
+ return git_check_attr (path , check ) ? NULL : check ;
112
+ }
113
+
114
+ static int check_attr_export_ignore (const struct attr_check * check )
115
+ {
116
+ return check && ATTR_TRUE (check -> items [0 ].value );
117
+ }
118
+
119
+ static int check_attr_export_subst (const struct attr_check * check )
120
+ {
121
+ return check && ATTR_TRUE (check -> items [1 ].value );
122
+ }
123
+
124
+ static int should_queue_directories (const struct archiver_args * args )
125
+ {
126
+ return args -> pathspec .has_wildcard ;
127
+ }
128
+
106
129
static int write_archive_entry (const unsigned char * sha1 , const char * base ,
107
130
int baselen , const char * filename , unsigned mode , int stage ,
108
131
void * context )
109
132
{
110
133
static struct strbuf path = STRBUF_INIT ;
111
- static struct attr_check * check ;
112
134
struct archiver_context * c = context ;
113
135
struct archiver_args * args = c -> args ;
114
136
write_archive_entry_fn_t write_entry = c -> write_entry ;
115
- const char * path_without_prefix ;
116
137
int err ;
138
+ const char * path_without_prefix ;
117
139
118
140
args -> convert = 0 ;
119
141
strbuf_reset (& path );
@@ -125,12 +147,12 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
125
147
strbuf_addch (& path , '/' );
126
148
path_without_prefix = path .buf + args -> baselen ;
127
149
128
- if (!check )
129
- check = attr_check_initl ( "export-ignore" , "export-subst" , NULL ) ;
130
- if (! git_check_attr ( path_without_prefix , check )) {
131
- if (ATTR_TRUE (check -> items [ 0 ]. value ))
150
+ if (!S_ISDIR ( mode ) || ! should_queue_directories ( args )) {
151
+ const struct attr_check * check ;
152
+ check = get_archive_attrs ( path_without_prefix );
153
+ if (check_attr_export_ignore (check ))
132
154
return 0 ;
133
- args -> convert = ATTR_TRUE (check -> items [ 1 ]. value );
155
+ args -> convert = check_attr_export_subst (check );
134
156
}
135
157
136
158
if (S_ISDIR (mode ) || S_ISGITLINK (mode )) {
@@ -204,6 +226,17 @@ static int queue_or_write_archive_entry(const unsigned char *sha1,
204
226
}
205
227
206
228
if (S_ISDIR (mode )) {
229
+ size_t baselen = base -> len ;
230
+ const struct attr_check * check ;
231
+
232
+ /* Borrow base, but restore its original value when done. */
233
+ strbuf_addstr (base , filename );
234
+ strbuf_addch (base , '/' );
235
+ check = get_archive_attrs (base -> buf );
236
+ strbuf_setlen (base , baselen );
237
+
238
+ if (check_attr_export_ignore (check ))
239
+ return 0 ;
207
240
queue_directory (sha1 , base , filename ,
208
241
mode , stage , c );
209
242
return READ_TREE_RECURSIVE ;
@@ -257,7 +290,7 @@ int write_archive_entries(struct archiver_args *args,
257
290
}
258
291
259
292
err = read_tree_recursive (args -> tree , "" , 0 , 0 , & args -> pathspec ,
260
- args -> pathspec . has_wildcard ?
293
+ should_queue_directories ( args ) ?
261
294
queue_or_write_archive_entry :
262
295
write_archive_entry_buf ,
263
296
& context );
0 commit comments