Last active
June 26, 2024 19:13
-
-
Save oliverlee/6e3f763c0db09f949e467e407957cfc3 to your computer and use it in GitHub Desktop.
Push commit to Github and open/update a PR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -euo pipefail | |
KEY="Change-Id: " | |
SOURCE_REMOTE=origin | |
TARGET_USER=$(git remote get-url "$SOURCE_REMOTE" | sed 's/^.*\.com[:/]\(.*\)\/.*$/\1/') | |
TARGET_REMOTE="${TARGET_REMOTE:-origin}" | |
if git rev-parse --verify main >/dev/null 2>&1; then | |
DEFAULT_TARGET_BRANCH="main" | |
else | |
DEFAULT_TARGET_BRANCH="master" | |
fi | |
TARGET_BRANCH="${TARGET_BRANCH:-${DEFAULT_TARGET_BRANCH}}" | |
function merge_base() { | |
git fetch "${TARGET_REMOTE}" | |
git merge-base "${TARGET_REMOTE}/${TARGET_BRANCH}" $1 | |
} | |
function commit_summary() { | |
git show --no-patch --format=%s $1 | |
} | |
function commit_body() { | |
git show --no-patch --format=%b $1 | |
} | |
function pr_branch() { | |
offset=$((${#KEY} + 1)) | |
commit_body $1 | grep -E "^$KEY" | cut -c ${offset}- | |
} | |
to=${2:-HEAD} | |
from=${1:-$(merge_base ${to})} | |
tail=$(git rev-parse $from) | |
head=$(git rev-parse $to) | |
git merge-base --is-ancestor $tail $head | |
repo=$(git rev-parse --show-toplevel) | |
commits=($(git rev-list --ancestry-path ${tail}..${head} | tac)) | |
for commit in "${commits[@]}"; do | |
if ! pr_branch $commit >/dev/null ; then | |
echo "Sorry but commit $commit is missing \`$KEY\`" | |
echo "" | |
echo "Try installing the Gerrit Git commit message hook and then amending your commits:" | |
echo "" | |
echo " (cd ${repo} && f=`git rev-parse --git-dir`/hooks/commit-msg ; mkdir -p \$(dirname \$f) ; curl -Lo \$f https://gerrit-review.googlesource.com/tools/hooks/commit-msg ; chmod +x \$f)" | |
echo "" | |
exit 1 | |
fi | |
done | |
remotes=() | |
for commit in "${commits[@]}"; do | |
remotes+=("${commit}:refs/heads/$(pr_branch $commit)") | |
done | |
git push $SOURCE_REMOTE --force-with-lease "${remotes[@]}" | |
if command -v gh >/dev/null; then | |
i=0 | |
for commit in "${commits[@]}"; do | |
pr=$(pr_branch $commit) | |
base=$( [[ $i -eq 0 ]] && echo "$TARGET_BRANCH" || echo "$(pr_branch ${commits[((i - 1))]})" ) | |
count=$(gh pr list --state all --head "$pr" --json id --jq length) | |
if [[ "$count" -gt 1 ]]; then | |
echo "Sorry I don't know which PR to update." | |
echo "There are multiple PRs with the same --head $pr" | |
gh pr list --state all --head "$pr" | |
exit 1 | |
fi | |
#&& [[ $(gh pr list --state all --search "$pr" | wc -l) -eq 0 ]] | |
if [[ "$count" -eq 0 ]]; then | |
gh pr create \ | |
--base "$base" \ | |
--head "${TARGET_USER}:${pr}" \ | |
--title "$(commit_summary $commit)" \ | |
--body "$(commit_body $commit)" | |
fi | |
gh pr edit "${pr}" \ | |
--base "$base" \ | |
--title "$(commit_summary $commit)" \ | |
--body "$(commit_body $commit)" || true | |
if [[ -f ".pr-update.$i.sh" ]]; then | |
bash ".pr-update.$i.sh" "$pr" | |
fi | |
((++i)) | |
done | |
fi | |
echo "🔥🔥🔥🔥🔥" | |
echo "Done! 🦙🚀" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment