blob: 002c499f8c81e2a85940297e16d1a832a5b4d964 [file] [log] [blame]
Patrick Georgi519c4b72016-09-22 12:46:45 +02001#!/bin/bash
2# $0 from-branch to-branch
3# applies all commits that from-branch has over to-branch,
4# based on a common ancestor and gerrit meta-data
5from=$1
6to=$2
7
8# match string: this is the git commit line that is used to
9# identify commits that were already copied over.
10#
11# Must not contain spaces except for leading and trailing.
12#
13# The first pick was Change-Id, but it was lost too often,
14# so go for Reviewed-on instead. It's also unique because it
15# contains the gerrit instance's host name and the change's number
16# on that system.
17match_string='^ [-A-Za-z]*[Rr]eviewed-on: '
18
19# fetch common ancestor
20common_base=$(git merge-base ${from} ${to} 2>/dev/null)
21
22if [ -z "${common_base}" ]; then
23 echo \"${from}\" or \"${to}\" is not a valid branch name.
24 exit 1
25fi
26
27# collect matches that are present on the target side
28to_matches="$(git log ${common_base}..${to} | \
29 grep "${match_string}" | \
30 cut -d: -f2-)"
31
32# start rebase process, but fail immediately by enforcing an invalid todo
33GIT_SEQUENCE_EDITOR="echo foo >" \
34 git rebase -i --onto ${to} ${from} ${to} 2>/dev/null
35
36# write new rebase todo
37# the appended "commit" line triggers handling of the last log entry
38commit=""
39(git log --reverse ${common_base}..${from} | \
40 grep -E "(^commit [0-9a-f]{40}\$|${match_string})"; \
41 echo "commit") | \
42while read key value; do
43 if [ "${key}" = "commit" ]; then
44 if [ -n "${commit}" ]; then
45 git log -n 1 --pretty="pick %h %s" ${commit}
46 fi
47 commit="${value}"
48 else
49 # if value was already found on the "to" side, skip this
50 # commit
51 if [[ ${to_matches} == *"${value}"* ]]; then
52 commit=""
53 fi
54 fi
55done | GIT_SEQUENCE_EDITOR="cat >" git rebase --edit-todo
56
57# allow user to edit todo
58git rebase --edit-todo
59
60# start processing todo to mimick git rebase -i behavior
61git rebase --continue