| 1388 | } |
| 1389 | |
| 1390 | enum ref_transaction_error ref_transaction_update(struct ref_transaction *transaction, |
| 1391 | const char *refname, |
| 1392 | const struct object_id *new_oid, |
| 1393 | const struct object_id *old_oid, |
| 1394 | const char *new_target, |
| 1395 | const char *old_target, |
| 1396 | unsigned int flags, const char *msg, |
| 1397 | struct strbuf *err) |
| 1398 | { |
| 1399 | struct object_id peeled; |
| 1400 | |
| 1401 | assert(err); |
| 1402 | |
| 1403 | if ((flags & REF_FORCE_CREATE_REFLOG) && |
| 1404 | (flags & REF_SKIP_CREATE_REFLOG)) { |
| 1405 | strbuf_addstr(err, _("refusing to force and skip creation of reflog")); |
| 1406 | return REF_TRANSACTION_ERROR_GENERIC; |
| 1407 | } |
| 1408 | |
| 1409 | if (!transaction_refname_valid(refname, new_oid, flags, err)) |
| 1410 | return REF_TRANSACTION_ERROR_GENERIC; |
| 1411 | |
| 1412 | if (flags & ~REF_TRANSACTION_UPDATE_ALLOWED_FLAGS) |
| 1413 | BUG("illegal flags 0x%x passed to ref_transaction_update()", flags); |
| 1414 | |
| 1415 | /* |
| 1416 | * Clear flags outside the allowed set; this should be a noop because |
| 1417 | * of the BUG() check above, but it works around a -Wnonnull warning |
| 1418 | * with some versions of "gcc -O3". |
| 1419 | */ |
| 1420 | flags &= REF_TRANSACTION_UPDATE_ALLOWED_FLAGS; |
| 1421 | |
| 1422 | flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0); |
| 1423 | flags |= (new_target ? REF_HAVE_NEW : 0) | (old_target ? REF_HAVE_OLD : 0); |
| 1424 | |
| 1425 | if ((flags & REF_HAVE_NEW) && !new_target && !is_null_oid(new_oid) && |
| 1426 | !(flags & REF_SKIP_OID_VERIFICATION) && !(flags & REF_LOG_ONLY)) { |
| 1427 | struct object *o = parse_object(transaction->ref_store->repo, new_oid); |
| 1428 | |
| 1429 | if (!o) { |
| 1430 | strbuf_addf(err, |
| 1431 | _("trying to write ref '%s' with nonexistent object %s"), |
| 1432 | refname, oid_to_hex(new_oid)); |
| 1433 | return REF_TRANSACTION_ERROR_INVALID_NEW_VALUE; |
| 1434 | } |
| 1435 | |
| 1436 | if (o->type != OBJ_COMMIT && is_branch(refname)) { |
| 1437 | strbuf_addf(err, _("trying to write non-commit object %s to branch '%s'"), |
| 1438 | oid_to_hex(new_oid), refname); |
| 1439 | return REF_TRANSACTION_ERROR_INVALID_NEW_VALUE; |
| 1440 | } |
| 1441 | |
| 1442 | if (o->type == OBJ_TAG) { |
| 1443 | if (!peel_object(transaction->ref_store->repo, new_oid, &peeled, |
| 1444 | PEEL_OBJECT_VERIFY_TAGGED_OBJECT_TYPE)) |
| 1445 | flags |= REF_HAVE_PEELED; |
| 1446 | } |
| 1447 | } |
no test coverage detected