Page MenuHomeFreeBSD

D47416.diff
No OneTemporary

D47416.diff

diff --git a/tools/tools/git/candidatematch.lua b/tools/tools/git/candidatematch.lua
deleted file mode 100755
--- a/tools/tools/git/candidatematch.lua
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/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
-
--- Execute a command and print to stdout
-local function exec_command(command)
- local handle = io.popen(command)
- local output = handle:read("a")
- handle:close()
- io.write(output)
-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
- exec_command("git show --pretty='%h %s' --no-patch " .. hash)
- end
-end
-
-main()
diff --git a/tools/tools/git/mfc-candidates.lua b/tools/tools/git/mfc-candidates.lua
new file mode 100755
--- /dev/null
+++ b/tools/tools/git/mfc-candidates.lua
@@ -0,0 +1,218 @@
+#!/usr/libexec/flua
+
+-- SPDX-License-Identifier: BSD-2-Clause
+-- Copyright 2024 The FreeBSD Foundation
+
+-- MFC candidate search utility. Identify hashes that exist only in the
+-- "MFC from" branch and do not have a corresponding "cherry picked from"
+-- commit in the "MFC to" branch.
+
+-- Execute a command and return its output. A final newline is stripped,
+-- similar to sh.
+local function exec_command(command)
+ local handle = assert(io.popen(command))
+ local output = handle:read("a")
+ handle:close()
+ if output:sub(-1) == "\n" then
+ return output:sub(1, -2)
+ end
+ return output
+end
+
+-- Return a table of cherry-pick (MFC) candidates.
+local function read_from(from_branch, to_branch, author, dirspec)
+ local command = "git rev-list --first-parent --reverse "
+ command = command .. to_branch .. ".." .. from_branch
+ if #author > 0 then
+ command = command .. " --committer \\<" .. author .. "@"
+ end
+ if dirspec then
+ command = command .. " " .. dirspec
+ end
+ if verbose > 1 then
+ print("Obtaining MFC-from commits using command:")
+ print(command)
+ end
+ local handle = assert(io.popen(command))
+ local content = {}
+ for line in handle:lines() do
+ table.insert(content, line)
+ end
+ handle:close()
+ return content
+end
+
+-- Return a table of original hashes of changes that have already been
+-- cherry-picked (MFC'd).
+local function read_to(from_branch, to_branch, dirspec)
+ local command = "git log " .. from_branch .. ".." .. to_branch
+ command = command .. " --grep 'cherry picked from'"
+ if dirspec then
+ command = command .. " " .. dirspec
+ end
+ if verbose > 1 then
+ print("Obtaining MFC-to commits using command:")
+ print(command)
+ end
+ local handle = assert(io.popen(command))
+ local content = {}
+ for line in handle:lines() do
+ local hash = line:match("%(cherry picked from commit ([0-9a-f]+)%)")
+ if hash then
+ table.insert(content, hash)
+ end
+ end
+ handle:close()
+ return content
+end
+
+-- Read a commit exclude file and return its content as a table. Comments
+-- starting with # and text after a hash is ignored.
+local function read_exclude(filename)
+ local file = assert(io.open(filename, "r"))
+ local content = {}
+ for line in file:lines() do
+ local hash = line:match("^%x+")
+ if hash then
+ -- Hashes are 40 chars; if less, expand short hash.
+ if #hash < 40 then
+ hash = exec_command(
+ "git show --pretty=%H --no-patch " .. hash)
+ end
+ table.insert(content, hash)
+ end
+ 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
+
+-- Global state
+verbose = 0
+
+local function params(from_branch, to_branch, author)
+ print("from: " .. from_branch)
+ print("to: " .. to_branch)
+ if #author > 0 then
+ print("author/committer: " .. author)
+ else
+ print("author/committer: <all>")
+ end
+end
+
+local function usage(from_branch, to_branch, author)
+ local script_name = arg[0]:match("([^/]+)$")
+ print(script_name .. " [-ah] [-f from_branch] [-t to_branch] [-u user] [-X exclude_file] [path ...]")
+ print()
+ params(from_branch, to_branch, author)
+end
+
+-- Main function
+local function main()
+ local from_branch = "freebsd/main"
+ local to_branch = ""
+ local author = os.getenv("USER") or ""
+ local dirspec = nil
+
+ local url = exec_command("git remote get-url freebsd")
+ local freebsd_repo = string.match(url, "[^/]+$")
+ freebsd_repo = string.gsub(freebsd_repo, ".git$", "")
+ if freebsd_repo == "ports" or freebsd_repo == "freebsd-ports" then
+ local year = os.date("%Y")
+ local month = os.date("%m")
+ local qtr = math.ceil(month / 3)
+ to_branch = "freebsd/" .. year .. "Q" .. qtr
+ elseif freebsd_repo == "src" or freebsd_repo == "freebsd-src" then
+ to_branch = "freebsd/stable/14"
+ -- If pwd is a stable or release branch tree, default to it.
+ local cur_branch = exec_command("git symbolic-ref --short HEAD")
+ if string.match(cur_branch, "^stable/") then
+ to_branch = cur_branch
+ elseif string.match(cur_branch, "^releng/") then
+ to_branch = cur_branch
+ local major = string.match(cur_branch, "%d+")
+ from_branch = "freebsd/stable/" .. major
+ end
+ else
+ print("pwd is not under a ports or src repository.")
+ return
+ end
+
+ local do_help = false
+ local exclude_file = nil
+ local i = 1
+ while i <= #arg and arg[i] do
+ local opt = arg[i]
+ if opt == "-a" then
+ author = ""
+ elseif opt == "-f" then
+ from_branch = arg[i + 1]
+ i = i + 1
+ elseif opt == "-h" then
+ do_help = true
+ i = i + 1
+ elseif opt == "-t" then
+ to_branch = arg[i + 1]
+ i = i + 1
+ elseif opt == "-u" then
+ author = arg[i + 1]
+ i = i + 1
+ elseif opt == "-v" then
+ verbose = verbose + 1
+ elseif opt == "-X" then
+ exclude_file = arg[i + 1]
+ print ("-X not working")
+ i = i + 1
+ else
+ break
+ end
+ i = i + 1
+ end
+
+ if do_help then
+ usage(from_branch, to_branch, author)
+ return
+ end
+
+ if arg[i] then
+ dirspec = arg[i]
+ --print("dirspec = " .. dirspec)
+ -- XXX handle multiple dirspecs?
+ end
+
+ if verbose > 0 then
+ params(from_branch, to_branch, author)
+ end
+
+ local from_hashes = read_from(from_branch, to_branch, author, dirspec)
+ local to_hashes = read_to(from_branch, to_branch, dirspec)
+
+ local result_hashes = set_difference(from_hashes, to_hashes)
+
+ if exclude_file then
+ exclude_hashes = read_exclude(exclude_file)
+ result_hashes = set_difference(result_hashes, exclude_hashes)
+ end
+
+ -- Print the result
+ for _, hash in ipairs(result_hashes) do
+ print(exec_command("git show --pretty='%h %s' --no-patch " .. hash))
+ end
+end
+
+main()
diff --git a/tools/tools/git/mfc-candidates.sh b/tools/tools/git/mfc-candidates.sh
--- a/tools/tools/git/mfc-candidates.sh
+++ b/tools/tools/git/mfc-candidates.sh
@@ -29,139 +29,5 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-from_branch=freebsd/main
-author="${USER}"
-
-# Get the FreeBSD repository
-repo=$(basename "$(git remote get-url freebsd 2>/dev/null)" .git 2>/dev/null)
-
-if [ "${repo}" = "ports" -o "${repo}" = "freebsd-ports" ]; then
- year=$(date '+%Y')
- month=$(date '+%m')
- qtr=$(((month-1) / 3 + 1))
- to_branch="freebsd/${year}Q${qtr}"
-elif [ "${repo}" = "src" -o "${repo}" = "freebsd-src" ]; then
- to_branch=freebsd/stable/14
- # If pwd is a stable or release branch tree, default to it.
- cur_branch=$(git symbolic-ref --short HEAD 2>/dev/null)
- case $cur_branch in
- stable/*)
- to_branch=$cur_branch
- ;;
- releng/*)
- to_branch=$cur_branch
- major=${cur_branch#releng/}
- major=${major%.*}
- from_branch=freebsd/stable/$major
- esac
-else
- echo "pwd is not under a ports or src repository."
- exit 0
-fi
-
-params()
-{
- echo "from: $from_branch"
- echo "to: $to_branch"
- if [ -n "$author" ]; then
- echo "author/committer: $author"
- else
- echo "author/committer: <all>"
- fi
-}
-
-usage()
-{
- echo "usage: $(basename $0) [-ah] [-f from_branch] [-t to_branch] [-u user] [-X exclude_file] [path ...]"
- echo
- params
- exit 0
-}
-
-while getopts "af:ht:u:vX:" opt; do
- case $opt in
- a)
- # All authors/committers
- author=
- ;;
- f)
- from_branch=$OPTARG
- ;;
- h)
- usage
- ;;
- t)
- to_branch=$OPTARG
- ;;
- u)
- author=$OPTARG
- ;;
- v)
- verbose=1
- ;;
- X)
- if [ ! -r "$OPTARG" ]; then
- echo "Exclude file $OPTARG not readable" >&2
- exit 1
- fi
- exclude_file=$OPTARG
- ;;
- esac
-done
-shift $(($OPTIND - 1))
-
-if [ $verbose ]; then
- params
- echo
-fi
-
-authorarg=
-if [ -n "$author" ]; then
- # Match user ID in the email portion of author or committer
- authorarg="--committer <${author}@"
-fi
-
-# Commits in from_branch after branch point
-commits_from()
-{
- 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'
-}
-
-# Turn a list of short hashes (and optional descriptions) into a list of full
-# hashes.
-canonicalize_hashes()
-{
- while read hash rest; do
- case "${hash}" in
- "#"*) continue ;;
- esac
- if ! git show --pretty=%H --no-patch $hash; then
- echo "error parsing hash list" >&2
- exit 1
- fi
- done | sort
-}
-
-workdir=$(mktemp -d /tmp/find-mfc.XXXXXXXXXX)
-from_list=$workdir/commits-from
-to_list=$workdir/commits-to
-
-if [ -n "$exclude_file" ]; then
- exclude_list=$workdir/commits-exclude
- canonicalize_hashes < $exclude_file > $exclude_list
-fi
-
-commits_from "$@" > $from_list
-commits_to "$@" > $to_list
-
-/usr/libexec/flua $(dirname $0)/candidatematch.lua \
- $from_list $to_list $exclude_list
-
-rm -rf "$workdir"
+# Backwards compatibility wrapper
+/usr/libexec/flua $(dirname $0)/mfc-candidates.lua "$@"

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 10, 5:39 AM (20 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23520426
Default Alt Text
D47416.diff (11 KB)

Event Timeline