##// END OF EJS Templates
phases: use nodemap to check for missing nodes
Sune Foldager -
r15902:4252d9f0 default
parent child Browse files
Show More
@@ -1,290 +1,291 b''
1 1 """ Mercurial phases support code
2 2
3 3 ---
4 4
5 5 Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
6 6 Logilab SA <contact@logilab.fr>
7 7 Augie Fackler <durin42@gmail.com>
8 8
9 9 This software may be used and distributed according to the terms of the
10 10 GNU General Public License version 2 or any later version.
11 11
12 12 ---
13 13
14 14 This module implements most phase logic in mercurial.
15 15
16 16
17 17 Basic Concept
18 18 =============
19 19
20 20 A 'changeset phases' is an indicator that tells us how a changeset is
21 21 manipulated and communicated. The details of each phase is described below,
22 22 here we describe the properties they have in common.
23 23
24 24 Like bookmarks, phases are not stored in history and thus are not permanent and
25 25 leave no audit trail.
26 26
27 27 First, no changeset can be in two phases at once. Phases are ordered, so they
28 28 can be considered from lowest to highest. The default, lowest phase is 'public'
29 29 - this is the normal phase of existing changesets. A child changeset can not be
30 30 in a lower phase than its parents.
31 31
32 32 These phases share a hierarchy of traits:
33 33
34 34 immutable shared
35 35 public: X X
36 36 draft: X
37 37 secret:
38 38
39 39 local commits are draft by default
40 40
41 41 Phase movement and exchange
42 42 ============================
43 43
44 44 Phase data are exchanged by pushkey on pull and push. Some server have a
45 45 publish option set, we call them publishing server. Pushing to such server make
46 46 draft changeset publish.
47 47
48 48 A small list of fact/rules define the exchange of phase:
49 49
50 50 * old client never changes server states
51 51 * pull never changes server states
52 52 * publish and old server csets are seen as public by client
53 53
54 54 * Any secret changeset seens in another repository is lowered to at least draft
55 55
56 56
57 57 Here is the final table summing up the 49 possible usecase of phase exchange:
58 58
59 59 server
60 60 old publish non-publish
61 61 N X N D P N D P
62 62 old client
63 63 pull
64 64 N - X/X - X/D X/P - X/D X/P
65 65 X - X/X - X/D X/P - X/D X/P
66 66 push
67 67 X X/X X/X X/P X/P X/P X/D X/D X/P
68 68 new client
69 69 pull
70 70 N - P/X - P/D P/P - D/D P/P
71 71 D - P/X - P/D P/P - D/D P/P
72 72 P - P/X - P/D P/P - P/D P/P
73 73 push
74 74 D P/X P/X P/P P/P P/P D/D D/D P/P
75 75 P P/X P/X P/P P/P P/P P/P P/P P/P
76 76
77 77 Legend:
78 78
79 79 A/B = final state on client / state on server
80 80
81 81 * N = new/not present,
82 82 * P = public,
83 83 * D = draft,
84 84 * X = not tracked (ie: the old client or server has no internal way of
85 85 recording the phase.)
86 86
87 87 passive = only pushes
88 88
89 89
90 90 A cell here can be read like this:
91 91
92 92 "When a new client pushes a draft changeset (D) to a publishing server
93 93 where it's not present (N), it's marked public on both sides (P/P)."
94 94
95 95 Note: old client behave as publish server with Draft only content
96 96 - other people see it as public
97 97 - content is pushed as draft
98 98
99 99 """
100 100
101 101 import errno
102 102 from node import nullid, bin, hex, short
103 103 from i18n import _
104 104
105 105 allphases = public, draft, secret = range(3)
106 106 trackedphases = allphases[1:]
107 107 phasenames = ['public', 'draft', 'secret']
108 108
109 109 def readroots(repo):
110 110 """Read phase roots from disk"""
111 111 roots = [set() for i in allphases]
112 112 roots[0].add(nullid)
113 113 try:
114 114 f = repo.sopener('phaseroots')
115 115 try:
116 116 for line in f:
117 117 phase, nh = line.strip().split()
118 118 roots[int(phase)].add(bin(nh))
119 119 finally:
120 120 f.close()
121 121 except IOError, inst:
122 122 if inst.errno != errno.ENOENT:
123 123 raise
124 124 return roots
125 125
126 126 def writeroots(repo):
127 127 """Write phase roots from disk"""
128 128 f = repo.sopener('phaseroots', 'w', atomictemp=True)
129 129 try:
130 130 for phase, roots in enumerate(repo._phaseroots):
131 131 for h in roots:
132 132 f.write('%i %s\n' % (phase, hex(h)))
133 133 repo._dirtyphases = False
134 134 finally:
135 135 f.close()
136 136
137 137 def filterunknown(repo, phaseroots=None):
138 138 """remove unknown nodes from the phase boundary
139 139
140 140 no data is lost as unknown node only old data for their descentants
141 141 """
142 142 if phaseroots is None:
143 143 phaseroots = repo._phaseroots
144 nodemap = repo.changelog.nodemap # to filter unknown nodes
144 145 for phase, nodes in enumerate(phaseroots):
145 missing = [node for node in nodes if node not in repo]
146 missing = [node for node in nodes if node not in nodemap]
146 147 if missing:
147 148 for mnode in missing:
148 149 msg = _('Removing unknown node %(n)s from %(p)i-phase boundary')
149 150 repo.ui.debug(msg, {'n': short(mnode), 'p': phase})
150 151 nodes.symmetric_difference_update(missing)
151 152 repo._dirtyphases = True
152 153
153 154 def advanceboundary(repo, targetphase, nodes):
154 155 """Add nodes to a phase changing other nodes phases if necessary.
155 156
156 157 This function move boundary *forward* this means that all nodes are set
157 158 in the target phase or kept in a *lower* phase.
158 159
159 160 Simplify boundary to contains phase roots only."""
160 161 delroots = [] # set of root deleted by this path
161 162 for phase in xrange(targetphase + 1, len(allphases)):
162 163 # filter nodes that are not in a compatible phase already
163 164 # XXX rev phase cache might have been invalidated by a previous loop
164 165 # XXX we need to be smarter here
165 166 nodes = [n for n in nodes if repo[n].phase() >= phase]
166 167 if not nodes:
167 168 break # no roots to move anymore
168 169 roots = repo._phaseroots[phase]
169 170 olds = roots.copy()
170 171 ctxs = list(repo.set('roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
171 172 roots.clear()
172 173 roots.update(ctx.node() for ctx in ctxs)
173 174 if olds != roots:
174 175 # invalidate cache (we probably could be smarter here
175 176 if '_phaserev' in vars(repo):
176 177 del repo._phaserev
177 178 repo._dirtyphases = True
178 179 # some roots may need to be declared for lower phases
179 180 delroots.extend(olds - roots)
180 181 # declare deleted root in the target phase
181 182 if targetphase != 0:
182 183 retractboundary(repo, targetphase, delroots)
183 184
184 185
185 186 def retractboundary(repo, targetphase, nodes):
186 187 """Set nodes back to a phase changing other nodes phases if necessary.
187 188
188 189 This function move boundary *backward* this means that all nodes are set
189 190 in the target phase or kept in a *higher* phase.
190 191
191 192 Simplify boundary to contains phase roots only."""
192 193 currentroots = repo._phaseroots[targetphase]
193 194 newroots = [n for n in nodes if repo[n].phase() < targetphase]
194 195 if newroots:
195 196 currentroots.update(newroots)
196 197 ctxs = repo.set('roots(%ln::)', currentroots)
197 198 currentroots.intersection_update(ctx.node() for ctx in ctxs)
198 199 if '_phaserev' in vars(repo):
199 200 del repo._phaserev
200 201 repo._dirtyphases = True
201 202
202 203
203 204 def listphases(repo):
204 205 """List phases root for serialisation over pushkey"""
205 206 keys = {}
206 207 value = '%i' % draft
207 208 for root in repo._phaseroots[draft]:
208 209 keys[hex(root)] = value
209 210
210 211 if repo.ui.configbool('phases', 'publish', True):
211 212 # Add an extra data to let remote know we are a publishing repo.
212 213 # Publishing repo can't just pretend they are old repo. When pushing to
213 214 # a publishing repo, the client still need to push phase boundary
214 215 #
215 216 # Push do not only push changeset. It also push phase data. New
216 217 # phase data may apply to common changeset which won't be push (as they
217 218 # are common). Here is a very simple example:
218 219 #
219 220 # 1) repo A push changeset X as draft to repo B
220 221 # 2) repo B make changeset X public
221 222 # 3) repo B push to repo A. X is not pushed but the data that X as now
222 223 # public should
223 224 #
224 225 # The server can't handle it on it's own as it has no idea of client
225 226 # phase data.
226 227 keys['publishing'] = 'True'
227 228 return keys
228 229
229 230 def pushphase(repo, nhex, oldphasestr, newphasestr):
230 231 """List phases root for serialisation over pushkey"""
231 232 lock = repo.lock()
232 233 try:
233 234 currentphase = repo[nhex].phase()
234 235 newphase = abs(int(newphasestr)) # let's avoid negative index surprise
235 236 oldphase = abs(int(oldphasestr)) # let's avoid negative index surprise
236 237 if currentphase == oldphase and newphase < oldphase:
237 238 advanceboundary(repo, newphase, [bin(nhex)])
238 239 return 1
239 240 else:
240 241 return 0
241 242 finally:
242 243 lock.release()
243 244
244 245 def visibleheads(repo):
245 246 """return the set of visible head of this repo"""
246 247 # XXX we want a cache on this
247 248 sroots = repo._phaseroots[secret]
248 249 if sroots:
249 250 # XXX very slow revset. storing heads or secret "boundary" would help.
250 251 revset = repo.set('heads(not (%ln::))', sroots)
251 252
252 253 vheads = [ctx.node() for ctx in revset]
253 254 if not vheads:
254 255 vheads.append(nullid)
255 256 else:
256 257 vheads = repo.heads()
257 258 return vheads
258 259
259 260 def analyzeremotephases(repo, subset, roots):
260 261 """Compute phases heads and root in a subset of node from root dict
261 262
262 263 * subset is heads of the subset
263 264 * roots is {<nodeid> => phase} mapping. key and value are string.
264 265
265 266 Accept unknown element input
266 267 """
267 268 # build list from dictionary
268 269 draftroots = []
269 nm = repo.changelog.nodemap # to filter unknown node
270 nodemap = repo.changelog.nodemap # to filter unknown nodes
270 271 for nhex, phase in roots.iteritems():
271 272 if nhex == 'publishing': # ignore data related to publish option
272 273 continue
273 274 node = bin(nhex)
274 275 phase = int(phase)
275 276 if phase == 0:
276 277 if node != nullid:
277 278 msg = _('ignoring inconsistense public root from remote: %s')
278 279 repo.ui.warn(msg, nhex)
279 280 elif phase == 1:
280 if node in nm:
281 if node in nodemap:
281 282 draftroots.append(node)
282 283 else:
283 284 msg = _('ignoring unexpected root from remote: %i %s')
284 285 repo.ui.warn(msg, phase, nhex)
285 286 # compute heads
286 287 revset = repo.set('heads((%ln + parents(%ln)) - (%ln::%ln))',
287 288 subset, draftroots, draftroots, subset)
288 289 publicheads = [c.node() for c in revset]
289 290 return publicheads, draftroots
290 291
@@ -1,1107 +1,1108 b''
1 1 $ "$TESTDIR/hghave" symlink unix-permissions serve || exit 80
2 2
3 3 $ cat <<EOF >> $HGRCPATH
4 4 > [extensions]
5 5 > keyword =
6 6 > mq =
7 7 > notify =
8 8 > record =
9 9 > transplant =
10 10 > [ui]
11 11 > interactive = true
12 12 > EOF
13 13
14 14 Run kwdemo before [keyword] files are set up
15 15 as it would succeed without uisetup otherwise
16 16
17 17 $ hg --quiet kwdemo
18 18 [extensions]
19 19 keyword =
20 20 [keyword]
21 21 demo.txt =
22 22 [keywordset]
23 23 svn = False
24 24 [keywordmaps]
25 25 Author = {author|user}
26 26 Date = {date|utcdate}
27 27 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
28 28 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
29 29 RCSFile = {file|basename},v
30 30 RCSfile = {file|basename},v
31 31 Revision = {node|short}
32 32 Source = {root}/{file},v
33 33 $Author: test $
34 34 $Date: ????/??/?? ??:??:?? $ (glob)
35 35 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
36 36 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
37 37 $RCSFile: demo.txt,v $
38 38 $RCSfile: demo.txt,v $
39 39 $Revision: ???????????? $ (glob)
40 40 $Source: */demo.txt,v $ (glob)
41 41
42 42 $ hg --quiet kwdemo "Branch = {branches}"
43 43 [extensions]
44 44 keyword =
45 45 [keyword]
46 46 demo.txt =
47 47 [keywordset]
48 48 svn = False
49 49 [keywordmaps]
50 50 Branch = {branches}
51 51 $Branch: demobranch $
52 52
53 53 $ cat <<EOF >> $HGRCPATH
54 54 > [keyword]
55 55 > ** =
56 56 > b = ignore
57 57 > i = ignore
58 58 > [hooks]
59 59 > EOF
60 60 $ cp $HGRCPATH $HGRCPATH.nohooks
61 61 > cat <<EOF >> $HGRCPATH
62 62 > commit=
63 63 > commit.test=cp a hooktest
64 64 > EOF
65 65
66 66 $ hg init Test-bndl
67 67 $ cd Test-bndl
68 68
69 69 kwshrink should exit silently in empty/invalid repo
70 70
71 71 $ hg kwshrink
72 72
73 73 Symlinks cannot be created on Windows.
74 74 A bundle to test this was made with:
75 75 hg init t
76 76 cd t
77 77 echo a > a
78 78 ln -s a sym
79 79 hg add sym
80 80 hg ci -m addsym -u mercurial
81 81 hg bundle --base null ../test-keyword.hg
82 82
83 83 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
84 84 pulling from *test-keyword.hg (glob)
85 85 requesting all changes
86 86 adding changesets
87 87 adding manifests
88 88 adding file changes
89 89 added 1 changesets with 1 changes to 1 files
90 90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 91
92 92 $ echo 'expand $Id$' > a
93 93 $ echo 'do not process $Id:' >> a
94 94 $ echo 'xxx $' >> a
95 95 $ echo 'ignore $Id$' > b
96 96
97 97 Output files as they were created
98 98
99 99 $ cat a b
100 100 expand $Id$
101 101 do not process $Id:
102 102 xxx $
103 103 ignore $Id$
104 104
105 105 no kwfiles
106 106
107 107 $ hg kwfiles
108 108
109 109 untracked candidates
110 110
111 111 $ hg -v kwfiles --unknown
112 112 k a
113 113
114 114 Add files and check status
115 115
116 116 $ hg addremove
117 117 adding a
118 118 adding b
119 119 $ hg status
120 120 A a
121 121 A b
122 122
123 123
124 124 Default keyword expansion including commit hook
125 125 Interrupted commit should not change state or run commit hook
126 126
127 127 $ hg --debug commit
128 128 abort: empty commit message
129 129 [255]
130 130 $ hg status
131 131 A a
132 132 A b
133 133
134 134 Commit with several checks
135 135
136 136 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
137 137 a
138 138 b
139 139 overwriting a expanding keywords
140 140 running hook commit.test: cp a hooktest
141 141 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
142 142 $ hg status
143 143 ? hooktest
144 144 $ hg debugrebuildstate
145 145 $ hg --quiet identify
146 146 ef63ca68695b
147 147
148 148 cat files in working directory with keywords expanded
149 149
150 150 $ cat a b
151 151 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
152 152 do not process $Id:
153 153 xxx $
154 154 ignore $Id$
155 155
156 156 hg cat files and symlink, no expansion
157 157
158 158 $ hg cat sym a b && echo
159 159 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
160 160 do not process $Id:
161 161 xxx $
162 162 ignore $Id$
163 163 a
164 164
165 165 $ diff a hooktest
166 166
167 167 $ cp $HGRCPATH.nohooks $HGRCPATH
168 168 $ rm hooktest
169 169
170 170 hg status of kw-ignored binary file starting with '\1\n'
171 171
172 172 $ printf '\1\nfoo' > i
173 173 $ hg -q commit -Am metasep i
174 174 $ hg status
175 175 $ printf '\1\nbar' > i
176 176 $ hg status
177 177 M i
178 178 $ hg -q commit -m "modify metasep" i
179 179 $ hg status --rev 2:3
180 180 M i
181 181 $ touch empty
182 182 $ hg -q commit -A -m "another file"
183 183 $ hg status -A --rev 3:4 i
184 184 C i
185 185
186 186 $ hg -q strip -n 2
187 187
188 188 Test hook execution
189 189
190 190 bundle
191 191
192 192 $ hg bundle --base null ../kw.hg
193 193 2 changesets found
194 194 $ cd ..
195 195 $ hg init Test
196 196 $ cd Test
197 197
198 198 Notify on pull to check whether keywords stay as is in email
199 199 ie. if patch.diff wrapper acts as it should
200 200
201 201 $ cat <<EOF >> $HGRCPATH
202 202 > [hooks]
203 203 > incoming.notify = python:hgext.notify.hook
204 204 > [notify]
205 205 > sources = pull
206 206 > diffstat = False
207 207 > maxsubject = 15
208 208 > [reposubs]
209 209 > * = Test
210 210 > EOF
211 211
212 212 Pull from bundle and trigger notify
213 213
214 214 $ hg pull -u ../kw.hg
215 215 pulling from ../kw.hg
216 216 requesting all changes
217 217 adding changesets
218 218 adding manifests
219 219 adding file changes
220 220 added 2 changesets with 3 changes to 3 files
221 221 Content-Type: text/plain; charset="us-ascii"
222 222 MIME-Version: 1.0
223 223 Content-Transfer-Encoding: 7bit
224 224 Date: * (glob)
225 225 Subject: changeset in...
226 226 From: mercurial
227 227 X-Hg-Notification: changeset a2392c293916
228 228 Message-Id: <hg.a2392c293916*> (glob)
229 229 To: Test
230 230
231 231 changeset a2392c293916 in $TESTTMP/Test (glob)
232 232 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
233 233 description:
234 234 addsym
235 235
236 236 diffs (6 lines):
237 237
238 238 diff -r 000000000000 -r a2392c293916 sym
239 239 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
240 240 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
241 241 @@ -0,0 +1,1 @@
242 242 +a
243 243 \ No newline at end of file
244 244 Content-Type: text/plain; charset="us-ascii"
245 245 MIME-Version: 1.0
246 246 Content-Transfer-Encoding: 7bit
247 247 Date:* (glob)
248 248 Subject: changeset in...
249 249 From: User Name <user@example.com>
250 250 X-Hg-Notification: changeset ef63ca68695b
251 251 Message-Id: <hg.ef63ca68695b*> (glob)
252 252 To: Test
253 253
254 254 changeset ef63ca68695b in $TESTTMP/Test (glob)
255 255 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
256 256 description:
257 257 absym
258 258
259 259 diffs (12 lines):
260 260
261 261 diff -r a2392c293916 -r ef63ca68695b a
262 262 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
263 263 +++ b/a Thu Jan 01 00:00:00 1970 +0000
264 264 @@ -0,0 +1,3 @@
265 265 +expand $Id$
266 266 +do not process $Id:
267 267 +xxx $
268 268 diff -r a2392c293916 -r ef63ca68695b b
269 269 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
270 270 +++ b/b Thu Jan 01 00:00:00 1970 +0000
271 271 @@ -0,0 +1,1 @@
272 272 +ignore $Id$
273 273 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
274 274
275 275 $ cp $HGRCPATH.nohooks $HGRCPATH
276 276
277 277 Touch files and check with status
278 278
279 279 $ touch a b
280 280 $ hg status
281 281
282 282 Update and expand
283 283
284 284 $ rm sym a b
285 285 $ hg update -C
286 286 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
287 287 $ cat a b
288 288 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
289 289 do not process $Id:
290 290 xxx $
291 291 ignore $Id$
292 292
293 293 Check whether expansion is filewise and file mode is preserved
294 294
295 295 $ echo '$Id$' > c
296 296 $ echo 'tests for different changenodes' >> c
297 297 $ chmod 600 c
298 298 $ ls -l c | cut -b 1-10
299 299 -rw-------
300 300
301 301 commit file c
302 302
303 303 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
304 304 adding c
305 305 $ ls -l c | cut -b 1-10
306 306 -rw-------
307 307
308 308 force expansion
309 309
310 310 $ hg -v kwexpand
311 311 overwriting a expanding keywords
312 312 overwriting c expanding keywords
313 313
314 314 compare changenodes in a and c
315 315
316 316 $ cat a c
317 317 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
318 318 do not process $Id:
319 319 xxx $
320 320 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
321 321 tests for different changenodes
322 322
323 323 record
324 324
325 325 $ echo '$Id$' > r
326 326 $ hg add r
327 327
328 328 record chunk
329 329
330 330 >>> lines = open('a').readlines()
331 331 >>> lines.insert(1, 'foo\n')
332 332 >>> lines.append('bar\n')
333 333 >>> open('a', 'w').writelines(lines)
334 334 $ hg record -d '1 10' -m rectest a<<EOF
335 335 > y
336 336 > y
337 337 > n
338 338 > EOF
339 339 diff --git a/a b/a
340 340 2 hunks, 2 lines changed
341 341 examine changes to 'a'? [Ynsfdaq?]
342 342 @@ -1,3 +1,4 @@
343 343 expand $Id$
344 344 +foo
345 345 do not process $Id:
346 346 xxx $
347 347 record change 1/2 to 'a'? [Ynsfdaq?]
348 348 @@ -2,2 +3,3 @@
349 349 do not process $Id:
350 350 xxx $
351 351 +bar
352 352 record change 2/2 to 'a'? [Ynsfdaq?]
353 353
354 354 $ hg identify
355 355 d17e03c92c97+ tip
356 356 $ hg status
357 357 M a
358 358 A r
359 359
360 360 Cat modified file a
361 361
362 362 $ cat a
363 363 expand $Id: a,v d17e03c92c97 1970/01/01 00:00:01 test $
364 364 foo
365 365 do not process $Id:
366 366 xxx $
367 367 bar
368 368
369 369 Diff remaining chunk
370 370
371 371 $ hg diff a
372 372 diff -r d17e03c92c97 a
373 373 --- a/a Wed Dec 31 23:59:51 1969 -0000
374 374 +++ b/a * (glob)
375 375 @@ -2,3 +2,4 @@
376 376 foo
377 377 do not process $Id:
378 378 xxx $
379 379 +bar
380 380
381 381 $ hg rollback
382 382 repository tip rolled back to revision 2 (undo commit)
383 383 working directory now based on revision 2
384 384
385 385 Record all chunks in file a
386 386
387 387 $ echo foo > msg
388 388
389 389 - do not use "hg record -m" here!
390 390
391 391 $ hg record -l msg -d '1 11' a<<EOF
392 392 > y
393 393 > y
394 394 > y
395 395 > EOF
396 396 diff --git a/a b/a
397 397 2 hunks, 2 lines changed
398 398 examine changes to 'a'? [Ynsfdaq?]
399 399 @@ -1,3 +1,4 @@
400 400 expand $Id$
401 401 +foo
402 402 do not process $Id:
403 403 xxx $
404 404 record change 1/2 to 'a'? [Ynsfdaq?]
405 405 @@ -2,2 +3,3 @@
406 406 do not process $Id:
407 407 xxx $
408 408 +bar
409 409 record change 2/2 to 'a'? [Ynsfdaq?]
410 410
411 411 File a should be clean
412 412
413 413 $ hg status -A a
414 414 C a
415 415
416 416 rollback and revert expansion
417 417
418 418 $ cat a
419 419 expand $Id: a,v 59f969a3b52c 1970/01/01 00:00:01 test $
420 420 foo
421 421 do not process $Id:
422 422 xxx $
423 423 bar
424 424 $ hg --verbose rollback
425 425 repository tip rolled back to revision 2 (undo commit)
426 426 working directory now based on revision 2
427 427 overwriting a expanding keywords
428 428 $ hg status a
429 429 M a
430 430 $ cat a
431 431 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
432 432 foo
433 433 do not process $Id:
434 434 xxx $
435 435 bar
436 436 $ echo '$Id$' > y
437 437 $ echo '$Id$' > z
438 438 $ hg add y
439 439 $ hg commit -Am "rollback only" z
440 440 $ cat z
441 441 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
442 442 $ hg --verbose rollback
443 443 repository tip rolled back to revision 2 (undo commit)
444 444 working directory now based on revision 2
445 445 overwriting z shrinking keywords
446 446
447 447 Only z should be overwritten
448 448
449 449 $ hg status a y z
450 450 M a
451 451 A y
452 452 A z
453 453 $ cat z
454 454 $Id$
455 455 $ hg forget y z
456 456 $ rm y z
457 457
458 458 record added file alone
459 459
460 460 $ hg -v record -l msg -d '1 12' r<<EOF
461 461 > y
462 462 > EOF
463 463 diff --git a/r b/r
464 464 new file mode 100644
465 465 examine changes to 'r'? [Ynsfdaq?]
466 466 r
467 467 committed changeset 3:899491280810
468 468 overwriting r expanding keywords
469 469 - status call required for dirstate.normallookup() check
470 470 $ hg status r
471 471 $ hg --verbose rollback
472 472 repository tip rolled back to revision 2 (undo commit)
473 473 working directory now based on revision 2
474 474 overwriting r shrinking keywords
475 475 $ hg forget r
476 476 $ rm msg r
477 477 $ hg update -C
478 478 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
479 479
480 480 record added keyword ignored file
481 481
482 482 $ echo '$Id$' > i
483 483 $ hg add i
484 484 $ hg --verbose record -d '1 13' -m recignored<<EOF
485 485 > y
486 486 > EOF
487 487 diff --git a/i b/i
488 488 new file mode 100644
489 489 examine changes to 'i'? [Ynsfdaq?]
490 490 i
491 491 committed changeset 3:5f40fe93bbdc
492 492 $ cat i
493 493 $Id$
494 494 $ hg -q rollback
495 495 $ hg forget i
496 496 $ rm i
497 497
498 498 Test patch queue repo
499 499
500 500 $ hg init --mq
501 501 $ hg qimport -r tip -n mqtest.diff
502 502 $ hg commit --mq -m mqtest
503 503
504 504 Keywords should not be expanded in patch
505 505
506 506 $ cat .hg/patches/mqtest.diff
507 507 # HG changeset patch
508 508 # User User Name <user@example.com>
509 509 # Date 1 0
510 510 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
511 511 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
512 512 cndiff
513 513
514 514 diff -r ef63ca68695b -r 40a904bbbe4c c
515 515 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
516 516 +++ b/c Thu Jan 01 00:00:01 1970 +0000
517 517 @@ -0,0 +1,2 @@
518 518 +$Id$
519 519 +tests for different changenodes
520 520
521 521 $ hg qpop
522 522 popping mqtest.diff
523 523 patch queue now empty
524 524
525 525 qgoto, implying qpush, should expand
526 526
527 527 $ hg qgoto mqtest.diff
528 528 applying mqtest.diff
529 529 now at: mqtest.diff
530 530 $ cat c
531 531 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
532 532 tests for different changenodes
533 533 $ hg cat c
534 534 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
535 535 tests for different changenodes
536 536
537 537 Keywords should not be expanded in filelog
538 538
539 539 $ hg --config 'extensions.keyword=!' cat c
540 540 $Id$
541 541 tests for different changenodes
542 542
543 543 qpop and move on
544 544
545 545 $ hg qpop
546 546 popping mqtest.diff
547 547 patch queue now empty
548 548
549 549 Copy and show added kwfiles
550 550
551 551 $ hg cp a c
552 552 $ hg kwfiles
553 553 a
554 554 c
555 555
556 556 Commit and show expansion in original and copy
557 557
558 558 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
559 invalidating branch cache (tip differs)
559 560 c
560 561 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
561 562 overwriting c expanding keywords
562 563 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
563 564 $ cat a c
564 565 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
565 566 do not process $Id:
566 567 xxx $
567 568 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
568 569 do not process $Id:
569 570 xxx $
570 571
571 572 Touch copied c and check its status
572 573
573 574 $ touch c
574 575 $ hg status
575 576
576 577 Copy kwfile to keyword ignored file unexpanding keywords
577 578
578 579 $ hg --verbose copy a i
579 580 copying a to i
580 581 overwriting i shrinking keywords
581 582 $ head -n 1 i
582 583 expand $Id$
583 584 $ hg forget i
584 585 $ rm i
585 586
586 587 Copy ignored file to ignored file: no overwriting
587 588
588 589 $ hg --verbose copy b i
589 590 copying b to i
590 591 $ hg forget i
591 592 $ rm i
592 593
593 594 cp symlink file; hg cp -A symlink file (part1)
594 595 - copied symlink points to kwfile: overwrite
595 596
596 597 $ cp sym i
597 598 $ ls -l i
598 599 -rw-r--r--* (glob)
599 600 $ head -1 i
600 601 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
601 602 $ hg copy --after --verbose sym i
602 603 copying sym to i
603 604 overwriting i shrinking keywords
604 605 $ head -1 i
605 606 expand $Id$
606 607 $ hg forget i
607 608 $ rm i
608 609
609 610 Test different options of hg kwfiles
610 611
611 612 $ hg kwfiles
612 613 a
613 614 c
614 615 $ hg -v kwfiles --ignore
615 616 I b
616 617 I sym
617 618 $ hg kwfiles --all
618 619 K a
619 620 K c
620 621 I b
621 622 I sym
622 623
623 624 Diff specific revision
624 625
625 626 $ hg diff --rev 1
626 627 diff -r ef63ca68695b c
627 628 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
628 629 +++ b/c * (glob)
629 630 @@ -0,0 +1,3 @@
630 631 +expand $Id$
631 632 +do not process $Id:
632 633 +xxx $
633 634
634 635 Status after rollback:
635 636
636 637 $ hg rollback
637 638 repository tip rolled back to revision 1 (undo commit)
638 639 working directory now based on revision 1
639 640 $ hg status
640 641 A c
641 642 $ hg update --clean
642 643 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
643 644
644 645 cp symlink file; hg cp -A symlink file (part2)
645 646 - copied symlink points to kw ignored file: do not overwrite
646 647
647 648 $ cat a > i
648 649 $ ln -s i symignored
649 650 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
650 651 $ cp symignored x
651 652 $ hg copy --after --verbose symignored x
652 653 copying symignored to x
653 654 $ head -n 1 x
654 655 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
655 656 $ hg forget x
656 657 $ rm x
657 658
658 659 $ hg rollback
659 660 repository tip rolled back to revision 1 (undo commit)
660 661 working directory now based on revision 1
661 662 $ hg update --clean
662 663 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
663 664 $ rm i symignored
664 665
665 666 Custom keywordmaps as argument to kwdemo
666 667
667 668 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
668 669 [extensions]
669 670 keyword =
670 671 [keyword]
671 672 ** =
672 673 b = ignore
673 674 demo.txt =
674 675 i = ignore
675 676 [keywordset]
676 677 svn = False
677 678 [keywordmaps]
678 679 Xinfo = {author}: {desc}
679 680 $Xinfo: test: hg keyword configuration and expansion example $
680 681
681 682 Configure custom keywordmaps
682 683
683 684 $ cat <<EOF >>$HGRCPATH
684 685 > [keywordmaps]
685 686 > Id = {file} {node|short} {date|rfc822date} {author|user}
686 687 > Xinfo = {author}: {desc}
687 688 > EOF
688 689
689 690 Cat and hg cat files before custom expansion
690 691
691 692 $ cat a b
692 693 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
693 694 do not process $Id:
694 695 xxx $
695 696 ignore $Id$
696 697 $ hg cat sym a b && echo
697 698 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
698 699 do not process $Id:
699 700 xxx $
700 701 ignore $Id$
701 702 a
702 703
703 704 Write custom keyword and prepare multiline commit message
704 705
705 706 $ echo '$Xinfo$' >> a
706 707 $ cat <<EOF >> log
707 708 > firstline
708 709 > secondline
709 710 > EOF
710 711
711 712 Interrupted commit should not change state
712 713
713 714 $ hg commit
714 715 abort: empty commit message
715 716 [255]
716 717 $ hg status
717 718 M a
718 719 ? c
719 720 ? log
720 721
721 722 Commit with multiline message and custom expansion
722 723
723 724 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
724 725 a
725 726 overwriting a expanding keywords
726 727 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
727 728 $ rm log
728 729
729 730 Stat, verify and show custom expansion (firstline)
730 731
731 732 $ hg status
732 733 ? c
733 734 $ hg verify
734 735 checking changesets
735 736 checking manifests
736 737 crosschecking files in changesets and manifests
737 738 checking files
738 739 3 files, 3 changesets, 4 total revisions
739 740 $ cat a b
740 741 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
741 742 do not process $Id:
742 743 xxx $
743 744 $Xinfo: User Name <user@example.com>: firstline $
744 745 ignore $Id$
745 746 $ hg cat sym a b && echo
746 747 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
747 748 do not process $Id:
748 749 xxx $
749 750 $Xinfo: User Name <user@example.com>: firstline $
750 751 ignore $Id$
751 752 a
752 753
753 754 annotate
754 755
755 756 $ hg annotate a
756 757 1: expand $Id$
757 758 1: do not process $Id:
758 759 1: xxx $
759 760 2: $Xinfo$
760 761
761 762 remove with status checks
762 763
763 764 $ hg debugrebuildstate
764 765 $ hg remove a
765 766 $ hg --debug commit -m rma
766 767 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
767 768 $ hg status
768 769 ? c
769 770
770 771 Rollback, revert, and check expansion
771 772
772 773 $ hg rollback
773 774 repository tip rolled back to revision 2 (undo commit)
774 775 working directory now based on revision 2
775 776 $ hg status
776 777 R a
777 778 ? c
778 779 $ hg revert --no-backup --rev tip a
779 780 $ cat a
780 781 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
781 782 do not process $Id:
782 783 xxx $
783 784 $Xinfo: User Name <user@example.com>: firstline $
784 785
785 786 Clone to test global and local configurations
786 787
787 788 $ cd ..
788 789
789 790 Expansion in destinaton with global configuration
790 791
791 792 $ hg --quiet clone Test globalconf
792 793 $ cat globalconf/a
793 794 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
794 795 do not process $Id:
795 796 xxx $
796 797 $Xinfo: User Name <user@example.com>: firstline $
797 798
798 799 No expansion in destination with local configuration in origin only
799 800
800 801 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
801 802 $ cat localconf/a
802 803 expand $Id$
803 804 do not process $Id:
804 805 xxx $
805 806 $Xinfo$
806 807
807 808 Clone to test incoming
808 809
809 810 $ hg clone -r1 Test Test-a
810 811 adding changesets
811 812 adding manifests
812 813 adding file changes
813 814 added 2 changesets with 3 changes to 3 files
814 815 updating to branch default
815 816 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
816 817 $ cd Test-a
817 818 $ cat <<EOF >> .hg/hgrc
818 819 > [paths]
819 820 > default = ../Test
820 821 > EOF
821 822 $ hg incoming
822 823 comparing with $TESTTMP/Test (glob)
823 824 searching for changes
824 825 changeset: 2:bb948857c743
825 826 tag: tip
826 827 user: User Name <user@example.com>
827 828 date: Thu Jan 01 00:00:02 1970 +0000
828 829 summary: firstline
829 830
830 831 Imported patch should not be rejected
831 832
832 833 >>> import re
833 834 >>> text = re.sub(r'(Id.*)', r'\1 rejecttest', open('a').read())
834 835 >>> open('a', 'wb').write(text)
835 836 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
836 837 a
837 838 overwriting a expanding keywords
838 839 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
839 840 $ hg export -o ../rejecttest.diff tip
840 841 $ cd ../Test
841 842 $ hg import ../rejecttest.diff
842 843 applying ../rejecttest.diff
843 844 $ cat a b
844 845 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
845 846 do not process $Id: rejecttest
846 847 xxx $
847 848 $Xinfo: User Name <user@example.com>: rejects? $
848 849 ignore $Id$
849 850
850 851 $ hg rollback
851 852 repository tip rolled back to revision 2 (undo import)
852 853 working directory now based on revision 2
853 854 $ hg update --clean
854 855 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
855 856
856 857 kwexpand/kwshrink on selected files
857 858
858 859 $ mkdir x
859 860 $ hg copy a x/a
860 861 $ hg --verbose kwshrink a
861 862 overwriting a shrinking keywords
862 863 - sleep required for dirstate.normal() check
863 864 $ sleep 1
864 865 $ hg status a
865 866 $ hg --verbose kwexpand a
866 867 overwriting a expanding keywords
867 868 $ hg status a
868 869
869 870 kwexpand x/a should abort
870 871
871 872 $ hg --verbose kwexpand x/a
872 873 abort: outstanding uncommitted changes
873 874 [255]
874 875 $ cd x
875 876 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
876 877 x/a
877 878 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
878 879 overwriting x/a expanding keywords
879 880 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
880 881 $ cat a
881 882 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
882 883 do not process $Id:
883 884 xxx $
884 885 $Xinfo: User Name <user@example.com>: xa $
885 886
886 887 kwshrink a inside directory x
887 888
888 889 $ hg --verbose kwshrink a
889 890 overwriting x/a shrinking keywords
890 891 $ cat a
891 892 expand $Id$
892 893 do not process $Id:
893 894 xxx $
894 895 $Xinfo$
895 896 $ cd ..
896 897
897 898 kwexpand nonexistent
898 899
899 900 $ hg kwexpand nonexistent
900 901 nonexistent:* (glob)
901 902
902 903
903 904 hg serve
904 905 - expand with hgweb file
905 906 - no expansion with hgweb annotate/changeset/filediff
906 907 - check errors
907 908
908 909 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
909 910 $ cat hg.pid >> $DAEMON_PIDS
910 911 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/file/tip/a/?style=raw'
911 912 200 Script output follows
912 913
913 914 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
914 915 do not process $Id:
915 916 xxx $
916 917 $Xinfo: User Name <user@example.com>: firstline $
917 918 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/annotate/tip/a/?style=raw'
918 919 200 Script output follows
919 920
920 921
921 922 user@1: expand $Id$
922 923 user@1: do not process $Id:
923 924 user@1: xxx $
924 925 user@2: $Xinfo$
925 926
926 927
927 928
928 929
929 930 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/rev/tip/?style=raw'
930 931 200 Script output follows
931 932
932 933
933 934 # HG changeset patch
934 935 # User User Name <user@example.com>
935 936 # Date 3 0
936 937 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
937 938 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
938 939 xa
939 940
940 941 diff -r bb948857c743 -r b4560182a3f9 x/a
941 942 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
942 943 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
943 944 @@ -0,0 +1,4 @@
944 945 +expand $Id$
945 946 +do not process $Id:
946 947 +xxx $
947 948 +$Xinfo$
948 949
949 950 $ $TESTDIR/get-with-headers.py localhost:$HGPORT '/diff/bb948857c743/a?style=raw'
950 951 200 Script output follows
951 952
952 953
953 954 diff -r ef63ca68695b -r bb948857c743 a
954 955 --- a/a Thu Jan 01 00:00:00 1970 +0000
955 956 +++ b/a Thu Jan 01 00:00:02 1970 +0000
956 957 @@ -1,3 +1,4 @@
957 958 expand $Id$
958 959 do not process $Id:
959 960 xxx $
960 961 +$Xinfo$
961 962
962 963
963 964
964 965
965 966 $ cat errors.log
966 967
967 968 Prepare merge and resolve tests
968 969
969 970 $ echo '$Id$' > m
970 971 $ hg add m
971 972 $ hg commit -m 4kw
972 973 $ echo foo >> m
973 974 $ hg commit -m 5foo
974 975
975 976 simplemerge
976 977
977 978 $ hg update 4
978 979 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
979 980 $ echo foo >> m
980 981 $ hg commit -m 6foo
981 982 created new head
982 983 $ hg merge
983 984 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
984 985 (branch merge, don't forget to commit)
985 986 $ hg commit -m simplemerge
986 987 $ cat m
987 988 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
988 989 foo
989 990
990 991 conflict: keyword should stay outside conflict zone
991 992
992 993 $ hg update 4
993 994 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
994 995 $ echo bar >> m
995 996 $ hg commit -m 8bar
996 997 created new head
997 998 $ hg merge
998 999 merging m
999 1000 warning: conflicts during merge.
1000 1001 merging m incomplete! (edit conflicts, then use 'hg resolve --mark')
1001 1002 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1002 1003 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1003 1004 [1]
1004 1005 $ cat m
1005 1006 $Id$
1006 1007 <<<<<<< local
1007 1008 bar
1008 1009 =======
1009 1010 foo
1010 1011 >>>>>>> other
1011 1012
1012 1013 resolve to local
1013 1014
1014 1015 $ HGMERGE=internal:local hg resolve -a
1015 1016 $ hg commit -m localresolve
1016 1017 $ cat m
1017 1018 $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
1018 1019 bar
1019 1020
1020 1021 Test restricted mode with transplant -b
1021 1022
1022 1023 $ hg update 6
1023 1024 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1024 1025 $ hg branch foo
1025 1026 marked working directory as branch foo
1026 1027 (branches are permanent and global, did you want a bookmark?)
1027 1028 $ mv a a.bak
1028 1029 $ echo foobranch > a
1029 1030 $ cat a.bak >> a
1030 1031 $ rm a.bak
1031 1032 $ hg commit -m 9foobranch
1032 1033 $ hg update default
1033 1034 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1034 1035 $ hg -y transplant -b foo tip
1035 1036 applying 4aa30d025d50
1036 1037 4aa30d025d50 transplanted to e00abbf63521
1037 1038
1038 1039 Expansion in changeset but not in file
1039 1040
1040 1041 $ hg tip -p
1041 1042 changeset: 11:e00abbf63521
1042 1043 tag: tip
1043 1044 parent: 9:800511b3a22d
1044 1045 user: test
1045 1046 date: Thu Jan 01 00:00:00 1970 +0000
1046 1047 summary: 9foobranch
1047 1048
1048 1049 diff -r 800511b3a22d -r e00abbf63521 a
1049 1050 --- a/a Thu Jan 01 00:00:00 1970 +0000
1050 1051 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1051 1052 @@ -1,3 +1,4 @@
1052 1053 +foobranch
1053 1054 expand $Id$
1054 1055 do not process $Id:
1055 1056 xxx $
1056 1057
1057 1058 $ head -n 2 a
1058 1059 foobranch
1059 1060 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1060 1061
1061 1062 Turn off expansion
1062 1063
1063 1064 $ hg -q rollback
1064 1065 $ hg -q update -C
1065 1066
1066 1067 kwshrink with unknown file u
1067 1068
1068 1069 $ cp a u
1069 1070 $ hg --verbose kwshrink
1070 1071 overwriting a shrinking keywords
1071 1072 overwriting m shrinking keywords
1072 1073 overwriting x/a shrinking keywords
1073 1074
1074 1075 Keywords shrunk in working directory, but not yet disabled
1075 1076 - cat shows unexpanded keywords
1076 1077 - hg cat shows expanded keywords
1077 1078
1078 1079 $ cat a b
1079 1080 expand $Id$
1080 1081 do not process $Id:
1081 1082 xxx $
1082 1083 $Xinfo$
1083 1084 ignore $Id$
1084 1085 $ hg cat sym a b && echo
1085 1086 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1086 1087 do not process $Id:
1087 1088 xxx $
1088 1089 $Xinfo: User Name <user@example.com>: firstline $
1089 1090 ignore $Id$
1090 1091 a
1091 1092
1092 1093 Now disable keyword expansion
1093 1094
1094 1095 $ rm "$HGRCPATH"
1095 1096 $ cat a b
1096 1097 expand $Id$
1097 1098 do not process $Id:
1098 1099 xxx $
1099 1100 $Xinfo$
1100 1101 ignore $Id$
1101 1102 $ hg cat sym a b && echo
1102 1103 expand $Id$
1103 1104 do not process $Id:
1104 1105 xxx $
1105 1106 $Xinfo$
1106 1107 ignore $Id$
1107 1108 a
General Comments 0
You need to be logged in to leave comments. Login now