chiark / gitweb /
add news file
[topgit.git] / tg-import.sh
1 #!/bin/sh
2 # TopGit - A different patch queue manager
3 # (c) Petr Baudis <pasky@suse.cz>  2008
4 # (c) Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>  2008
5 # GPLv2
6
7 branch_prefix=t/
8 single=
9 ranges=
10 basedep=
11
12
13 ## Parse options
14
15 while [ -n "$1" ]; do
16         arg="$1"; shift
17         case "$arg" in
18         -d)
19                 basedep="$1"; shift;;
20         -p)
21                 branch_prefix="$1"; shift;;
22         -s)
23                 single="$1"; shift;;
24         -*)
25                 echo "Usage: tg [...] import [-d BASE_BRANCH] {[-p PREFIX] RANGE...|-s NAME COMMIT}" >&2
26                 exit 1;;
27         *)
28                 ranges="$ranges $arg";;
29         esac
30 done
31
32
33 ## Make sure our tree is clean
34
35 git update-index --ignore-submodules --refresh || exit
36 [ -z "$(git diff-index --cached --name-status -r --ignore-submodules HEAD --)" ] ||
37         die "the index is not clean"
38
39
40 ## Perform import
41
42 get_commit_msg()
43 {
44         commit="$1"
45         headers=""
46         ! header="$(git config topgit.to)" || headers="$headers%nTo: $header"
47         ! header="$(git config topgit.cc)" || headers="$headers%nCc: $header"
48         ! header="$(git config topgit.bcc)" || headers="$headers%nBcc: $header"
49         git log -1 --pretty=format:"From: %an <%ae>$headers%nSubject: %s%n%n%b" "$commit"
50 }
51
52 get_branch_name()
53 {
54         # nice sed script from git-format-patch.sh
55         commit="$1"
56         titleScript='
57         s/[^-a-z.A-Z_0-9]/-/g
58         s/\.\.\.*/\./g
59         s/\.*$//
60         s/--*/-/g
61         s/^-//
62         s/-$//
63         q
64 '
65         git log -1 --pretty=format:"%s" "$commit" | sed -e "$titleScript"
66 }
67
68 process_commit()
69 {
70         commit="$1"
71         branch_name="$2"
72         info "---- Importing $commit to $branch_name"
73         tg create "$branch_name" $basedep
74         basedep=
75         get_commit_msg "$commit" > .topmsg
76         git add -f .topmsg .topdeps
77         if ! git cherry-pick --no-commit "$commit"; then
78                 info "The commit will also finish the import of this patch."
79                 exit 2
80         fi
81         git commit -C "$commit"
82         info "++++ Importing $commit finished"
83 }
84
85 if [ -n "$single" ]; then
86         process_commit $ranges "$single"
87         exit
88 fi
89
90 # nice arg verification stolen from git-format-patch.sh
91 for revpair in $ranges
92 do
93         case "$revpair" in
94         ?*..?*)
95                 rev1=`expr "z$revpair" : 'z\(.*\)\.\.'`
96                 rev2=`expr "z$revpair" : 'z.*\.\.\(.*\)'`
97                 ;;
98         *)
99                 die "Unknow range spec $revpair"
100                 ;;
101         esac
102         git rev-parse --verify "$rev1^0" >/dev/null 2>&1 ||
103                 die "Not a valid rev $rev1 ($revpair)"
104         git rev-parse --verify "$rev2^0" >/dev/null 2>&1 ||
105                 die "Not a valid rev $rev2 ($revpair)"
106         git cherry -v "$rev1" "$rev2" |
107         while read sign rev comment
108         do
109                 case "$sign" in
110                 '-')
111                         info "Merged already: $comment"
112                         ;;
113                 *)
114                         process_commit "$rev" "$branch_prefix$(get_branch_name "$rev")"
115                         ;;
116                 esac
117         done
118 done