From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jonathan Nieder Subject: [PATCH 19/22] refs.c: make prune_ref use a transaction to delete the ref Date: Tue, 2 Sep 2014 14:09:46 -0700 Message-ID: <20140902210946.GT18279@google.com> References: <20140820231723.GF20185@google.com> <20140826000354.GW20185@google.com> <20140826221448.GY20185@google.com> <20140827002804.GA20185@google.com> <20140902205841.GA18279@google.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: Ronnie Sahlberg , "git@vger.kernel.org" , Michael Haggerty To: Junio C Hamano X-From: git-owner@vger.kernel.org Tue Sep 02 23:09:59 2014 Return-path: Envelope-to: gcvg-git-2@plane.gmane.org Received: from vger.kernel.org ([209.132.180.67]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1XOvKr-0006Sd-U4 for gcvg-git-2@plane.gmane.org; Tue, 02 Sep 2014 23:09:54 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755125AbaIBVJu (ORCPT ); Tue, 2 Sep 2014 17:09:50 -0400 Received: from mail-pa0-f41.google.com ([209.85.220.41]:43282 "EHLO mail-pa0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754776AbaIBVJt (ORCPT ); Tue, 2 Sep 2014 17:09:49 -0400 Received: by mail-pa0-f41.google.com with SMTP id lj1so15625191pab.14 for ; Tue, 02 Sep 2014 14:09:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=/4QjfRcutK1Ozzrn/hHud680udf5cRwb5Xt67lvXc5U=; b=BfVf/puyoJL2vcggMwqvS3RowMPuUJnhGKbPkzLWD8UgLEXfjs0oeGhHnLfEVl5iPr gqtHmTYWKHhLtK7AxcJHDTc+LBMd1qQ5rehyYBZDAmKz8H9j3e9l0ObBF6J+S+bJWtrq kQitWjSVw9srHDvlh0hINj0Tq0ybS50SDTOOkvTpHCwoSLUmK6ePwKIWqQNTLdyevNfZ pHAT2tOpCOrFtuPwwMl53mjuFJzTT264zkJuxodFaURu9FMpOEMHPHdB1VpiIHipCuQ1 OSjYhToxiDNYsk719SkdVQqPTWPTgfYH4YTHRJDyDs644ghhCVN4zGrBhdN5LcN7aFoB gKHA== X-Received: by 10.70.5.33 with SMTP id p1mr22722486pdp.134.1409692188947; Tue, 02 Sep 2014 14:09:48 -0700 (PDT) Received: from google.com (aiede.mtv.corp.google.com [172.27.69.120]) by mx.google.com with ESMTPSA id v1sm6799343pdg.28.2014.09.02.14.09.47 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 02 Sep 2014 14:09:48 -0700 (PDT) Content-Disposition: inline In-Reply-To: <20140902205841.GA18279@google.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: From: Ronnie Sahlberg Date: Wed, 30 Apr 2014 09:03:36 -0700 Change prune_ref to delete the ref using a ref transaction. To do this we also need to add a new flag REF_ISPRUNING that will tell the transaction that we do not want to delete this ref from the packed refs. This flag is private to refs.c and not exposed to external callers. Signed-off-by: Ronnie Sahlberg Reviewed-by: Michael Haggerty Signed-off-by: Jonathan Nieder --- refs.c | 28 +++++++++++++++++++++------- refs.h | 13 +++++++++++-- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/refs.c b/refs.c index fd67684..22eb3dd 100644 --- a/refs.c +++ b/refs.c @@ -25,6 +25,11 @@ static unsigned char refname_disposition[256] = { }; /* + * Used as a flag to ref_transaction_delete when a loose ref is being + * pruned. + */ +#define REF_ISPRUNING 0x0100 +/* * Try to read one refname component from the front of refname. * Return the length of the component found, or -1 if the component is * not legal. It is legal if it is something reasonable to have under @@ -2382,17 +2387,25 @@ static void try_remove_empty_parents(char *name) /* make sure nobody touched the ref, and unlink */ static void prune_ref(struct ref_to_prune *r) { - struct ref_lock *lock; + struct ref_transaction *transaction; + struct strbuf err = STRBUF_INIT; if (check_refname_format(r->name + 5, 0)) return; - lock = lock_ref_sha1_basic(r->name, r->sha1, 0, NULL); - if (lock) { - unlink_or_warn(git_path("%s", r->name)); - unlock_ref(lock); - try_remove_empty_parents(r->name); + transaction = ref_transaction_begin(&err); + if (!transaction || + ref_transaction_delete(transaction, r->name, r->sha1, + REF_ISPRUNING, 1, &err) || + ref_transaction_commit(transaction, NULL, &err)) { + ref_transaction_free(transaction); + error("%s", err.buf); + strbuf_release(&err); + return; } + ref_transaction_free(transaction); + strbuf_release(&err); + try_remove_empty_parents(r->name); } static void prune_refs(struct ref_to_prune *r) @@ -3598,8 +3611,9 @@ int ref_transaction_commit(struct ref_transaction *transaction, struct ref_update *update = updates[i]; if (update->lock) { - delnames[delnum++] = update->lock->ref_name; ret |= delete_ref_loose(update->lock, update->type); + if (!(update->flags & REF_ISPRUNING)) + delnames[delnum++] = update->lock->ref_name; } } diff --git a/refs.h b/refs.h index 65dd593..69ef28c 100644 --- a/refs.h +++ b/refs.h @@ -170,9 +170,18 @@ extern int ref_exists(const char *); */ extern int peel_ref(const char *refname, unsigned char *sha1); -/** Locks any ref (for 'HEAD' type refs). */ +/* + * Flags controlling lock_any_ref_for_update(), ref_transaction_update(), + * ref_transaction_create(), etc. + * REF_NODEREF: act on the ref directly, instead of dereferencing + * symbolic references. + * + * Flags >= 0x100 are reserved for internal use. + */ #define REF_NODEREF 0x01 -/* errno is set to something meaningful on failure */ +/* + * This function sets errno to something meaningful on failure. + */ extern struct ref_lock *lock_any_ref_for_update(const char *refname, const unsigned char *old_sha1, int flags, int *type_p); -- 2.1.0.rc2.206.gedb03e5