on main help sign in
Multigram/scripts/export-patches.sh
86 lines 4.1 kB history raw
1#!/usr/bin/env bash
2# Write the MultiGram stack as numbered patches (git format-patch forkgram..multigram) into
3# a folder, with APPLY.txt saying how to apply them onto a plain Forkgram checkout.
4#
5# scripts/export-patches.sh [--base REF] [--head REF] [--force] [FOLDER]
6#
7# --base REF the snapshot branch (default: forkgram)
8# --head REF the app branch (default: multigram)
9# --force replace the patches of an earlier export in FOLDER
10# FOLDER where to write them (default: multigram-patches)
12# For branches you have not checked out locally, pass --base origin/forkgram
13# --head origin/multigram after a git fetch.
14set -euo pipefail
16die() { printf 'export-patches: %s\n' "$*" >&2; exit 1; }
18base=forkgram head=multigram force=no dir=multigram-patches
19while [ $# -gt 0 ]; do
20 case $1 in
21 --base) base=${2:?--base needs a ref}; shift 2 ;;
22 --head) head=${2:?--head needs a ref}; shift 2 ;;
23 --force) force=yes; shift ;;
24 -h | --help) sed -n '2,/^set -euo/p' "$0" | sed '$d; s/^# \{0,1\}//'; exit 0 ;;
25 -*) die "unknown option: $1 (see --help)" ;;
26 *) dir=$1; shift ;;
27 esac
28done
30git rev-parse --git-dir >/dev/null 2>&1 || die "run this inside a clone of the MultiGram repository"
31base_c=$(git rev-parse -q --verify "$base^{commit}") || die "no such ref: $base"
32head_c=$(git rev-parse -q --verify "$head^{commit}") || die "no such ref: $head"
33count=$(git rev-list --count "$base_c..$head_c")
34[ "$count" -gt 0 ] || die "$head has no commits on top of $base"
35[ -z "$(git rev-list --merges "$base_c..$head_c")" ] ||
36 die "$head has merge commits on top of $base; git format-patch cannot export them"
38# The snapshot the stack sits on, and the Forkgram commit it was made from.
39snap=$(git merge-base "$base_c" "$head_c") || die "$head shares no history with $base"
40msg=$(git log -1 --format=%B "$snap")
41fg_commit=$(printf '%s\n' "$msg" | sed -n 's/^Forkgram-Commit:[[:space:]]*\([0-9a-f]\{40\}\).*/\1/p' | tail -n 1)
42fg_version=$(printf '%s\n' "$msg" | sed -n 's/^Forkgram-Version:[[:space:]]*\([0-9A-Za-z._+-]*\).*/\1/p' | tail -n 1)
43[ -n "$fg_commit" ] || die "$(git rev-parse --short "$snap") (where $head meets $base) is not a Forkgram snapshot"
44[ -n "$fg_version" ] || fg_version=unknown
45if [ "$snap" != "$base_c" ]; then
46 printf 'export-patches: note: %s is based on an older snapshot than %s; the patches are for Forkgram %s\n' \
47 "$head" "$base" "$fg_version" >&2
48fi
50mkdir -p "$dir"
51if [ -n "$(ls -A "$dir")" ]; then
52 [ "$force" = yes ] || die "$dir is not empty (use --force to replace an earlier export)"
53 find "$dir" -mindepth 1 -maxdepth 1 \( -name '[0-9][0-9][0-9][0-9]-*.patch' -o -name APPLY.txt \) -exec rm -f {} +
54 [ -z "$(ls -A "$dir")" ] || die "$dir holds files this script did not write; pick another folder"
55fi
57git format-patch --quiet --full-index --binary -o "$dir" "$base_c..$head_c"
58abs=$(cd "$dir" && pwd)
60cat >"$dir/APPLY.txt" <<EOF
61MultiGram patches
62=================
64$count patch(es): the MultiGram commits of $head ($(git rev-parse --short "$head_c")), made on the
65forkgram snapshot $(git rev-parse --short "$snap"), which is Forkgram $fg_version with the .github folder removed:
67 Forkgram commit $fg_commit
69Apply them onto a plain Forkgram checkout of that commit. Forkgram tags its releases
70<version>.0 (so $fg_version.0 here); if the tag is missing, fetch the commit instead.
72 git clone --depth 1 --branch $fg_version.0 https://github.com/forkgram/TelegramAndroid.git
73 cd TelegramAndroid
74 git rev-parse HEAD # should print $fg_commit
75 git switch -c multigram
76 git am -3 $abs/*.patch
78-3 lets git fall back to a three-way merge when a patch does not apply as it is.
79If git am still stops, it names the patch and the files: fix them, "git add" them and
80run "git am --continue" (or "git am --skip" to leave that patch out, "git am --abort"
81to go back). The same commands work on a newer Forkgram release (expect more stops);
82clone without --depth 1 then, so -3 can find the older versions of the files.
83EOF
85printf '%s\n' "Wrote $count patch(es) and APPLY.txt to $abs"
86sed -n '/^ git clone/,/^ git am/p' "$dir/APPLY.txt"