git: Shell out to ‘git gc’ when necessary.
Fixes <https://issues.guix.gnu.org/65720>. This fixes a bug whereby libgit2-managed checkouts would keep growing as we fetch. * guix/git.scm (packs-in-git-repository, maybe-run-git-gc): New procedures. (update-cached-checkout): Use it.master
parent
300e9ad43d
commit
b150c546b0
39
guix/git.scm
39
guix/git.scm
|
@ -1,6 +1,6 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2017, 2020 Mathieu Othacehe <m.othacehe@gmail.com>
|
||||
;;; Copyright © 2018-2022 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2018-2023 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2021 Kyle Meyer <kyle@kyleam.com>
|
||||
;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
|
||||
;;; Copyright © 2022 Maxime Devos <maximedevos@telenet.be>
|
||||
|
@ -29,7 +29,7 @@
|
|||
#:use-module (guix cache)
|
||||
#:use-module (gcrypt hash)
|
||||
#:use-module ((guix build utils)
|
||||
#:select (mkdir-p delete-file-recursively))
|
||||
#:select (mkdir-p delete-file-recursively invoke/quiet))
|
||||
#:use-module (guix store)
|
||||
#:use-module (guix utils)
|
||||
#:use-module (guix records)
|
||||
|
@ -38,8 +38,9 @@
|
|||
#:use-module (guix gexp)
|
||||
#:autoload (guix git-download)
|
||||
(git-reference-url git-reference-commit git-reference-recursive?)
|
||||
#:autoload (guix config) (%git)
|
||||
#:use-module (guix sets)
|
||||
#:use-module ((guix diagnostics) #:select (leave warning))
|
||||
#:use-module ((guix diagnostics) #:select (leave warning info))
|
||||
#:use-module (guix progress)
|
||||
#:autoload (guix swh) (swh-download commit-id?)
|
||||
#:use-module (rnrs bytevectors)
|
||||
|
@ -430,6 +431,35 @@ could not be fetched from Software Heritage~%")
|
|||
(rename-file directory trashed)
|
||||
(delete-file-recursively trashed)))
|
||||
|
||||
(define (packs-in-git-repository directory)
|
||||
"Return the number of pack files under DIRECTORY, a Git checkout."
|
||||
(catch 'system-error
|
||||
(lambda ()
|
||||
(let ((directory (opendir (in-vicinity directory ".git/objects/pack"))))
|
||||
(let loop ((count 0))
|
||||
(match (readdir directory)
|
||||
((? eof-object?)
|
||||
(closedir directory)
|
||||
count)
|
||||
(str
|
||||
(loop (if (string-suffix? ".pack" str)
|
||||
(+ 1 count)
|
||||
count)))))))
|
||||
(const 0)))
|
||||
|
||||
(define (maybe-run-git-gc directory)
|
||||
"Run 'git gc' in DIRECTORY if needed."
|
||||
;; XXX: As of libgit2 1.3.x (used by Guile-Git), there's no support for GC.
|
||||
;; Each time a checkout is pulled, a new pack is created, which eventually
|
||||
;; takes up a lot of space (lots of small, poorly-compressed packs). As a
|
||||
;; workaround, shell out to 'git gc' when the number of packs in a
|
||||
;; repository has become "too large", potentially wasting a lot of space.
|
||||
;; See <https://issues.guix.gnu.org/65720>.
|
||||
(when (> (packs-in-git-repository directory) 25)
|
||||
(info (G_ "compressing cached Git repository at '~a'...~%")
|
||||
directory)
|
||||
(invoke/quiet %git "-C" directory "gc")))
|
||||
|
||||
(define* (update-cached-checkout url
|
||||
#:key
|
||||
(ref '())
|
||||
|
@ -517,6 +547,9 @@ it unchanged."
|
|||
seconds seconds
|
||||
nanoseconds nanoseconds))))
|
||||
|
||||
;; Run 'git gc' if needed.
|
||||
(maybe-run-git-gc cache-directory)
|
||||
|
||||
;; When CACHE-DIRECTORY is a sub-directory of the default cache
|
||||
;; directory, remove expired checkouts that are next to it.
|
||||
(let ((parent (dirname cache-directory)))
|
||||
|
|
Reference in New Issue