diff --git a/tools/tools/git/candidatematch.lua b/tools/tools/git/candidatematch.lua index 98c247fca339..481c1f38fea1 100755 --- a/tools/tools/git/candidatematch.lua +++ b/tools/tools/git/candidatematch.lua @@ -1,66 +1,74 @@ #!/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 - print(hash) + 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 index dd88710a4a4a..bc1ad602cb1c 100644 --- a/tools/tools/git/mfc-candidates.sh +++ b/tools/tools/git/mfc-candidates.sh @@ -1,169 +1,164 @@ #!/bin/sh #- # SPDX-License-Identifier: BSD-2-Clause # # Copyright 2022 The FreeBSD Foundation # # This software was developed by Ed Maste # under sponsorship from the FreeBSD Foundation. # # Redistribution and use in source and binary forms, with or without # modification, are permitted providing that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # 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)" 2>/dev/null) if [ "${repo}" = "ports.git" ]; then year=$(date '+%Y') month=$(date '+%m') qtr=$(((month-1) / 3 + 1)) to_branch="freebsd/${year}Q${qtr}" elif [ "${repo}" = "src.git" ]; 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: " 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 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 -candidate_list=$workdir/candidates 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 > $candidate_list - -while read hash; do - git show --pretty='%h %s' --no-patch $hash -done < $candidate_list + $from_list $to_list $exclude_list rm -rf "$workdir"