Skip to content

Commit 029cdb4

Browse files
rsahlberggitster
authored andcommitted
refs.c: make prune_ref use a transaction to delete the ref
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 <[email protected]> Reviewed-by: Michael Haggerty <[email protected]> Signed-off-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cba1202 commit 029cdb4

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

refs.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ static unsigned char refname_disposition[256] = {
2424
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4
2525
};
2626

27+
/*
28+
* Used as a flag to ref_transaction_delete when a loose ref is being
29+
* pruned.
30+
*/
31+
#define REF_ISPRUNING 0x0100
2732
/*
2833
* Try to read one refname component from the front of refname.
2934
* Return the length of the component found, or -1 if the component is
@@ -2382,17 +2387,25 @@ static void try_remove_empty_parents(char *name)
23822387
/* make sure nobody touched the ref, and unlink */
23832388
static void prune_ref(struct ref_to_prune *r)
23842389
{
2385-
struct ref_lock *lock;
2390+
struct ref_transaction *transaction;
2391+
struct strbuf err = STRBUF_INIT;
23862392

23872393
if (check_refname_format(r->name + 5, 0))
23882394
return;
23892395

2390-
lock = lock_ref_sha1_basic(r->name, r->sha1, 0, NULL);
2391-
if (lock) {
2392-
unlink_or_warn(git_path("%s", r->name));
2393-
unlock_ref(lock);
2394-
try_remove_empty_parents(r->name);
2396+
transaction = ref_transaction_begin(&err);
2397+
if (!transaction ||
2398+
ref_transaction_delete(transaction, r->name, r->sha1,
2399+
REF_ISPRUNING, 1, &err) ||
2400+
ref_transaction_commit(transaction, NULL, &err)) {
2401+
ref_transaction_free(transaction);
2402+
error("%s", err.buf);
2403+
strbuf_release(&err);
2404+
return;
23952405
}
2406+
ref_transaction_free(transaction);
2407+
strbuf_release(&err);
2408+
try_remove_empty_parents(r->name);
23962409
}
23972410

23982411
static void prune_refs(struct ref_to_prune *r)
@@ -3598,8 +3611,9 @@ int ref_transaction_commit(struct ref_transaction *transaction,
35983611
struct ref_update *update = updates[i];
35993612

36003613
if (update->lock) {
3601-
delnames[delnum++] = update->lock->ref_name;
36023614
ret |= delete_ref_loose(update->lock, update->type);
3615+
if (!(update->flags & REF_ISPRUNING))
3616+
delnames[delnum++] = update->lock->ref_name;
36033617
}
36043618
}
36053619

refs.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,18 @@ extern int ref_exists(const char *);
170170
*/
171171
extern int peel_ref(const char *refname, unsigned char *sha1);
172172

173-
/** Locks any ref (for 'HEAD' type refs). */
173+
/*
174+
* Flags controlling lock_any_ref_for_update(), ref_transaction_update(),
175+
* ref_transaction_create(), etc.
176+
* REF_NODEREF: act on the ref directly, instead of dereferencing
177+
* symbolic references.
178+
*
179+
* Flags >= 0x100 are reserved for internal use.
180+
*/
174181
#define REF_NODEREF 0x01
175-
/* errno is set to something meaningful on failure */
182+
/*
183+
* This function sets errno to something meaningful on failure.
184+
*/
176185
extern struct ref_lock *lock_any_ref_for_update(const char *refname,
177186
const unsigned char *old_sha1,
178187
int flags, int *type_p);

0 commit comments

Comments
 (0)