Skip to content

Commit c2b7570

Browse files
bbhttbarthalion
andcommitted
builder-git: Add support for fetching and checking out Git LFS objects
This explicitly fetches Git LFS objects as long as git-lfs is available on host (but doesn't need to be configured) Fixes #463 Co-authored-by: Bartłomiej Piotrowski <b@bpiotrowski.pl>
1 parent b53b016 commit c2b7570

File tree

3 files changed

+100
-4
lines changed

3 files changed

+100
-4
lines changed

.github/workflows/check.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
libseccomp-dev libsystemd-dev libxml2-utils libgpgme11-dev gobject-introspection \
2727
libgirepository1.0-dev libappstream-dev libdconf-dev clang socat flatpak \
2828
libcurl4-gnutls-dev libflatpak-dev libyaml-dev elfutils git patch libarchive-tools \
29-
docbook-xsl xmlto xsltproc
29+
docbook-xsl xmlto xsltproc git-lfs
3030
- name: Check out flatpak
3131
uses: actions/checkout@v4
3232
with:
@@ -59,7 +59,7 @@ jobs:
5959
libseccomp-dev libsystemd-dev libxml2-utils libgpgme11-dev gobject-introspection \
6060
libgirepository1.0-dev libappstream-dev libdconf-dev clang flatpak \
6161
libcurl4-gnutls-dev libflatpak-dev libyaml-dev elfutils git patch libarchive-tools \
62-
docbook-xsl xmlto xsltproc
62+
docbook-xsl xmlto xsltproc git-lfs
6363
- name: Check out flatpak
6464
uses: actions/checkout@v4
6565
with:
@@ -135,7 +135,8 @@ jobs:
135135
libarchive-tools \
136136
docbook-xsl \
137137
xmlto \
138-
xsltproc
138+
xsltproc \
139+
git-lfs
139140
140141
- name: Check out flatpak-builder
141142
uses: actions/checkout@v4

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Very commonly used:
4141
* git
4242
* 7z
4343
* bsdunzip (libarchive)
44+
* git-lfs
4445

4546
Rarely used:
4647

src/builder-git.c

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,85 @@ git_has_version (int major,
148148
return TRUE;
149149
}
150150

151+
static gboolean
152+
git_lfs (GFile *dir,
153+
char **output,
154+
GSubprocessFlags flags,
155+
GError **error,
156+
const char **args)
157+
{
158+
g_autoptr(GPtrArray) full_args = g_ptr_array_new ();
159+
gboolean res;
160+
161+
g_ptr_array_add (full_args, "git");
162+
g_ptr_array_add (full_args, "lfs");
163+
164+
for (const char **arg = args; *arg; arg++)
165+
g_ptr_array_add (full_args, (char *) *arg);
166+
167+
g_ptr_array_add (full_args, NULL);
168+
169+
res = flatpak_spawnv (dir, output, flags, error, (const char **) full_args->pdata, NULL);
170+
171+
return res;
172+
}
173+
174+
static gboolean
175+
git_lfs_is_available (void)
176+
{
177+
static gsize lfs_available = 0;
178+
179+
if (g_once_init_enter (&lfs_available))
180+
{
181+
g_autoptr(GError) my_error = NULL;
182+
gsize new_lfs_available = 2;
183+
184+
if (git_lfs (NULL, NULL, 0, &my_error, (const char *[]){"version", NULL}))
185+
new_lfs_available = 1;
186+
else
187+
g_debug ("git-lfs is not available: %s", my_error->message);
188+
189+
g_once_init_leave (&lfs_available, new_lfs_available);
190+
}
191+
192+
return lfs_available == 1;
193+
}
194+
195+
static gboolean
196+
builder_git_run_lfs (GFile *dir,
197+
GError **error,
198+
const char *subcommand,
199+
...)
200+
{
201+
va_list ap;
202+
g_autoptr(GPtrArray) args = g_ptr_array_new ();
203+
const char *arg;
204+
gboolean ok;
205+
206+
if (!git_lfs_is_available ())
207+
return TRUE;
208+
209+
g_ptr_array_add (args, (char *) subcommand);
210+
211+
va_start (ap, subcommand);
212+
while ((arg = va_arg (ap, const char *)))
213+
g_ptr_array_add (args, (char *) arg);
214+
va_end (ap);
215+
216+
g_ptr_array_add (args, NULL);
217+
218+
g_print ("Running git lfs %s\n", subcommand);
219+
ok = git_lfs (dir, NULL, 0, error, (const char **) args->pdata);
220+
221+
if (!ok)
222+
{
223+
git_lfs (dir, NULL, 0, NULL, (const char *[]){"logs", "last", NULL});
224+
return FALSE;
225+
}
226+
227+
return TRUE;
228+
}
229+
151230
static gboolean
152231
git_version_supports_fsck_and_shallow (void)
153232
{
@@ -578,6 +657,10 @@ builder_git_mirror_repo (const char *repo_location,
578657
origin, full_ref_mapping, NULL))
579658
return FALSE;
580659

660+
if (!builder_git_run_lfs (mirror_dir, error,
661+
"fetch", "--all", NULL))
662+
return FALSE;
663+
581664
/* It turns out that older versions of git (at least 2.7.4)
582665
* cannot check out a commit unless a real tag/branch points
583666
* to it, which is not the case for e.g. gitbug pull requests.
@@ -606,6 +689,10 @@ builder_git_mirror_repo (const char *repo_location,
606689
was_shallow ? "--unshallow" : NULL,
607690
NULL))
608691
return FALSE;
692+
693+
if (!builder_git_run_lfs (mirror_dir, error,
694+
"fetch", "--all", NULL))
695+
return FALSE;
609696
}
610697

611698
if (alternates)
@@ -708,6 +795,10 @@ builder_git_shallow_mirror_ref (const char *repo_location,
708795
"fetch", "--depth", "1", "origin", full_ref_colon_full_ref, NULL))
709796
return FALSE;
710797

798+
if (!builder_git_run_lfs (mirror_dir, error,
799+
"fetch", "origin", full_ref, NULL))
800+
return FALSE;
801+
711802
/* Always mirror submodules */
712803
current_commit = git_get_current_commit (mirror_dir, ref, FALSE, context, error);
713804
if (current_commit == NULL)
@@ -862,6 +953,9 @@ builder_git_checkout (const char *repo_location,
862953
"checkout", branch, NULL))
863954
return FALSE;
864955

956+
if (!builder_git_run_lfs (dest, error, "checkout", NULL))
957+
return FALSE;
958+
865959
if (mirror_flags & FLATPAK_GIT_MIRROR_FLAGS_MIRROR_SUBMODULES)
866960
if (!git_extract_submodule (repo_location, dest, branch, context, error))
867961
return FALSE;
@@ -897,4 +991,4 @@ builder_git_get_default_branch (const char *repo_location)
897991

898992
g_debug ("Failed to auto-detect default branch from git output");
899993
return g_strdup ("master");
900-
}
994+
}

0 commit comments

Comments
 (0)