| 2502 | } |
| 2503 | |
| 2504 | int refs_update_symref_extended(struct ref_store *refs, const char *ref, |
| 2505 | const char *target, const char *logmsg, |
| 2506 | struct strbuf *referent, int create_only) |
| 2507 | { |
| 2508 | struct ref_transaction *transaction; |
| 2509 | struct strbuf err = STRBUF_INIT; |
| 2510 | int ret = 0, prepret = 0; |
| 2511 | |
| 2512 | transaction = ref_store_transaction_begin(refs, 0, &err); |
| 2513 | if (!transaction) { |
| 2514 | error_return: |
| 2515 | ret = error("%s", err.buf); |
| 2516 | goto cleanup; |
| 2517 | } |
| 2518 | if (create_only) { |
| 2519 | if (ref_transaction_create(transaction, ref, NULL, target, |
| 2520 | REF_NO_DEREF, logmsg, &err)) |
| 2521 | goto error_return; |
| 2522 | prepret = ref_transaction_prepare(transaction, &err); |
| 2523 | if (prepret && prepret != REF_TRANSACTION_ERROR_CREATE_EXISTS) |
| 2524 | goto error_return; |
| 2525 | } else { |
| 2526 | if (ref_transaction_update(transaction, ref, NULL, NULL, |
| 2527 | target, NULL, REF_NO_DEREF, |
| 2528 | logmsg, &err) || |
| 2529 | ref_transaction_prepare(transaction, &err)) |
| 2530 | goto error_return; |
| 2531 | } |
| 2532 | |
| 2533 | if (referent && refs_read_symbolic_ref(refs, ref, referent) == NOT_A_SYMREF) { |
| 2534 | struct object_id oid; |
| 2535 | if (!refs_read_ref(refs, ref, &oid)) { |
| 2536 | strbuf_add_oid_hex(referent, &oid); |
| 2537 | ret = NOT_A_SYMREF; |
| 2538 | } |
| 2539 | } |
| 2540 | |
| 2541 | if (prepret == REF_TRANSACTION_ERROR_CREATE_EXISTS) |
| 2542 | goto cleanup; |
| 2543 | |
| 2544 | if (ref_transaction_commit(transaction, &err)) |
| 2545 | goto error_return; |
| 2546 | |
| 2547 | cleanup: |
| 2548 | strbuf_release(&err); |
| 2549 | if (transaction) |
| 2550 | ref_transaction_free(transaction); |
| 2551 | |
| 2552 | return ret; |
| 2553 | } |
| 2554 | |
| 2555 | /* |
| 2556 | * Write an error to `err` and return a nonzero value iff the same |
no test coverage detected