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