Skip to content

Instantly share code, notes, and snippets.

@3v1n0
Last active September 26, 2018 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 3v1n0/832522f0e1d538a68c278c467b7eb4f3 to your computer and use it in GitHub Desktop.
Save 3v1n0/832522f0e1d538a68c278c467b7eb4f3 to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# Simply cherry picks a revision from a bazaar branch, cloning its metadata
#
# Usage:
# bzr-format-patch [lp:unity] [1234] [--add-bzr-revision] [--stdout] [--only-merged] [-1]
if [ -z "$1" ]; then
if ! (bzr root &> /dev/null); then
echo "It seems you're not in a bazaar branch directory"
echo "$(basename $0) <branch location> <revision number>"
exit 1
fi
branch=$PWD
elif ! [[ "$1" =~ ^-[-a-z0-9]+$ ]]; then
branch=$1
shift
fi
if [ -n "$1" ] && ! [[ $1 =~ ^-?[0-9.]+$ ]] && ! [[ "$1" =~ ^-[-a-z0-9]+$ ]]; then
echo "Revision must be a number"
exit 1
fi
last_revision=$(bzr revision-info --tree 2> /dev/null | cut -f1 -d' ')
rev=$last_revision
if [ -n "$1" ] && [[ $1 =~ ^-?[0-9.]+$ ]]; then
rev=$1
shift
fi
cmdline_args=$*
merged=--include-merged
single_mode=false
add_bzr_revision=false
stdout=false
if (echo "$cmdline_args" | grep -q -w -- "--add-bzr-revision"); then
cmdline_args="${cmdline_args//--add-bzr-revision/}"
add_bzr_revision=true;
fi
if (echo "$cmdline_args" | grep -q -w -- "--only-merged"); then
cmdline_args="${cmdline_args//--only-merged/}"
merged=-n1;
fi
if (echo "$cmdline_args" | grep -q -w -- "--stdout"); then
cmdline_args="${cmdline_args//--stdout/}"
stdout=true;
fi
if (echo "$cmdline_args" | grep -q -w -- "-1"); then
cmdline_args="${cmdline_args//-1/}"
single_mode=true;
fi
export LC_ALL=C.UTF-8
if [[ $rev =~ ^-[0-9]+$ ]] && [ $rev -lt 0 ]; then
rev=$(($last_revision+$rev+1))
fi
rev_selection=$rev
if [ "$single_mode" == "false" ] && [[ $rev =~ ^[0-9]+$ ]]; then
rev_selection="$rev..$last_revision"
fi
function patch_revision()
{
local log="$revision_entry"
[ -z "$log" ] && return 0
log_rev="$(echo "$log" | sed -n 's/^revno: \([0-9.]\+\).*/\1/p')"
log_msg="$(echo "$log" | sed '0,/^message:$/d' | tail -n +1 | sed -e 's/^\s*//' | sed '/^Approved by: /d')"
log_author="$(echo "$log" | sed -n 's/^author: //p')"
log_time="$(echo "$log" | sed -n 's/^timestamp: \([A-Za-z]\+ \)\?//p')"
log_bugs="$(echo "$log" | sed -n 's/^fixes bugs\?: //p' | sed 's,https://launchpad.net/bugs/,,g')"
if [ -z "$log_author" ]; then
log_author="$(echo "$log" | sed -n 's/^committer: //p')"
fi
log_time=$(date --date="$log_time" -R)
if [ -z "$log_author" ]; then log_author="$(bzr whoami)"; fi
if [ -z "$log_bugs" ]; then log_bugs="$(echo "$log_msg" | sed '/Fixes: #[0-9]\+/!d' | sed 's/.*Fixes: #\([0-9#, ]\+\).*/\1/m' | sed 's/[,#]//g')"; fi
if [ -z "$log_bugs" ]; then log_bugs="$(echo "$log_msg" | sed '/(LP: [^)]\+)/!d' | sed 's/.*(LP: \([^)]\+\)).*/\1/m' | sed 's/[,#]//g')"; fi
log_msg=$(echo "$log_msg" | sed 's/Fixes: #[0-9, #]\+//')
log_msg=$(echo "$log_msg" | sed 's/(LP: [^)]\+)//')
echo "Revision: $log_rev"
echo "Author: $log_author"
echo "Time: $log_time"
for bug in $log_bugs; do echo "Bug: https://launchpad.net/bugs/$bug"; done;
echo -e "Message:\n$log_msg\n"
read -r -d '' format_patch <<EOF || true
From: $log_author
Date: $log_time
Subject: $log_msg
EOF
if [ -n "$log_bugs" ]; then
format_patch="$format_patch\n\nFixes LP:"
for bug in $log_bugs; do format_patch="$format_patch #$bug,"; done;
format_patch=${format_patch::-1}
fi
if [ "$add_bzr_revision" == true ]; then
format_patch="$format_patch\n\n(bzr r$log_rev)"
fi
diff="$(bzr di $branch -p a/:b/ -c$log_rev)"
format_patch="$format_patch\n---\n$(echo "$diff")"
if [ "$stdout" == true ]; then
dest=/dev/stdout
else
dest="$(basename $PWD)-revision-$log_rev.patch"
fi
echo -e "$format_patch" > $dest
if [ "$stdout" != true ]; then
echo "Patch saved as '$dest'"
fi
}
bzrlog="$(bzr log $merged -r$rev_selection $branch)"
if [ $? != 0 ]; then
exit_error=$?
echo "Invalid to get commit info for $branch at revision $rev"
exit $exit_error
fi
revision_entry=""
line_strip=0
while IFS= read -r line
do
if ! [[ $line =~ ([ ]*)------------------------------------------------------------ ]]; then
line="${line:$line_strip}"
if [ -z "$revision_entry" ]; then
revision_entry="$line"
else
revision_entry="$revision_entry\n$line"
fi
else
revision_entry="$(echo -e "$revision_entry")"
line_strip=$(expr length "${BASH_REMATCH[1]}")
patch_revision
revision_entry=""
fi
done <<< "$bzrlog"
patch_revision
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment