From d88424cfecb4e295dcfeb6085d4eadedbfca6c8d Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 10 Sep 2025 18:10:09 +0200 Subject: [PATCH] patch-git: Do not use --filter with --unshallow on old git versions Before git 2.28, --filter cannot be used if the clone did not use it. Related: RHEL-111490 --- patch-git.lua | 124 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 49 deletions(-) diff --git a/patch-git.lua b/patch-git.lua index 6f3d230..edb2cd7 100644 --- a/patch-git.lua +++ b/patch-git.lua @@ -283,6 +283,74 @@ do end end +-- Sort the list lexicographically, in place, treating sequences of +-- digits as a single positive decimal number. +local function version_sort(list) + -- Sorting is only needed for two or more elements. + if #list <= 1 then + return + end + + -- Maximum length of a sequence of consecutive digits in patch names. + local max_width = 1 + for i=1,#list do + local s = list[i] + for number in string.gmatch(s, '%d+') do + if #number > max_width then + max_width = #number + end + end + end + + -- Pad the number argument with leading '0' to max_width. + local function pad(s) + return string.rep('0', max_width - #s) .. s + end + + local padded = {} + for i=1,#list do + local s = list[i] + padded[s] = string.gsub(s, '%d+', pad) + end + + table.sort(list, function (a, b) + return padded[a] < padded[b] + end) +end +-- Tests for version_sort. +do + local test = {'b2-30b', 'b1', 'b10', 'b2', 'a', 'b2-30', 'b2-4'} + version_sort(test) + assert(#test == 7) + assert(test[1] == 'a') + assert(test[2] == 'b1') + assert(test[3] == 'b2') + assert(test[4] == 'b2-4') + assert(test[5] == 'b2-30') + assert(test[6] == 'b2-30b') + assert(test[7] == 'b10') +end + +-- Returns true if the git command version is at least that of the +-- argument string. +local check_git_version +do + -- Cached version of the git command. + local git_version + + function check_git_version(reference) + if not git_version then + local output = run_git('version') + git_version = assert( + string.match(output, '^git version (%d[^\n]*)\n'), output) + end + -- If the reference version sorts first, the version check succeeds. + local sorted = {git_version, reference} + version_sort(sorted) + return sorted[1] == reference + end +end + -- Called to generate the files (if HEAD or the script version has changed). local function generate_files() -- True if %_sourcedir refers to a Git repository and git is installed. @@ -311,7 +379,13 @@ local function generate_files() do local shallow = run_git('rev-parse --is-shallow-repository') if shallow == 'true\n' then - check_git('fetch --unshallow --filter=blob:none') + if check_git_version('2.28') then + check_git('fetch --unshallow --filter=blob:none') + else + -- 2.27 and earlier error out if the original clone did not + -- use --filter. + check_git('fetch --unshallow') + end else assert(shallow == 'false\n', shallow) end @@ -499,54 +573,6 @@ local function parse_commits() patchgit.commits = commits end --- Sort the list lexicographically, in place, treating sequences of --- digits as a single positive decimal number. -local function version_sort(list) - -- Sorting is only needed for two or more elements. - if #list <= 1 then - return - end - - -- Maximum length of a sequence of consecutive digits in patch names. - local max_width = 1 - for i=1,#list do - local s = list[i] - for number in string.gmatch(s, '%d+') do - if #number > max_width then - max_width = #number - end - end - end - - -- Pad the number argument with leading '0' to max_width. - local function pad(s) - return string.rep('0', max_width - #s) .. s - end - - local padded = {} - for i=1,#list do - local s = list[i] - padded[s] = string.gsub(s, '%d+', pad) - end - - table.sort(list, function (a, b) - return padded[a] < padded[b] - end) -end --- Tests for version_sort. -do - local test = {'b2-30b', 'b1', 'b10', 'b2', 'a', 'b2-30', 'b2-4'} - version_sort(test) - assert(#test == 7) - assert(test[1] == 'a') - assert(test[2] == 'b1') - assert(test[3] == 'b2') - assert(test[4] == 'b2-4') - assert(test[5] == 'b2-30') - assert(test[6] == 'b2-30b') - assert(test[7] == 'b10') -end - -- Inject the Patch: lines into the spec file, in the appropriate -- (commit) order. Unapplied patches found in the source directory -- and that are not present in the Git history are applied last.