├── 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 | --------------------------------------------------------------------------------