git: 63cd0ebe4be8 - stable/14 - mfc-candidates: fix output order with incorrect commit dates

From: Ed Maste <emaste_at_FreeBSD.org>
Date: Thu, 01 Aug 2024 16:07:17 UTC
The branch stable/14 has been updated by emaste:

URL: https://cgit.FreeBSD.org/src/commit/?id=63cd0ebe4be8dde0e0cec23920ed40f7618042d3

commit 63cd0ebe4be8dde0e0cec23920ed40f7618042d3
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2024-04-16 15:41:05 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2024-08-01 15:11:45 +0000

    mfc-candidates: fix output order with incorrect commit dates
    
    Previously we obtained the list of MFC candidate hashes (i.e., those
    commits only in the mfc-from branch), removed the already-merged
    commits based on "cherry picked from" commit message entries, and then
    printed the list sorted by commit time.  This is usually the correct
    order, but it is not when commits have non-monotonically-increasing
    commit times.  This is unfortunately the case for a number of commits in
    our tree.  This made it difficult to merge some groups of dependent
    commits in the correct order.
    
    Instead, leave the from-list in git rev-parse order, and move the
    matching logic to a new lua script.
    
    Reviewed by:    imp
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D44808
    
    (cherry picked from commit d51c590023675ca20a7da74d75a3b5a5dcfdfddc)
---
 tools/tools/git/candidatematch.lua | 66 ++++++++++++++++++++++++++++++++++++++
 tools/tools/git/mfc-candidates.sh  | 19 ++++-------
 2 files changed, 72 insertions(+), 13 deletions(-)

diff --git a/tools/tools/git/candidatematch.lua b/tools/tools/git/candidatematch.lua
new file mode 100755
index 000000000000..98c247fca339
--- /dev/null
+++ b/tools/tools/git/candidatematch.lua
@@ -0,0 +1,66 @@
+#!/usr/libexec/flua
+
+-- MFC candidate script utility - $0 from-file to-file
+--
+-- from-file specifies hashes that exist only in the "MFC from" branch and
+-- to-file specifies the original hashes of commits already merged to the
+-- "MFC to" branch.
+
+-- SPDX-License-Identifier: BSD-2-Clause
+-- Copyright 2024 The FreeBSD Foundation
+
+-- Read a file and return its content as a table
+local function read_file(filename)
+	local file = assert(io.open(filename, "r"))
+	local content = {}
+	for line in file:lines() do
+		table.insert(content, line)
+	end
+	file:close()
+	return content
+end
+
+-- Remove hashes from 'set1' list that are present in 'set2' list
+local function set_difference(set1, set2)
+	local set2_values = {}
+	for _, value in ipairs(set2) do
+		set2_values[value] = true
+	end
+
+	local result = {}
+	for _, value in ipairs(set1) do
+		if not set2_values[value] then
+			table.insert(result, value)
+		end
+	end
+	return result
+end
+
+-- Main function
+local function main()
+	local from_file = arg[1]
+	local to_file = arg[2]
+	local exclude_file = arg[3]
+
+	if not from_file or not to_file then
+		print("Usage: flua $0 from-file to-file")
+		return
+	end
+
+	local from_hashes = read_file(from_file)
+	local to_hashes = read_file(to_file)
+
+	local result_hashes = set_difference(from_hashes, to_hashes)
+
+	if exclude_file then
+		exclude_hashes = read_file(exclude_file)
+		result_hashes = set_difference(result_hashes, exclude_hashes)
+	end
+
+	-- Print the result
+	for _, hash in ipairs(result_hashes) do
+		print(hash)
+	end
+end
+
+main()
diff --git a/tools/tools/git/mfc-candidates.sh b/tools/tools/git/mfc-candidates.sh
index 6610f539fef0..dd88710a4a4a 100644
--- a/tools/tools/git/mfc-candidates.sh
+++ b/tools/tools/git/mfc-candidates.sh
@@ -124,16 +124,14 @@ fi
 # Commits in from_branch after branch point
 commits_from()
 {
-	git rev-list --first-parent $authorarg $to_branch..$from_branch "$@" |\
-	    sort
+	git rev-list --first-parent --reverse $authorarg $to_branch..$from_branch "$@"
 }
 
 # "cherry picked from" hashes from commits in to_branch after branch point
 commits_to()
 {
 	git log $from_branch..$to_branch --grep 'cherry picked from' "$@" |\
-	    sed -E -n 's/^[[:space:]]*\(cherry picked from commit ([0-9a-f]+)\)[[:space:]]*$/\1/p' |\
-	    sort
+	    sed -E -n 's/^[[:space:]]*\(cherry picked from commit ([0-9a-f]+)\)[[:space:]]*$/\1/p'
 }
 
 # Turn a list of short hashes (and optional descriptions) into a list of full
@@ -161,16 +159,11 @@ fi
 commits_from "$@" > $from_list
 commits_to "$@" > $to_list
 
-comm -23 $from_list $to_list > $candidate_list
+/usr/libexec/flua $(dirname $0)/candidatematch.lua \
+    $from_list $to_list $exclude_list > $candidate_list
 
-if [ -n "$exclude_file" ]; then
-	mv $candidate_list $candidate_list.bak
-	comm -23 $candidate_list.bak $exclude_list > $candidate_list
-fi
-
-# Sort by (but do not print) commit time
 while read hash; do
-	git show --pretty='%ct %h %s' --no-patch $hash
-done < $candidate_list | sort -n | cut -d ' ' -f 2-
+	git show --pretty='%h %s' --no-patch $hash
+done < $candidate_list
 
 rm -rf "$workdir"