Alpine: multiple branches and backports
Intro
One of the major differences between my previous distro, Void Linux, and the distro i contribute to now, Alpine Linux, is the presence of multiple releases on the latter one.
Alpine Linux has multiple releases, the last is the 3.10.x branch which is on 3.10.1, on my desktop i run edge which is directly from master, and most of my contributions assumed that i would contribute only to the master branch.
Consequently, my scripts were all made with the assumption of a single branch, if you wanted to contribute to another branch you had to modify them to point to another branch.
Soon i wanted to involve myself more on Alpine, so i started backporting fixes and following that my scripts to contribute were rewritten
Rewriting
alpine-stable-prefix
Alpine Linux has branches for each of its 3.x releases in the following format:
- $major.$minor-stable
3.10.1 is held in 3.10-stable, all versions from 3.6.x to 3.10.x follow that and so will 3.11.x as far as it can be seen.
To work on those branches i prepend the $major.$minor- to the package i am working on, for example if I'm working on GnuTLS on the 3.9 branch the branch name would be 3.9-gnutls.
To extract that value i create the alpine-stable-prefix
script, it will just print the version
in $major.$minor format if the prefix is present or nothing if it is not, allowing for a quick
empty variable check on scripts.
#!/bin/sh [ -d .git ] || exit 1 if [ "$1" ]; then branch="$1" else branch="$(git rev-parse --abbrev-ref HEAD)" fi # Only work on supported alpine releases. case "$branch" in 3.10-*) echo 3.10 ;; 3.9-*) echo 3.9 ;; 3.8-*) echo 3.8 ;; 3.7-*) echo 3.7 ;; *) exit 1 ;; esac
gbr
gbr
is my script to make-or-switch to new git branches, if the branch doesn't exist, it creates
it, if it exists it will switch to it. Quite simple, quite important since my workflow is based
on branches.
Before my adaptations it would always follow from the master branch, but since Alpine Linux
has other branches i needed to adapt to it, using the previously mentioned alpine-stable-prefix
it now checks if the new branch has a alpine version prefix and then switches to it.
if git rev-parse --quiet --verify "$1" >/dev/null 2>&1; then git checkout "$1" >/dev/null 2>&1 else - git checkout master >/dev/null 2>&1 - git checkout -b "$1" >/dev/null 2>&1 + _RELBASE="$(alpine-stable-prefix "$1")" + if [ -n "$_RELBASE" ]; then + git branch -f "$1" upstream/"$_RELBASE"-stable >/dev/null 2>&1 + else + git branch -f "$1" upstream/master >/dev/null 2>&1 + fi + git checkout "$1" >/dev/null 2>&1 fi shift done
gcp
The gcp
script compares my branch with the master branch, or whatever branch I'm working against
and gives me a list of commits that will be pushed from my branch to the tracked branch when i push.
$ gcp 8e61ccf621 main/sqlite: fix CVE-2019-8457
set $@ -- $(git rev-parse --abbrev-ref HEAD) fi +_REALBASE="$(alpine-stable-prefix)" + +if [ -n "$_REALBASE" ]; then + _REALBASE="$_REALBASE-stable" +fi + while [ $# -gt 0 ] do - git log upstream/master..$1 --pretty='%C(yellow)%h %C(white)%s' + git log upstream/"${_REALBASE:-master}".."$1" --pretty='%C(yellow)%h %C(white)%s' shift done
pushp and pullp
Those 2 scripts are responsible for pulling from upstream and then pushing to it.
#!/bin/sh _REALBASE="$(alpine-stable-prefix)" if [ -n "$_REALBASE" ]; then _REALBASE="$_REALBASE-stable" fi git pull upstream --rebase "${_REALBASE:-master}"
#!/bin/sh _REALBASE="$(alpine-stable-prefix)" if [ -n "$_REALBASE" ]; then _REALBASE="$_REALBASE-stable" fi git push upstream "$(git rev-parse --abbrev-ref HEAD)":"${_REALBASE:-master}"
mkpr
This script is very important, it is used to create pull requests, it also needs to be cognizant of multiple branches so it can create pull requests against the correct branch.
} pr() { + if [ -z "$BASE" ] && [ -n "$(alpine-stable-prefix "$1")" ]; then + _REALBASE="$(alpine-stable-prefix "$1")"-stable + BASE="--base $_REALBASE" + fi git rebase upstream/"${_REALBASE:-master}" >/dev/null 2>&1 git push -uf origin "$1" >/dev/null 2>&1 if [ "$(git rev-list --count upstream/"${_REALBASE:-master}"..$1)" -gt 1 ]
ax
The most used script, it deals with editing APKBUILDs, running docker to build them via dabuild and other things such as unpacking the source code for inspection.
Part of my workflow is using the name of the package for the branch name, it takes
that name and allows easy operation, writing ax e
to edit an APKBUILD is far
quicker than typing ax e $pkgname
, but it can be done if necessary, and it extends
to all operations.
Adding support means that ax
now needs to know that there is the possibility of
a prefix in the form of the alpine branch $major.$minor- and deal with it accordingly.
Like in all scripts alpine-stable-prefix
is used to get that information.
@@ -282,6 +282,12 @@ mkgit() { cmd="$1" _branch="$(git rev-parse --abbrev-ref HEAD)" + +# Deal with branches with alpine stable prefixes +if [ -n "$(alpine-stable-prefix "$_branch")" ]; then + _branch="$(echo "$_branch" | cut -d - -f2-)" +fi + if [ -z "$2" ]; then branch="$(find_repo "$_branch")" else @@ -290,7 +296,12 @@ else case "$2" in main|community|testing|unmaintained) branch="$(find_repo "$_branch")";; - *) branch="$(find_repo "$2" && shift || find_repo "$_branch")" ;; + *) + # Deal with branches with alpine stable prefixes + if [ -n "$(alpine-stable-prefix "$2")" ]; then + branch="$(echo "$2" | cut -d - -f2-)" + fi + branch="$(find_repo "${branch:-$2}" && shift || find_repo "$_branch")" ;; esac fi shift