Skip to content

Commit 5f03e51

Browse files
Will Chandlergitster
authored andcommitted
refs: cleanup directories when deleting packed ref
When deleting a packed ref via 'update-ref -d', a lockfile is made in the directory that would contain the loose copy of that ref, creating any directories in the ref's path that do not exist. When the transaction completes, the lockfile is deleted, but any empty parent directories made when creating the lockfile are left in place. These empty directories are not removed by 'pack-refs' or other housekeeping tasks and will accumulate over time. When deleting a loose ref, we remove all empty parent directories at the end of the transaction. This commit applies the parent directory cleanup logic used when deleting loose refs to packed refs as well. Signed-off-by: Will Chandler <[email protected]> Reviewed-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 48bf2fa commit 5f03e51

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

refs/files-backend.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@
4545
#define REF_UPDATE_VIA_HEAD (1 << 8)
4646

4747
/*
48-
* Used as a flag in ref_update::flags when the loose reference has
49-
* been deleted.
48+
* Used as a flag in ref_update::flags when a reference has been
49+
* deleted and the ref's parent directories may need cleanup.
5050
*/
51-
#define REF_DELETED_LOOSE (1 << 9)
51+
#define REF_DELETED_RMDIR (1 << 9)
5252

5353
struct ref_lock {
5454
char *ref_name;
@@ -2852,6 +2852,7 @@ static int files_transaction_finish(struct ref_store *ref_store,
28522852

28532853
if (update->flags & REF_DELETING &&
28542854
!(update->flags & REF_LOG_ONLY)) {
2855+
update->flags |= REF_DELETED_RMDIR;
28552856
if (!(update->type & REF_ISPACKED) ||
28562857
update->type & REF_ISSYMREF) {
28572858
/* It is a loose reference. */
@@ -2861,7 +2862,6 @@ static int files_transaction_finish(struct ref_store *ref_store,
28612862
ret = TRANSACTION_GENERIC_ERROR;
28622863
goto cleanup;
28632864
}
2864-
update->flags |= REF_DELETED_LOOSE;
28652865
}
28662866
}
28672867
}
@@ -2874,9 +2874,9 @@ static int files_transaction_finish(struct ref_store *ref_store,
28742874
for (i = 0; i < transaction->nr; i++) {
28752875
struct ref_update *update = transaction->updates[i];
28762876

2877-
if (update->flags & REF_DELETED_LOOSE) {
2877+
if (update->flags & REF_DELETED_RMDIR) {
28782878
/*
2879-
* The loose reference was deleted. Delete any
2879+
* The reference was deleted. Delete any
28802880
* empty parent directories. (Note that this
28812881
* can only work because we have already
28822882
* removed the lockfile.)

t/t1400-update-ref.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,4 +1598,13 @@ test_expect_success 'transaction cannot restart ongoing transaction' '
15981598
test_must_fail git show-ref --verify refs/heads/restart
15991599
'
16001600

1601+
test_expect_success 'directory not created deleting packed ref' '
1602+
git branch d1/d2/r1 HEAD &&
1603+
git pack-refs --all &&
1604+
test_path_is_missing .git/refs/heads/d1/d2 &&
1605+
git update-ref -d refs/heads/d1/d2/r1 &&
1606+
test_path_is_missing .git/refs/heads/d1/d2 &&
1607+
test_path_is_missing .git/refs/heads/d1
1608+
'
1609+
16011610
test_done

0 commit comments

Comments
 (0)