|
9 | 9 | #include "object.h" |
10 | 10 | #include "tag.h" |
11 | 11 |
|
| 12 | +/* |
| 13 | + * List of all available backends |
| 14 | + */ |
| 15 | +static struct ref_storage_be *refs_backends = &refs_be_files; |
| 16 | + |
| 17 | +static struct ref_storage_be *find_ref_storage_backend(const char *name) |
| 18 | +{ |
| 19 | + struct ref_storage_be *be; |
| 20 | + for (be = refs_backends; be; be = be->next) |
| 21 | + if (!strcmp(be->name, name)) |
| 22 | + return be; |
| 23 | + return NULL; |
| 24 | +} |
| 25 | + |
| 26 | +int ref_storage_backend_exists(const char *name) |
| 27 | +{ |
| 28 | + return find_ref_storage_backend(name) != NULL; |
| 29 | +} |
| 30 | + |
12 | 31 | /* |
13 | 32 | * How to handle various characters in refnames: |
14 | 33 | * 0: An acceptable character for refs |
@@ -1081,20 +1100,20 @@ const char *find_descendant_ref(const char *dirname, |
1081 | 1100 | return NULL; |
1082 | 1101 | } |
1083 | 1102 |
|
1084 | | -int rename_ref_available(const char *oldname, const char *newname) |
| 1103 | +int rename_ref_available(const char *old_refname, const char *new_refname) |
1085 | 1104 | { |
1086 | 1105 | struct string_list skip = STRING_LIST_INIT_NODUP; |
1087 | 1106 | struct strbuf err = STRBUF_INIT; |
1088 | | - int ret; |
| 1107 | + int ok; |
1089 | 1108 |
|
1090 | | - string_list_insert(&skip, oldname); |
1091 | | - ret = !verify_refname_available(newname, NULL, &skip, &err); |
1092 | | - if (!ret) |
| 1109 | + string_list_insert(&skip, old_refname); |
| 1110 | + ok = !verify_refname_available(new_refname, NULL, &skip, &err); |
| 1111 | + if (!ok) |
1093 | 1112 | error("%s", err.buf); |
1094 | 1113 |
|
1095 | 1114 | string_list_clear(&skip, 0); |
1096 | 1115 | strbuf_release(&err); |
1097 | | - return ret; |
| 1116 | + return ok; |
1098 | 1117 | } |
1099 | 1118 |
|
1100 | 1119 | int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) |
@@ -1132,9 +1151,13 @@ int head_ref(each_ref_fn fn, void *cb_data) |
1132 | 1151 | static int do_for_each_ref(const char *submodule, const char *prefix, |
1133 | 1152 | each_ref_fn fn, int trim, int flags, void *cb_data) |
1134 | 1153 | { |
| 1154 | + struct ref_store *refs = get_ref_store(submodule); |
1135 | 1155 | struct ref_iterator *iter; |
1136 | 1156 |
|
1137 | | - iter = files_ref_iterator_begin(submodule, prefix, flags); |
| 1157 | + if (!refs) |
| 1158 | + return 0; |
| 1159 | + |
| 1160 | + iter = refs->be->iterator_begin(refs, prefix, flags); |
1138 | 1161 | iter = prefix_ref_iterator_begin(iter, prefix, trim); |
1139 | 1162 |
|
1140 | 1163 | return do_for_each_ref_iterator(iter, fn, cb_data); |
@@ -1193,8 +1216,10 @@ int for_each_rawref(each_ref_fn fn, void *cb_data) |
1193 | 1216 | } |
1194 | 1217 |
|
1195 | 1218 | /* This function needs to return a meaningful errno on failure */ |
1196 | | -const char *resolve_ref_unsafe(const char *refname, int resolve_flags, |
1197 | | - unsigned char *sha1, int *flags) |
| 1219 | +static const char *resolve_ref_recursively(struct ref_store *refs, |
| 1220 | + const char *refname, |
| 1221 | + int resolve_flags, |
| 1222 | + unsigned char *sha1, int *flags) |
1198 | 1223 | { |
1199 | 1224 | static struct strbuf sb_refname = STRBUF_INIT; |
1200 | 1225 | int unused_flags; |
@@ -1226,7 +1251,8 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags, |
1226 | 1251 | for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) { |
1227 | 1252 | unsigned int read_flags = 0; |
1228 | 1253 |
|
1229 | | - if (read_raw_ref(refname, sha1, &sb_refname, &read_flags)) { |
| 1254 | + if (refs->be->read_raw_ref(refs, refname, |
| 1255 | + sha1, &sb_refname, &read_flags)) { |
1230 | 1256 | *flags |= read_flags; |
1231 | 1257 | if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING)) |
1232 | 1258 | return NULL; |
@@ -1265,3 +1291,266 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags, |
1265 | 1291 | errno = ELOOP; |
1266 | 1292 | return NULL; |
1267 | 1293 | } |
| 1294 | + |
| 1295 | +/* backend functions */ |
| 1296 | +int refs_init_db(struct strbuf *err) |
| 1297 | +{ |
| 1298 | + struct ref_store *refs = get_ref_store(NULL); |
| 1299 | + |
| 1300 | + return refs->be->init_db(refs, err); |
| 1301 | +} |
| 1302 | + |
| 1303 | +const char *resolve_ref_unsafe(const char *refname, int resolve_flags, |
| 1304 | + unsigned char *sha1, int *flags) |
| 1305 | +{ |
| 1306 | + return resolve_ref_recursively(get_ref_store(NULL), refname, |
| 1307 | + resolve_flags, sha1, flags); |
| 1308 | +} |
| 1309 | + |
| 1310 | +int resolve_gitlink_ref(const char *submodule, const char *refname, |
| 1311 | + unsigned char *sha1) |
| 1312 | +{ |
| 1313 | + size_t len = strlen(submodule); |
| 1314 | + struct ref_store *refs; |
| 1315 | + int flags; |
| 1316 | + |
| 1317 | + while (len && submodule[len - 1] == '/') |
| 1318 | + len--; |
| 1319 | + |
| 1320 | + if (!len) |
| 1321 | + return -1; |
| 1322 | + |
| 1323 | + if (submodule[len]) { |
| 1324 | + /* We need to strip off one or more trailing slashes */ |
| 1325 | + char *stripped = xmemdupz(submodule, len); |
| 1326 | + |
| 1327 | + refs = get_ref_store(stripped); |
| 1328 | + free(stripped); |
| 1329 | + } else { |
| 1330 | + refs = get_ref_store(submodule); |
| 1331 | + } |
| 1332 | + |
| 1333 | + if (!refs) |
| 1334 | + return -1; |
| 1335 | + |
| 1336 | + if (!resolve_ref_recursively(refs, refname, 0, sha1, &flags) || |
| 1337 | + is_null_sha1(sha1)) |
| 1338 | + return -1; |
| 1339 | + return 0; |
| 1340 | +} |
| 1341 | + |
| 1342 | +/* A pointer to the ref_store for the main repository: */ |
| 1343 | +static struct ref_store *main_ref_store; |
| 1344 | + |
| 1345 | +/* A linked list of ref_stores for submodules: */ |
| 1346 | +static struct ref_store *submodule_ref_stores; |
| 1347 | + |
| 1348 | +void base_ref_store_init(struct ref_store *refs, |
| 1349 | + const struct ref_storage_be *be, |
| 1350 | + const char *submodule) |
| 1351 | +{ |
| 1352 | + refs->be = be; |
| 1353 | + if (!submodule) { |
| 1354 | + if (main_ref_store) |
| 1355 | + die("BUG: main_ref_store initialized twice"); |
| 1356 | + |
| 1357 | + refs->submodule = ""; |
| 1358 | + refs->next = NULL; |
| 1359 | + main_ref_store = refs; |
| 1360 | + } else { |
| 1361 | + if (lookup_ref_store(submodule)) |
| 1362 | + die("BUG: ref_store for submodule '%s' initialized twice", |
| 1363 | + submodule); |
| 1364 | + |
| 1365 | + refs->submodule = xstrdup(submodule); |
| 1366 | + refs->next = submodule_ref_stores; |
| 1367 | + submodule_ref_stores = refs; |
| 1368 | + } |
| 1369 | +} |
| 1370 | + |
| 1371 | +struct ref_store *ref_store_init(const char *submodule) |
| 1372 | +{ |
| 1373 | + const char *be_name = "files"; |
| 1374 | + struct ref_storage_be *be = find_ref_storage_backend(be_name); |
| 1375 | + |
| 1376 | + if (!be) |
| 1377 | + die("BUG: reference backend %s is unknown", be_name); |
| 1378 | + |
| 1379 | + if (!submodule || !*submodule) |
| 1380 | + return be->init(NULL); |
| 1381 | + else |
| 1382 | + return be->init(submodule); |
| 1383 | +} |
| 1384 | + |
| 1385 | +struct ref_store *lookup_ref_store(const char *submodule) |
| 1386 | +{ |
| 1387 | + struct ref_store *refs; |
| 1388 | + |
| 1389 | + if (!submodule || !*submodule) |
| 1390 | + return main_ref_store; |
| 1391 | + |
| 1392 | + for (refs = submodule_ref_stores; refs; refs = refs->next) { |
| 1393 | + if (!strcmp(submodule, refs->submodule)) |
| 1394 | + return refs; |
| 1395 | + } |
| 1396 | + |
| 1397 | + return NULL; |
| 1398 | +} |
| 1399 | + |
| 1400 | +struct ref_store *get_ref_store(const char *submodule) |
| 1401 | +{ |
| 1402 | + struct ref_store *refs; |
| 1403 | + |
| 1404 | + if (!submodule || !*submodule) { |
| 1405 | + refs = lookup_ref_store(NULL); |
| 1406 | + |
| 1407 | + if (!refs) |
| 1408 | + refs = ref_store_init(NULL); |
| 1409 | + } else { |
| 1410 | + refs = lookup_ref_store(submodule); |
| 1411 | + |
| 1412 | + if (!refs) { |
| 1413 | + struct strbuf submodule_sb = STRBUF_INIT; |
| 1414 | + |
| 1415 | + strbuf_addstr(&submodule_sb, submodule); |
| 1416 | + if (is_nonbare_repository_dir(&submodule_sb)) |
| 1417 | + refs = ref_store_init(submodule); |
| 1418 | + strbuf_release(&submodule_sb); |
| 1419 | + } |
| 1420 | + } |
| 1421 | + |
| 1422 | + return refs; |
| 1423 | +} |
| 1424 | + |
| 1425 | +void assert_main_repository(struct ref_store *refs, const char *caller) |
| 1426 | +{ |
| 1427 | + if (*refs->submodule) |
| 1428 | + die("BUG: %s called for a submodule", caller); |
| 1429 | +} |
| 1430 | + |
| 1431 | +/* backend functions */ |
| 1432 | +int pack_refs(unsigned int flags) |
| 1433 | +{ |
| 1434 | + struct ref_store *refs = get_ref_store(NULL); |
| 1435 | + |
| 1436 | + return refs->be->pack_refs(refs, flags); |
| 1437 | +} |
| 1438 | + |
| 1439 | +int peel_ref(const char *refname, unsigned char *sha1) |
| 1440 | +{ |
| 1441 | + struct ref_store *refs = get_ref_store(NULL); |
| 1442 | + |
| 1443 | + return refs->be->peel_ref(refs, refname, sha1); |
| 1444 | +} |
| 1445 | + |
| 1446 | +int create_symref(const char *ref_target, const char *refs_heads_master, |
| 1447 | + const char *logmsg) |
| 1448 | +{ |
| 1449 | + struct ref_store *refs = get_ref_store(NULL); |
| 1450 | + |
| 1451 | + return refs->be->create_symref(refs, ref_target, refs_heads_master, |
| 1452 | + logmsg); |
| 1453 | +} |
| 1454 | + |
| 1455 | +int ref_transaction_commit(struct ref_transaction *transaction, |
| 1456 | + struct strbuf *err) |
| 1457 | +{ |
| 1458 | + struct ref_store *refs = get_ref_store(NULL); |
| 1459 | + |
| 1460 | + return refs->be->transaction_commit(refs, transaction, err); |
| 1461 | +} |
| 1462 | + |
| 1463 | +int verify_refname_available(const char *refname, |
| 1464 | + const struct string_list *extra, |
| 1465 | + const struct string_list *skip, |
| 1466 | + struct strbuf *err) |
| 1467 | +{ |
| 1468 | + struct ref_store *refs = get_ref_store(NULL); |
| 1469 | + |
| 1470 | + return refs->be->verify_refname_available(refs, refname, extra, skip, err); |
| 1471 | +} |
| 1472 | + |
| 1473 | +int for_each_reflog(each_ref_fn fn, void *cb_data) |
| 1474 | +{ |
| 1475 | + struct ref_store *refs = get_ref_store(NULL); |
| 1476 | + struct ref_iterator *iter; |
| 1477 | + |
| 1478 | + iter = refs->be->reflog_iterator_begin(refs); |
| 1479 | + |
| 1480 | + return do_for_each_ref_iterator(iter, fn, cb_data); |
| 1481 | +} |
| 1482 | + |
| 1483 | +int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, |
| 1484 | + void *cb_data) |
| 1485 | +{ |
| 1486 | + struct ref_store *refs = get_ref_store(NULL); |
| 1487 | + |
| 1488 | + return refs->be->for_each_reflog_ent_reverse(refs, refname, |
| 1489 | + fn, cb_data); |
| 1490 | +} |
| 1491 | + |
| 1492 | +int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, |
| 1493 | + void *cb_data) |
| 1494 | +{ |
| 1495 | + struct ref_store *refs = get_ref_store(NULL); |
| 1496 | + |
| 1497 | + return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data); |
| 1498 | +} |
| 1499 | + |
| 1500 | +int reflog_exists(const char *refname) |
| 1501 | +{ |
| 1502 | + struct ref_store *refs = get_ref_store(NULL); |
| 1503 | + |
| 1504 | + return refs->be->reflog_exists(refs, refname); |
| 1505 | +} |
| 1506 | + |
| 1507 | +int safe_create_reflog(const char *refname, int force_create, |
| 1508 | + struct strbuf *err) |
| 1509 | +{ |
| 1510 | + struct ref_store *refs = get_ref_store(NULL); |
| 1511 | + |
| 1512 | + return refs->be->create_reflog(refs, refname, force_create, err); |
| 1513 | +} |
| 1514 | + |
| 1515 | +int delete_reflog(const char *refname) |
| 1516 | +{ |
| 1517 | + struct ref_store *refs = get_ref_store(NULL); |
| 1518 | + |
| 1519 | + return refs->be->delete_reflog(refs, refname); |
| 1520 | +} |
| 1521 | + |
| 1522 | +int reflog_expire(const char *refname, const unsigned char *sha1, |
| 1523 | + unsigned int flags, |
| 1524 | + reflog_expiry_prepare_fn prepare_fn, |
| 1525 | + reflog_expiry_should_prune_fn should_prune_fn, |
| 1526 | + reflog_expiry_cleanup_fn cleanup_fn, |
| 1527 | + void *policy_cb_data) |
| 1528 | +{ |
| 1529 | + struct ref_store *refs = get_ref_store(NULL); |
| 1530 | + |
| 1531 | + return refs->be->reflog_expire(refs, refname, sha1, flags, |
| 1532 | + prepare_fn, should_prune_fn, |
| 1533 | + cleanup_fn, policy_cb_data); |
| 1534 | +} |
| 1535 | + |
| 1536 | +int initial_ref_transaction_commit(struct ref_transaction *transaction, |
| 1537 | + struct strbuf *err) |
| 1538 | +{ |
| 1539 | + struct ref_store *refs = get_ref_store(NULL); |
| 1540 | + |
| 1541 | + return refs->be->initial_transaction_commit(refs, transaction, err); |
| 1542 | +} |
| 1543 | + |
| 1544 | +int delete_refs(struct string_list *refnames, unsigned int flags) |
| 1545 | +{ |
| 1546 | + struct ref_store *refs = get_ref_store(NULL); |
| 1547 | + |
| 1548 | + return refs->be->delete_refs(refs, refnames, flags); |
| 1549 | +} |
| 1550 | + |
| 1551 | +int rename_ref(const char *oldref, const char *newref, const char *logmsg) |
| 1552 | +{ |
| 1553 | + struct ref_store *refs = get_ref_store(NULL); |
| 1554 | + |
| 1555 | + return refs->be->rename_ref(refs, oldref, newref, logmsg); |
| 1556 | +} |
0 commit comments