]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/tools/git/mfc-candidates.sh
Merge OpenSSL 3.0.9
[FreeBSD/FreeBSD.git] / tools / tools / git / mfc-candidates.sh
1 #!/bin/sh
2
3 #-
4 # SPDX-License-Identifier: BSD-2-Clause
5 #
6 # Copyright 2022 The FreeBSD Foundation
7 #
8 # This software was developed by Ed Maste
9 # under sponsorship from the FreeBSD Foundation.
10 #
11 # Redistribution and use in source and binary forms, with or without
12 # modification, are permitted providing that the following conditions
13 # are met:
14 # 1. Redistributions of source code must retain the above copyright
15 #    notice, this list of conditions and the following disclaimer.
16 # 2. Redistributions in binary form must reproduce the above copyright
17 #    notice, this list of conditions and the following disclaimer in the
18 #    documentation and/or other materials provided with the distribution.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 # SUCH DAMAGE.
31
32 from_branch=freebsd/main
33 author="${USER}"
34
35 # Get the FreeBSD repository
36 repo=$(basename "$(git remote get-url freebsd 2>/dev/null)" 2>/dev/null)
37
38 if [ "${repo}" = "ports.git" ]; then
39         year=$(date '+%Y')
40         month=$(date '+%m')
41         qtr=$(((month-1) / 3 + 1))
42         to_branch="freebsd/${year}Q${qtr}"
43 elif [ "${repo}" = "src.git" ]; then
44         to_branch=freebsd/stable/13
45         # If pwd is a stable or release branch tree, default to it.
46         cur_branch=$(git symbolic-ref --short HEAD 2>/dev/null)
47         case $cur_branch in
48         stable/*)
49                 to_branch=$cur_branch
50                 ;;
51         releng/*)
52                 to_branch=$cur_branch
53                 major=${cur_branch#releng/}
54                 major=${major%.*}
55                 from_branch=freebsd/stable/$major
56         esac
57 else
58         echo "pwd is not under a ports or src repository."
59         exit 0
60 fi
61
62 params()
63 {
64         echo "from:             $from_branch"
65         echo "to:               $to_branch"
66         if [ -n "$author" ]; then
67                 echo "author/committer: $author"
68         else
69                 echo "author/committer: <all>"
70         fi
71 }
72
73 usage()
74 {
75         echo "usage: $(basename $0) [-ah] [-f from_branch] [-t to_branch] [-u user] [-X exclude_file] [path ...]"
76         echo
77         params
78         exit 0
79 }
80
81 while getopts "af:ht:u:vX:" opt; do
82         case $opt in
83         a)
84                 # All authors/committers
85                 author=
86                 ;;
87         f)
88                 from_branch=$OPTARG
89                 ;;
90         h)
91                 usage
92                 ;;
93         t)
94                 to_branch=$OPTARG
95                 ;;
96         u)
97                 author=$OPTARG
98                 ;;
99         v)
100                 verbose=1
101                 ;;
102         X)
103                 if [ ! -r "$OPTARG" ]; then
104                         echo "Exclude file $OPTARG not readable" >&2
105                         exit 1
106                 fi
107                 exclude_file=$OPTARG
108                 ;;
109         esac
110 done
111 shift $(($OPTIND - 1))
112
113 if [ $verbose ]; then
114         params
115         echo
116 fi
117
118 authorarg=
119 if [ -n "$author" ]; then
120         # Match user ID in the email portion of author or committer
121         authorarg="--author <${author}@ --committer <${author}@"
122 fi
123
124 # Commits in from_branch after branch point
125 commits_from()
126 {
127         git rev-list --first-parent $authorarg $to_branch..$from_branch "$@" |\
128             sort
129 }
130
131 # "cherry picked from" hashes from commits in to_branch after branch point
132 commits_to()
133 {
134         git log $from_branch..$to_branch --grep 'cherry picked from' "$@" |\
135             sed -E -n 's/^[[:space:]]*\(cherry picked from commit ([0-9a-f]+)\)[[:space:]]*$/\1/p' |\
136             sort
137 }
138
139 # Turn a list of short hashes (and optional descriptions) into a list of full
140 # hashes.
141 canonicalize_hashes()
142 {
143         while read hash rest; do
144                 if ! git show --pretty=%H --no-patch $hash; then
145                         echo "error parsing hash list" >&2
146                         exit 1
147                 fi
148         done | sort
149 }
150
151 workdir=$(mktemp -d /tmp/find-mfc.XXXXXXXXXX)
152 from_list=$workdir/commits-from
153 to_list=$workdir/commits-to
154 candidate_list=$workdir/candidates
155
156 if [ -n "$exclude_file" ]; then
157         exclude_list=$workdir/commits-exclude
158         canonicalize_hashes < $exclude_file > $exclude_list
159 fi
160
161 commits_from "$@" > $from_list
162 commits_to "$@" > $to_list
163
164 comm -23 $from_list $to_list > $candidate_list
165
166 if [ -n "$exclude_file" ]; then
167         mv $candidate_list $candidate_list.bak
168         comm -23 $candidate_list.bak $exclude_list > $candidate_list
169 fi
170
171 # Sort by (but do not print) commit time
172 while read hash; do
173         git show --pretty='%ct %h %s' --no-patch $hash
174 done < $candidate_list | sort -n | cut -d ' ' -f 2-
175
176 rm -rf "$workdir"