moved os-dependant code into per-os files
[guilt.git] / guilt-rebase
blob739fb262a6c34e42cfee2fd39987ce2f0a7efb44
1 #!/bin/sh
3 # Copyright (c) Josef "Jeff" Sipek, 2007
5 # Heavily based on the long removed sh version of git-cherry
8 USAGE="<upstream>"
9 . `dirname $0`/guilt
11 disp "Beware, rebase is currently EXPERIMENTAL."
12 disp "In other words, it might eat your patches."
13 _disp "Do you wish to proceed? [y/N] "
14 read n
15 if [ "$n" != "y" -a "$n" != "Y" ]; then
16 disp "Aborted."
17 exit 0
20 case "$#" in
21 1)
22 upstream=`git rev-parse --verify "$1"` &&
23 ours=`git rev-parse --verify HEAD` || usage
24 limit="$upstream"
27 usage
29 esac
31 # make sure that there are no unapplied changes
32 if ! must_commit_first; then
33 die "Uncommited changes detected. Refresh first."
34 elif [ `wc -l < "$applied"` -eq 0 ]; then
35 die "Nothing to rebase. First, you need to push patches onto the stack."
38 # Note that these list commits in reverse order;
39 # not that the order in inup matters...
40 inup=`git rev-list ^$ours $upstream` &&
41 ours=`git rev-list $ours ^$limit` || exit
43 rebase_dir="$GUILT_DIR/$branch/.rebase.$$"
44 mkdir "$rebase_dir"
47 # calculate the patch ids for all the commits in upstream
49 for c in $inup ; do
50 git diff-tree -p $c
51 done | git patch-id | while read id name ; do
52 echo "$name" >> "$rebase_dir/$id"
53 done
55 # backup the status file, so we don't have to do more work to figure out all
56 # the patches that were pushed before we started rebasing
57 cp "$applied" "$rebase_dir/status"
59 disp "First, poping all patches..."
60 pop_all_patches
61 git merge --no-commit $upstream > /dev/null 2> /dev/null
63 disp ""
64 log=`git log -1 --pretty=oneline`
65 disp "HEAD is now at `echo $log | cut -c 1-7`... `echo "$log" | cut -c 41-`"
68 # For each previously applied patch:
69 # 1) calculate the patchid
70 # 2) if the patchid matches any of the upstream commits' patchids...
71 # a) comment out the patch from the series file
72 # 3) else
73 # a) push the patch onto the stack
75 IFS=":"
76 cat "$rebase_dir/status" | while read hash name; do
77 disp ""
78 IFS=" "
79 cat "$GUILT_DIR/$branch/$name" | git patch-id |
80 while read patchid commitid ; do
81 disp "Applying '$name'"
82 if [ -f "$rebase_dir/$patchid" ]; then
83 realcommit=`head_n 1 "$rebase_dir/$patchid"`
84 disp "Matches upstream commit $realcommit"
85 series_rename_patch "$name" "###rebased###$name"
86 disp "Patch removed from series."
87 else
88 # FIXME: use a guilt function instead
89 guilt-push > /dev/null
90 disp "Patch applied."
92 done
93 IFS=":"
94 done
96 rm -rf "$rebase_dir"
98 disp ""
99 disp "Done."