├── README.md
└── linux-stable.sh
/README.md:
--------------------------------------------------------------------------------
1 | # linux-stable merge script
2 |
3 | This script is designed to help you merge or pick linux-stable into your own kernel source repos.
4 |
5 | Either clone this repo or run the following command in the root of your kernel folder:
6 |
7 | `curl -o linux-stable.sh https://raw.githubusercontent.com/android-linux-stable/script/master/linux-stable.sh && chmod +x linux-stable.sh`
8 |
9 | Once you have it downloaded, run `./linux-stable.sh -h` to learn more about it
10 |
11 | If you have any questions or issues, file an issue on this repo!
12 |
--------------------------------------------------------------------------------
/linux-stable.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #
3 | # Pull in linux-stable updates to a kernel tree
4 | #
5 | # Copyright (C) 2017-2018 Nathan Chancellor
6 | #
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # This program is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with this program. If not, see
19 |
20 |
21 | # Colors for script
22 | BOLD="\033[1m"
23 | GRN="\033[01;32m"
24 | RED="\033[01;31m"
25 | RST="\033[0m"
26 | YLW="\033[01;33m"
27 |
28 |
29 | # Alias for echo to handle escape codes like colors
30 | function echo() {
31 | command echo -e "$@"
32 | }
33 |
34 |
35 | # Prints a formatted header to point out what is being done to the user
36 | function header() {
37 | if [[ -n ${2} ]]; then
38 | COLOR=${2}
39 | else
40 | COLOR=${RED}
41 | fi
42 | echo "${COLOR}"
43 | # shellcheck disable=SC2034
44 | echo "====$(for i in $(seq ${#1}); do echo "=\c"; done)===="
45 | echo "== ${1} =="
46 | # shellcheck disable=SC2034
47 | echo "====$(for i in $(seq ${#1}); do echo "=\c"; done)===="
48 | echo "${RST}"
49 | }
50 |
51 |
52 | # Prints an error in bold red
53 | function die() {
54 | echo
55 | echo "${RED}${1}${RST}"
56 | [[ ${2} = "-h" ]] && ${0} -h
57 | exit 1
58 | }
59 |
60 |
61 | # Prints a statement in bold green
62 | function success() {
63 | echo
64 | echo "${GRN}${1}${RST}"
65 | [[ -z ${2} ]] && echo
66 | }
67 |
68 |
69 | # Prints a warning in bold yellow
70 | function warn() {
71 | echo
72 | echo "${YLW}${1}${RST}"
73 | [[ -z ${2} ]] && echo
74 | }
75 |
76 |
77 | # Parse the provided parameters
78 | function parse_parameters() {
79 | while [[ $# -ge 1 ]]; do
80 | case ${1} in
81 | # Use git cherry-pick
82 | "-c"|"--cherry-pick")
83 | UPDATE_METHOD=cherry-pick ;;
84 |
85 | # Only update the linux-stable remote
86 | "-f"|"--fetch-only")
87 | FETCH_REMOTE_ONLY=true ;;
88 |
89 | # Help menu
90 | "-h"|"--help")
91 | echo
92 | echo "${BOLD}Command:${RST} ./$(basename "${0}") "
93 | echo
94 | echo "${BOLD}Script description:${RST} Merges/cherry-picks Linux upstream into a kernel tree"
95 | echo
96 | echo "${BOLD}Required parameters:${RST}"
97 | echo " -c | --cherry-pick"
98 | echo " -m | --merge"
99 | echo " Call either git cherry-pick or git merge when updating from upstream"
100 | echo
101 | echo "${BOLD}Optional parameters:${RST}"
102 | echo " -f | --fetch-only"
103 | echo " Simply fetches the tags from linux-stable then exits"
104 | echo
105 | echo " -k | --kernel-folder"
106 | echo " The device's kernel source's location; this can either be a full path or relative to where the script is being executed."
107 | echo
108 | echo " -l | --latest"
109 | echo " Updates to the latest version available for the current kernel tree"
110 | echo
111 | echo " -p | --print-latest"
112 | echo " Prints the latest version available for the current kernel tree then exits"
113 | echo
114 | echo " -v | --version"
115 | echo " Updates to the specified version (e.g. -v 3.18.78)"
116 | echo
117 | echo "${BOLD}Defaults:${RST}"
118 | echo " If -l or -v are not specified, ONE version is picked at a time (e.g. 3.18.31 to 3.18.32)"
119 | echo
120 | echo " If -k is not specified, the script assumes it is in the kernel source folder already"
121 | echo
122 | exit 1 ;;
123 |
124 | # Kernel source location
125 | "-k"|"--kernel-folder")
126 | shift
127 | [[ $# -lt 1 ]] && die "Please specify a kernel source location!"
128 |
129 | KERNEL_FOLDER=${1} ;;
130 |
131 | # Update to the latest version upstream unconditionally
132 | "-l"|"--latest")
133 | UPDATE_MODE=1 ;;
134 |
135 | # Use git merge
136 | "-m"|"--merge")
137 | UPDATE_METHOD=merge ;;
138 |
139 | # Print the latest version from kernel.org
140 | "-p"|"--print-latest")
141 | PRINT_LATEST=true ;;
142 |
143 | # Update to the specified version
144 | "-v"|"--version")
145 | shift
146 | [[ $# -lt 1 ]] && die "Please specify a version to update!"
147 |
148 | TARGET_VERSION=${1} ;;
149 |
150 | *)
151 | die "Invalid parameter!" ;;
152 | esac
153 |
154 | shift
155 | done
156 |
157 | # If kernel source isn't specified, assume we're there
158 | [[ -z ${KERNEL_FOLDER} ]] && KERNEL_FOLDER=$(pwd)
159 |
160 | # Sanity checks
161 | [[ ! ${UPDATE_METHOD} ]] && die "Neither cherry-pick nor merge were specified, please supply one!" -h
162 | [[ ! -d ${KERNEL_FOLDER} ]] && die "Invalid kernel source location specified! Folder does not exist" -h
163 | [[ ! -f ${KERNEL_FOLDER}/Makefile ]] && die "Invalid kernel source location specified! No Makefile present" -h
164 |
165 | # Default update mode is one version at a time
166 | [[ -z ${UPDATE_MODE} && -z ${TARGET_VERSION} ]] && UPDATE_MODE=0
167 | }
168 |
169 |
170 | # Update the linux-stable remote (and add it if it doesn't exist)
171 | function update_remote() {
172 | header "Updating linux-stable"
173 |
174 | # Add remote if it isn't already present
175 | cd "${KERNEL_FOLDER}" || die "Could not change into ${KERNEL_FOLDER}!"
176 |
177 | if git fetch --tags https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/; then
178 | success "linux-stable updated successfully!"
179 | else
180 | die "linux-stable update failed!"
181 | fi
182 |
183 | [[ ${FETCH_REMOTE_ONLY} ]] && exit 0
184 | }
185 |
186 |
187 | # Generate versions
188 | function generate_versions() {
189 | header "Calculating versions"
190 |
191 | # Full kernel version
192 | CURRENT_VERSION=$(make -s CC=gcc CROSS_COMPILE="" kernelversion)
193 | # First two numbers (3.4 | 3.10 | 3.18 | 4.4)
194 | CURRENT_MAJOR_VERSION=$(echo "${CURRENT_VERSION}" | cut -f 1,2 -d .)
195 | # Last number
196 | CURRENT_SUBLEVEL=$(echo "${CURRENT_VERSION}" | cut -d . -f 3)
197 |
198 | # Get latest update from upstream
199 | LATEST_VERSION=$(git tag --sort=-taggerdate -l "v${CURRENT_MAJOR_VERSION}"* | head -n 1 | sed s/v//)
200 | LATEST_SUBLEVEL=$(echo "${LATEST_VERSION}" | cut -d . -f 3)
201 |
202 | # Print the current/latest version and exit if requested
203 | echo "${BOLD}Current kernel version:${RST} ${CURRENT_VERSION}"
204 | echo
205 | echo "${BOLD}Latest kernel version:${RST} ${LATEST_VERSION}"
206 | if [[ ${PRINT_LATEST} ]]; then
207 | echo
208 | exit 0
209 | fi
210 |
211 | # UPDATE_MODES:
212 | # 0. Update one version
213 | # 1. Update to the latest version
214 | case ${UPDATE_MODE} in
215 | 0)
216 | TARGET_SUBLEVEL=$((CURRENT_SUBLEVEL + 1))
217 | TARGET_VERSION=${CURRENT_MAJOR_VERSION}.${TARGET_SUBLEVEL} ;;
218 | 1)
219 | TARGET_VERSION=${LATEST_VERSION} ;;
220 | esac
221 |
222 | # Make sure target version is between current version and latest version
223 | TARGET_SUBLEVEL=$(echo "${TARGET_VERSION}" | cut -d . -f 3)
224 | [[ ${TARGET_SUBLEVEL} -le ${CURRENT_SUBLEVEL} ]] && die "${TARGET_VERSION} is already present in ${CURRENT_VERSION}!"
225 | [[ ${TARGET_SUBLEVEL} -gt ${LATEST_SUBLEVEL} ]] && die "${CURRENT_VERSION} is the latest!"
226 | [[ ${CURRENT_SUBLEVEL} -eq 0 ]] && CURRENT_VERSION=${CURRENT_MAJOR_VERSION}
227 |
228 | RANGE=v${CURRENT_VERSION}..v${TARGET_VERSION}
229 |
230 | echo
231 | echo "${BOLD}Target kernel version:${RST} ${TARGET_VERSION}"
232 | echo
233 | }
234 |
235 |
236 | function update_to_target_version() {
237 | case ${UPDATE_METHOD} in
238 | "cherry-pick")
239 | if ! git cherry-pick "${RANGE}"; then
240 | die "Cherry-pick needs manual intervention! Resolve conflicts then run:
241 |
242 | git add . && git cherry-pick --continue"
243 | else
244 | header "${TARGET_VERSION} PICKED CLEANLY!" "${GRN}"
245 | fi ;;
246 |
247 | "merge")
248 | if ! GIT_MERGE_VERBOSITY=1 git merge --no-edit "v${TARGET_VERSION}"; then
249 | die "Merge needs manual intervention!
250 |
251 | Resolve conflicts then run git commit!"
252 | else
253 | header "${TARGET_VERSION} MERGED CLEANLY!" "${GRN}"
254 | fi ;;
255 | esac
256 | }
257 |
258 |
259 | parse_parameters "$@"
260 | update_remote
261 | generate_versions
262 | update_to_target_version
263 |
--------------------------------------------------------------------------------