-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmq
executable file
·239 lines (224 loc) · 7 KB
/
mq
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#! /bin/bash
#
# Manipulating MQ files. Work with both MQ and Guilt (not complete).
# Note: no matter MQ or guilt, the repo for the patches is itself Mercurial.
#
# For guilt, make sure adding alias
# mq = ! /space/repos/external/guilt/guilt
if [ "$1" = "" ]; then
cat<<EOF
Usage:
mq back switch to guilt/master
mq log [-a] view history of patch
mq cat [-n] [name] cat this/next/named patch
mq diff [name] [r1] [r2] diff patch (def last 2)
mq revert [r] revert to another version
mq vi vi .hg/patches/series
mq ls hg qseries | head
mq pr [-b base] [name] create a branch and start pr
mq [q]push/pop/ref/new/...
EOF
exit 0
fi
function q2id {
ID=$(head -1 $MQ/$1 | perl -ne 'print "$1" if /^(\d{7}):/')
if [ "$ID" != "" ]; then
echo $ID
else
echo $1
fi
}
hg root > /dev/null 2> /dev/null
if [ $? = 0 ]; then
MERCURIAL=1
cd $(hg root)
_qq=`hg qqueue --active 2> /dev/null`
if [ "$_qq" != "patches" ]; then
MQ=.hg/patches-$_qq
else
MQ=.hg/patches
fi
else
MERCURIAL=0
if [ "$1" = "back" ]; then
git switch guilt/master
exit 0
fi
CB=`git branch --show-current`
if [[ "$CB" != "master" && "$CB" != "guilt/master" ]]; then
echo Not on master. Please run
echo git switch guilt/master
exit 1
fi
cd $(git rev-parse --show-toplevel)
MQ=.git/patches/master
fi
CMD=$1
shift
if [[ $CMD != top && $CMD != qtop ]]; then
QNAME=`mq top`
fi
case $CMD in
ls ) # what is in patch
head $MQ/$QNAME
echo ==========
lsdiff $MQ/$QNAME
;;
cat )
if [ "$1" = "" ]; then
cat $MQ/$QNAME
elif [ "$1" = "-n" ]; then
cat $MQ/`mq next`
else
cat $MQ/$1
fi
;;
vi ) # manipulate MQ order
vi $MQ/series
;;
log ) # look at history of MQ repo (-a for all, none for qtop)
if [ "$1" = "-a" ]; then
hg logs --cwd $MQ
else
hg logs --cwd $MQ $QNAME
fi
;;
diff ) # interdiff for two versions of qtop
if [ "$2" != "" ]; then # versions specified
R1=$1
R2=$2
elif [ "$1" != "" ]; then # one vs current
R1=$1
R2=`mq log | head -1 | cut -f 1 -d :`
else # latest two
R1=`mq log | head -2 | tail -1 | cut -f 1 -d :`
R2=`mq log | head -1 | cut -f 1 -d :`
fi
echo "First ($R1):"
hg --cwd $MQ log -r $R1:0 --limit 1 $QNAME
echo
echo "Second ($R2):"
hg --cwd $MQ log -r $R2:0 --limit 1 $QNAME
hg --cwd $MQ cat -r $R1 $QNAME | grep -v ^new | grep -v ^deleted > /tmp/mqdiff.1.$$
hg --cwd $MQ cat -r $R2 $QNAME | grep -v ^new | grep -v ^deleted > /tmp/mqdiff.2.$$
interdiff -i /tmp/mqdiff.1.$$ /tmp/mqdiff.2.$$
if [ $? != 0 ]; then
echo "Want to see raw diff?"
read
diff /tmp/mqdiff.1.$$ /tmp/mqdiff.2.$$
fi
;;
revert ) # revert current patch to a previous version
if [ $MERCURIAL = 0 ]; then
echo Cannot call revert in git repo
exit 1
fi
if [ -n "`hg st -mard`" ]; then
echo "Working dir must be clean"
exit 1
fi
if [ "$1" = "" ]; then
echo "Must provide a revision"
exit 1
fi
REV=$1
hg --cwd $MQ cat -r $REV $QNAME > $MQ/$QNAME
hg qpop
hg qpush
echo "MQ is updated but not committed. hg qref if you like it, or hg revert --mq $QNAME if not."
;;
help )
if [ $MERCURIAL = 1 ]; then
hg help mq
else
/space/repos/external/guilt/guilt
fi
;;
pr ) # copy qtop to a new branch for publishing
if [ $MERCURIAL = 1 ]; then
echo Cannot call pr in hg repo
exit 1
fi
QNAME=$(mq top)
# "-b bname" means the new branch will be based on another branch
if [ "$1" = "-b" ]; then
shift
QBASE=$1
shift
else
QBASE=master
fi
# branch name will be specified name, bug id, or patch name
if [ "$1" != "" ]; then # branch name specified
BRANCH=$1
else
BRANCH=`q2id $QNAME`
fi
git format-patch -1 --stdout | perl -ne 'print if //../^$/' > /tmp/pr
echo >> /tmp/pr
git diff $QBASE guilt/master >> /tmp/pr
echo "Will create a new branch $BRANCH on $QBASE to hold the change to:"
head -1 /tmp/pr
lsdiff /tmp/pr
echo "Press enter to continue, or Ctrl-C to terminate"
read
git branch $BRANCH $QBASE
git switch $BRANCH
git am /tmp/pr
echo 'You can call "git publish" and "git pr create" now.'
;;
* ) # original mq an dguilt commands
if [[ $CMD =~ ^q ]]; then # Either "qpop" and "pop" is OK
CMD=${CMD:1}
fi
if [ $MERCURIAL = 1 ]; then
hg q$CMD $@
# We have MQ hooks to record the history
else
if [ "$CMD" = "finish" ]; then
echo "Do not call finish in git"
echo "Instead, call 'mq pr' to copy the change into a branch"
ech0 "and create a PR from there."
exit 0
elif [[ "$CMD" =~ ^del ]]; then
for a in $@; do
BRANCH=`q2id $a`
git show-ref --verify --quiet refs/heads/$BRANCH &&
echo "Will remove $BRANCH at local and origin..."
done
echo "Press enter to continue, or Ctrl-C to terminate"
read
for a in $@; do
BRANCH=`q2id $a`
echo "removing $a/$BRANCH..."
git branch -d $BRANCH
git push origin --delete $BRANCH
done
fi
git mq $CMD "$@"
# Manually record the history
if [ $CMD = init ]; then
# hg init --cwd $MQ
afterqinit
else
cd $MQ
if [[ $CMD =~ ^ref ]]; then
read -p "Comment: " q
rm $QNAME~
echo "$QNAME: $q" | hg commit -A -l -
else
# Some commands will not make a change so need to
# record history. This list needs not to be complete
# as `hg commit` will find out if there's any change.
case $CMD in
top | series | pop | push | top | goto | next | prev | diff )
;;
* )
hg commit -A -m "auto-commit: $CMD $@" > /dev/null
;;
esac
fi
fi
fi
;;
esac