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.
This commit is contained in:
parent
300e9ad43d
commit
b150c546b0
39
guix/git.scm
39
guix/git.scm
@ -1,6 +1,6 @@
|
|||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2017, 2020 Mathieu Othacehe <m.othacehe@gmail.com>
|
;;; 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 Kyle Meyer <kyle@kyleam.com>
|
||||||
;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
|
;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
|
||||||
;;; Copyright © 2022 Maxime Devos <maximedevos@telenet.be>
|
;;; Copyright © 2022 Maxime Devos <maximedevos@telenet.be>
|
||||||
@ -29,7 +29,7 @@
|
|||||||
#:use-module (guix cache)
|
#:use-module (guix cache)
|
||||||
#:use-module (gcrypt hash)
|
#:use-module (gcrypt hash)
|
||||||
#:use-module ((guix build utils)
|
#: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 store)
|
||||||
#:use-module (guix utils)
|
#:use-module (guix utils)
|
||||||
#:use-module (guix records)
|
#:use-module (guix records)
|
||||||
@ -38,8 +38,9 @@
|
|||||||
#:use-module (guix gexp)
|
#:use-module (guix gexp)
|
||||||
#:autoload (guix git-download)
|
#:autoload (guix git-download)
|
||||||
(git-reference-url git-reference-commit git-reference-recursive?)
|
(git-reference-url git-reference-commit git-reference-recursive?)
|
||||||
|
#:autoload (guix config) (%git)
|
||||||
#:use-module (guix sets)
|
#:use-module (guix sets)
|
||||||
#:use-module ((guix diagnostics) #:select (leave warning))
|
#:use-module ((guix diagnostics) #:select (leave warning info))
|
||||||
#:use-module (guix progress)
|
#:use-module (guix progress)
|
||||||
#:autoload (guix swh) (swh-download commit-id?)
|
#:autoload (guix swh) (swh-download commit-id?)
|
||||||
#:use-module (rnrs bytevectors)
|
#:use-module (rnrs bytevectors)
|
||||||
@ -430,6 +431,35 @@ could not be fetched from Software Heritage~%")
|
|||||||
(rename-file directory trashed)
|
(rename-file directory trashed)
|
||||||
(delete-file-recursively 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
|
(define* (update-cached-checkout url
|
||||||
#:key
|
#:key
|
||||||
(ref '())
|
(ref '())
|
||||||
@ -517,6 +547,9 @@ it unchanged."
|
|||||||
seconds seconds
|
seconds seconds
|
||||||
nanoseconds nanoseconds))))
|
nanoseconds nanoseconds))))
|
||||||
|
|
||||||
|
;; Run 'git gc' if needed.
|
||||||
|
(maybe-run-git-gc cache-directory)
|
||||||
|
|
||||||
;; When CACHE-DIRECTORY is a sub-directory of the default cache
|
;; When CACHE-DIRECTORY is a sub-directory of the default cache
|
||||||
;; directory, remove expired checkouts that are next to it.
|
;; directory, remove expired checkouts that are next to it.
|
||||||
(let ((parent (dirname cache-directory)))
|
(let ((parent (dirname cache-directory)))
|
||||||
|
Loading…
Reference in New Issue
Block a user