*/
packed_refs_path = get_locked_file_path(&refs->lock);
strbuf_addf(&sb, "%s.new", packed_refs_path);
- if (create_tempfile(&refs->tempfile, sb.buf) < 0) {
+ free(packed_refs_path);
+ refs->tempfile = create_tempfile(sb.buf);
+ if (!refs->tempfile) {
strbuf_addf(err, "unable to create file %s: %s",
sb.buf, strerror(errno));
strbuf_release(&sb);
goto error;
}
- if (rename_tempfile(&refs->tempfile, packed_refs_path)) {
- strbuf_addf(err, "error replacing %s: %s",
- refs->path, strerror(errno));
- goto out;
- if (close_tempfile(&refs->tempfile)) {
++ if (close_tempfile_gently(refs->tempfile)) {
+ strbuf_addf(err, "error closing file %s: %s",
- get_tempfile_path(&refs->tempfile),
++ get_tempfile_path(refs->tempfile),
+ strerror(errno));
+ strbuf_release(&sb);
++ delete_tempfile(&refs->tempfile);
+ return -1;
}
- ret = 0;
- goto out;
+ return 0;
+
+ write_error:
+ strbuf_addf(err, "error writing to %s: %s",
- get_tempfile_path(&refs->tempfile), strerror(errno));
++ get_tempfile_path(refs->tempfile), strerror(errno));
error:
- delete_tempfile(&refs->tempfile);
+ if (iter)
+ ref_iterator_abort(iter);
- out:
- free(packed_refs_path);
- return ret;
+ delete_tempfile(&refs->tempfile);
+ return -1;
}
- /*
- * Rewrite the packed-refs file, omitting any refs listed in
- * 'refnames'. On error, leave packed-refs unchanged, write an error
- * message to 'err', and return a nonzero value. The packed refs lock
- * must be held when calling this function; it will still be held when
- * the function returns.
- *
- * The refs in 'refnames' needn't be sorted. `err` must not be NULL.
- */
- int repack_without_refs(struct ref_store *ref_store,
- struct string_list *refnames, struct strbuf *err)
+ struct packed_transaction_backend_data {
+ /* True iff the transaction owns the packed-refs lock. */
+ int own_lock;
+
+ struct string_list updates;
+ };
+
+ static void packed_transaction_cleanup(struct packed_ref_store *refs,
+ struct ref_transaction *transaction)
{
- struct packed_ref_store *refs =
- packed_downcast(ref_store, REF_STORE_WRITE | REF_STORE_MAIN,
- "repack_without_refs");
- struct ref_dir *packed;
- struct string_list_item *refname;
- int needs_repacking = 0, removed = 0;
+ struct packed_transaction_backend_data *data = transaction->backend_data;
- packed_assert_main_repository(refs, "repack_without_refs");
- assert(err);
+ if (data) {
+ string_list_clear(&data->updates, 0);
- if (!is_lock_file_locked(&refs->lock))
- die("BUG: repack_without_refs called without holding lock");
- if (is_tempfile_active(&refs->tempfile))
++ if (is_tempfile_active(refs->tempfile))
+ delete_tempfile(&refs->tempfile);
- /* Look for a packed ref */
- for_each_string_list_item(refname, refnames) {
- if (get_packed_ref(refs, refname->string)) {
- needs_repacking = 1;
- break;
+ if (data->own_lock && is_lock_file_locked(&refs->lock)) {
+ packed_refs_unlock(&refs->base);
+ data->own_lock = 0;
}
- }
- /* Avoid locking if we have nothing to do */
- if (!needs_repacking)
- return 0; /* no refname exists in packed refs */
-
- packed = get_packed_refs(refs);
-
- /* Remove refnames from the cache */
- for_each_string_list_item(refname, refnames)
- if (remove_entry_from_dir(packed, refname->string) != -1)
- removed = 1;
- if (!removed) {
- /*
- * All packed entries disappeared while we were
- * acquiring the lock.
- */
- clear_packed_ref_cache(refs);
- return 0;
+ free(data);
+ transaction->backend_data = NULL;
}
- /* Write what remains */
- return commit_packed_refs(&refs->base, err);
- }
-
- static int packed_init_db(struct ref_store *ref_store, struct strbuf *err)
- {
- /* Nothing to do. */
- return 0;
+ transaction->state = REF_TRANSACTION_CLOSED;
}
static int packed_transaction_prepare(struct ref_store *ref_store,