File: guilt-rebase

package info (click to toggle)
guilt 0.36-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster
  • size: 1,272 kB
  • ctags: 201
  • sloc: sh: 3,062; makefile: 93; perl: 42
file content (106 lines) | stat: -rwxr-xr-x 2,555 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/bin/sh
#
# Copyright (c) Josef "Jeff" Sipek, 2007-2013
#
# Heavily based on the long removed sh version of git-cherry
#

USAGE="<upstream>"
if [ -z "$GUILT_VERSION" ]; then
	echo "Invoking `basename "$0"` directly is no longer supported." >&2
	exit 1
fi

_main() {

disp "Beware, rebase is currently EXPERIMENTAL."
disp "In other words, it might eat your patches."
_disp "Do you wish to proceed? [y/N] "
read n
if [ "$n" != "y" -a "$n" != "Y" ]; then
	disp "Aborted."
	exit 0
fi

case "$#" in
	1) 
		upstream=`git rev-parse --verify "$1"` &&
		ours=`git rev-parse --verify HEAD` || usage
		limit="$upstream"
		;;
	*)
		usage
		;;
esac

# make sure that there are no unapplied changes
if ! must_commit_first; then
	die "Uncommited changes detected. Refresh first."
elif [ `wc -l < "$applied"` -eq 0 ]; then
	die "Nothing to rebase. First, you need to push patches onto the stack."
fi

# Note that these list commits in reverse order;
# not that the order in inup matters...
inup=`git rev-list ^$ours $upstream` &&
ours=`git rev-list $ours ^$limit` || exit

rebase_dir="$GUILT_DIR/$branch/.rebase.$$"
mkdir "$rebase_dir"

#
# calculate the patch ids for all the commits in upstream
#
for c in $inup ; do
	git diff-tree -p $c
done | git patch-id | while read id name ; do
	echo "$name" >> "$rebase_dir/$id"
done

# backup the status file, so we don't have to do more work to figure out all
# the patches that were pushed before we started rebasing
cp "$applied" "$rebase_dir/status"

disp "First, poping all patches..."
pop_all_patches
git merge --no-commit $upstream > /dev/null 2> /dev/null

disp ""
log=`git log -1 --no-decorate --pretty=oneline`
disp "HEAD is now at `echo $log | cut -c 1-7`... `echo "$log" | cut -c 41-`"

#
# For each previously applied patch:
#	1) calculate the patchid
#	2) if the patchid matches any of the upstream commits' patchids...
#		a) comment out the patch from the series file
#	3) else
#		a) push the patch onto the stack
#
IFS=":"
cat "$rebase_dir/status" | while read hash name; do
	disp ""
	IFS=" "
	cat "$GUILT_DIR/$branch/$name" | git patch-id |
		while read patchid commitid ; do
			disp "Applying '$name'"
			if [ -f "$rebase_dir/$patchid" ]; then
				realcommit=`head_n 1 "$rebase_dir/$patchid"`
				disp "Matches upstream commit $realcommit"
				series_rename_patch "$name" "###rebased###$name"
				disp "Patch removed from series."
			else
				# FIXME: use a guilt function instead
				guilt-push > /dev/null
				disp "Patch applied."
			fi
		done
	IFS=":"
done

rm -rf "$rebase_dir"

disp ""
disp "Done."

}