17
#include "utf8.h"
18
#include "quote.h"
19
#include "read-cache-ll.h"
20
+#include "refs.h"
21
#include "revision.h"
22
#include "object-store-ll.h"
23
#include "setup.h"
184
}
185
}
186
187
+/*
188
+ * Atribute name cannot begin with "builtin_" which
189
+ * is a reserved namespace for built in attributes values.
190
+ */
191
+static int attr_name_reserved(const char *name)
192
+{
193
+ return starts_with(name, "builtin_");
194
+}
195
+
196
static int attr_name_valid(const char *name, size_t namelen)
197
{
198
/*
325
cp++;
326
len--;
327
}
318
- if (!attr_name_valid(cp, len)) {
328
+ if (!attr_name_valid(cp, len) || attr_name_reserved(cp)) {
329
report_invalid_attr(cp, len, src, lineno);
330
return NULL;
331
}
389
name += strlen(ATTRIBUTE_MACRO_PREFIX);
390
name += strspn(name, blank);
391
namelen = strcspn(name, blank);
382
- if (!attr_name_valid(name, namelen)) {
392
+ if (!attr_name_valid(name, namelen) || attr_name_reserved(name)) {
393
report_invalid_attr(name, namelen, src, lineno);
394
goto fail_return;
395
}
1250
return &attr_source;
1251
}
1252
1253
+static const char *interned_mode_string(unsigned int mode)
1254
+{
1255
+ static struct {
1256
+ unsigned int val;
1257
+ char str[7];
1258
+ } mode_string[] = {
1259
+ { .val = 0040000 },
1260
+ { .val = 0100644 },
1261
+ { .val = 0100755 },
1262
+ { .val = 0120000 },
1263
+ { .val = 0160000 },
1264
+ };
1265
+ int i;
1266
+
1267
+ for (i = 0; i < ARRAY_SIZE(mode_string); i++) {
1268
+ if (mode_string[i].val != mode)
1269
+ continue;
1270
+ if (!*mode_string[i].str)
1271
+ snprintf(mode_string[i].str, sizeof(mode_string[i].str),
1272
+ "%06o", mode);
1273
+ return mode_string[i].str;
1274
+ }
1275
+ BUG("Unsupported mode 0%o", mode);
1276
+}
1277
+
1278
+static const char *builtin_object_mode_attr(struct index_state *istate, const char *path)
1279
+{
1280
+ unsigned int mode;
1281
+
1282
+ if (direction == GIT_ATTR_CHECKIN) {
1283
+ struct object_id oid;
1284
+ struct stat st;
1285
+ if (lstat(path, &st))
1286
+ die_errno(_("unable to stat '%s'"), path);
1287
+ mode = canon_mode(st.st_mode);
1288
+ if (S_ISDIR(mode)) {
1289
+ /*
1290
+ *`path` is either a directory or it is a submodule,
1291
+ * in which case it is already indexed as submodule
1292
+ * or it does not exist in the index yet and we need to
1293
+ * check if we can resolve to a ref.
1294
+ */
1295
+ int pos = index_name_pos(istate, path, strlen(path));
1296
+ if (pos >= 0) {
1297
+ if (S_ISGITLINK(istate->cache[pos]->ce_mode))
1298
+ mode = istate->cache[pos]->ce_mode;
1299
+ } else if (resolve_gitlink_ref(path, "HEAD", &oid) == 0) {
1300
+ mode = S_IFGITLINK;
1301
+ }
1302
+ }
1303
+ } else {
1304
+ /*
1305
+ * For GIT_ATTR_CHECKOUT and GIT_ATTR_INDEX we only check
1306
+ * for mode in the index.
1307
+ */
1308
+ int pos = index_name_pos(istate, path, strlen(path));
1309
+ if (pos >= 0)
1310
+ mode = istate->cache[pos]->ce_mode;
1311
+ else
1312
+ return ATTR__UNSET;
1313
+ }
1314
+
1315
+ return interned_mode_string(mode);
1316
+}
1317
+
1318
+
1319
+static const char *compute_builtin_attr(struct index_state *istate,
1320
+ const char *path,
1321
+ const struct git_attr *attr) {
1322
+ static const struct git_attr *object_mode_attr;
1323
+
1324
+ if (!object_mode_attr)
1325
+ object_mode_attr = git_attr("builtin_objectmode");
1326
+
1327
+ if (attr == object_mode_attr)
1328
+ return builtin_object_mode_attr(istate, path);
1329
+ return ATTR__UNSET;
1330
+}
1331
+
1332
void git_check_attr(struct index_state *istate,
1333
const char *path,
1334
struct attr_check *check)
1342
unsigned int n = check->items[i].attr->attr_nr;
1343
const char *value = check->all_attrs[n].value;
1344
if (value == ATTR__UNKNOWN)
1256
- value = ATTR__UNSET;
1345
+ value = compute_builtin_attr(istate, path, check->all_attrs[n].attr);
1346
check->items[i].value = value;
1347
}
1348
}