##// END OF EJS Templates
merge: allow merging going backwards...
Matt Mackall -
r8742:a964ab62 default
parent child Browse files
Show More
@@ -1,497 +1,500 b''
1 # merge.py - directory-level update/merge handling for Mercurial
1 # merge.py - directory-level update/merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 from node import nullid, nullrev, hex, bin
8 from node import nullid, nullrev, hex, bin
9 from i18n import _
9 from i18n import _
10 import util, filemerge, copies
10 import util, filemerge, copies
11 import errno, os, shutil
11 import errno, os, shutil
12
12
13 class mergestate(object):
13 class mergestate(object):
14 '''track 3-way merge state of individual files'''
14 '''track 3-way merge state of individual files'''
15 def __init__(self, repo):
15 def __init__(self, repo):
16 self._repo = repo
16 self._repo = repo
17 self._read()
17 self._read()
18 def reset(self, node=None):
18 def reset(self, node=None):
19 self._state = {}
19 self._state = {}
20 if node:
20 if node:
21 self._local = node
21 self._local = node
22 shutil.rmtree(self._repo.join("merge"), True)
22 shutil.rmtree(self._repo.join("merge"), True)
23 def _read(self):
23 def _read(self):
24 self._state = {}
24 self._state = {}
25 try:
25 try:
26 localnode = None
26 localnode = None
27 f = self._repo.opener("merge/state")
27 f = self._repo.opener("merge/state")
28 for i, l in enumerate(f):
28 for i, l in enumerate(f):
29 if i == 0:
29 if i == 0:
30 localnode = l[:-1]
30 localnode = l[:-1]
31 else:
31 else:
32 bits = l[:-1].split("\0")
32 bits = l[:-1].split("\0")
33 self._state[bits[0]] = bits[1:]
33 self._state[bits[0]] = bits[1:]
34 self._local = bin(localnode)
34 self._local = bin(localnode)
35 except IOError, err:
35 except IOError, err:
36 if err.errno != errno.ENOENT:
36 if err.errno != errno.ENOENT:
37 raise
37 raise
38 def _write(self):
38 def _write(self):
39 f = self._repo.opener("merge/state", "w")
39 f = self._repo.opener("merge/state", "w")
40 f.write(hex(self._local) + "\n")
40 f.write(hex(self._local) + "\n")
41 for d, v in self._state.iteritems():
41 for d, v in self._state.iteritems():
42 f.write("\0".join([d] + v) + "\n")
42 f.write("\0".join([d] + v) + "\n")
43 def add(self, fcl, fco, fca, fd, flags):
43 def add(self, fcl, fco, fca, fd, flags):
44 hash = util.sha1(fcl.path()).hexdigest()
44 hash = util.sha1(fcl.path()).hexdigest()
45 self._repo.opener("merge/" + hash, "w").write(fcl.data())
45 self._repo.opener("merge/" + hash, "w").write(fcl.data())
46 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
46 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
47 hex(fca.filenode()), fco.path(), flags]
47 hex(fca.filenode()), fco.path(), flags]
48 self._write()
48 self._write()
49 def __contains__(self, dfile):
49 def __contains__(self, dfile):
50 return dfile in self._state
50 return dfile in self._state
51 def __getitem__(self, dfile):
51 def __getitem__(self, dfile):
52 return self._state[dfile][0]
52 return self._state[dfile][0]
53 def __iter__(self):
53 def __iter__(self):
54 l = self._state.keys()
54 l = self._state.keys()
55 l.sort()
55 l.sort()
56 for f in l:
56 for f in l:
57 yield f
57 yield f
58 def mark(self, dfile, state):
58 def mark(self, dfile, state):
59 self._state[dfile][0] = state
59 self._state[dfile][0] = state
60 self._write()
60 self._write()
61 def resolve(self, dfile, wctx, octx):
61 def resolve(self, dfile, wctx, octx):
62 if self[dfile] == 'r':
62 if self[dfile] == 'r':
63 return 0
63 return 0
64 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
64 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
65 f = self._repo.opener("merge/" + hash)
65 f = self._repo.opener("merge/" + hash)
66 self._repo.wwrite(dfile, f.read(), flags)
66 self._repo.wwrite(dfile, f.read(), flags)
67 fcd = wctx[dfile]
67 fcd = wctx[dfile]
68 fco = octx[ofile]
68 fco = octx[ofile]
69 fca = self._repo.filectx(afile, fileid=anode)
69 fca = self._repo.filectx(afile, fileid=anode)
70 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
70 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
71 if not r:
71 if not r:
72 self.mark(dfile, 'r')
72 self.mark(dfile, 'r')
73 return r
73 return r
74
74
75 def _checkunknown(wctx, mctx):
75 def _checkunknown(wctx, mctx):
76 "check for collisions between unknown files and files in mctx"
76 "check for collisions between unknown files and files in mctx"
77 for f in wctx.unknown():
77 for f in wctx.unknown():
78 if f in mctx and mctx[f].cmp(wctx[f].data()):
78 if f in mctx and mctx[f].cmp(wctx[f].data()):
79 raise util.Abort(_("untracked file in working directory differs"
79 raise util.Abort(_("untracked file in working directory differs"
80 " from file in requested revision: '%s'") % f)
80 " from file in requested revision: '%s'") % f)
81
81
82 def _checkcollision(mctx):
82 def _checkcollision(mctx):
83 "check for case folding collisions in the destination context"
83 "check for case folding collisions in the destination context"
84 folded = {}
84 folded = {}
85 for fn in mctx:
85 for fn in mctx:
86 fold = fn.lower()
86 fold = fn.lower()
87 if fold in folded:
87 if fold in folded:
88 raise util.Abort(_("case-folding collision between %s and %s")
88 raise util.Abort(_("case-folding collision between %s and %s")
89 % (fn, folded[fold]))
89 % (fn, folded[fold]))
90 folded[fold] = fn
90 folded[fold] = fn
91
91
92 def _forgetremoved(wctx, mctx, branchmerge):
92 def _forgetremoved(wctx, mctx, branchmerge):
93 """
93 """
94 Forget removed files
94 Forget removed files
95
95
96 If we're jumping between revisions (as opposed to merging), and if
96 If we're jumping between revisions (as opposed to merging), and if
97 neither the working directory nor the target rev has the file,
97 neither the working directory nor the target rev has the file,
98 then we need to remove it from the dirstate, to prevent the
98 then we need to remove it from the dirstate, to prevent the
99 dirstate from listing the file when it is no longer in the
99 dirstate from listing the file when it is no longer in the
100 manifest.
100 manifest.
101
101
102 If we're merging, and the other revision has removed a file
102 If we're merging, and the other revision has removed a file
103 that is not present in the working directory, we need to mark it
103 that is not present in the working directory, we need to mark it
104 as removed.
104 as removed.
105 """
105 """
106
106
107 action = []
107 action = []
108 state = branchmerge and 'r' or 'f'
108 state = branchmerge and 'r' or 'f'
109 for f in wctx.deleted():
109 for f in wctx.deleted():
110 if f not in mctx:
110 if f not in mctx:
111 action.append((f, state))
111 action.append((f, state))
112
112
113 if not branchmerge:
113 if not branchmerge:
114 for f in wctx.removed():
114 for f in wctx.removed():
115 if f not in mctx:
115 if f not in mctx:
116 action.append((f, "f"))
116 action.append((f, "f"))
117
117
118 return action
118 return action
119
119
120 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
120 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
121 """
121 """
122 Merge p1 and p2 with ancestor ma and generate merge action list
122 Merge p1 and p2 with ancestor ma and generate merge action list
123
123
124 overwrite = whether we clobber working files
124 overwrite = whether we clobber working files
125 partial = function to filter file lists
125 partial = function to filter file lists
126 """
126 """
127
127
128 repo.ui.note(_("resolving manifests\n"))
128 repo.ui.note(_("resolving manifests\n"))
129 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
129 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
130 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
130 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
131
131
132 m1 = p1.manifest()
132 m1 = p1.manifest()
133 m2 = p2.manifest()
133 m2 = p2.manifest()
134 ma = pa.manifest()
135 backwards = (pa == p2)
134 backwards = (pa == p2)
136
135
137 if backwards or overwrite:
136 if overwrite:
138 ma = m1
137 ma = m1
138 elif backwards:
139 ma = p1.p1().manifest()
140 else:
141 ma = pa.manifest()
139
142
140 action = []
143 action = []
141 copy, copied, diverge = {}, {}, {}
144 copy, copied, diverge = {}, {}, {}
142
145
143 def fmerge(f, f2, fa):
146 def fmerge(f, f2, fa):
144 """merge flags"""
147 """merge flags"""
145 a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
148 a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
146 if m == n: # flags agree
149 if m == n: # flags agree
147 return m # unchanged
150 return m # unchanged
148 if m and n and not a: # flags set, don't agree, differ from parent
151 if m and n and not a: # flags set, don't agree, differ from parent
149 r = repo.ui.prompt(
152 r = repo.ui.prompt(
150 _(" conflicting flags for %s\n"
153 _(" conflicting flags for %s\n"
151 "(n)one, e(x)ec or sym(l)ink?") % f,
154 "(n)one, e(x)ec or sym(l)ink?") % f,
152 (_("&None"), _("E&xec"), _("Sym&link")), _("n"))
155 (_("&None"), _("E&xec"), _("Sym&link")), _("n"))
153 return r != _("n") and r or ''
156 return r != _("n") and r or ''
154 if m and m != a: # changed from a to m
157 if m and m != a: # changed from a to m
155 return m
158 return m
156 if n and n != a: # changed from a to n
159 if n and n != a: # changed from a to n
157 return n
160 return n
158 return '' # flag was cleared
161 return '' # flag was cleared
159
162
160 def act(msg, m, f, *args):
163 def act(msg, m, f, *args):
161 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
164 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
162 action.append((f, m) + args)
165 action.append((f, m) + args)
163
166
164 if pa and not (backwards or overwrite):
167 if pa and not (backwards or overwrite):
165 if repo.ui.configbool("merge", "followcopies", True):
168 if repo.ui.configbool("merge", "followcopies", True):
166 dirs = repo.ui.configbool("merge", "followdirs", True)
169 dirs = repo.ui.configbool("merge", "followdirs", True)
167 copy, diverge = copies.copies(repo, p1, p2, pa, dirs)
170 copy, diverge = copies.copies(repo, p1, p2, pa, dirs)
168 copied = set(copy.values())
171 copied = set(copy.values())
169 for of, fl in diverge.iteritems():
172 for of, fl in diverge.iteritems():
170 act("divergent renames", "dr", of, fl)
173 act("divergent renames", "dr", of, fl)
171
174
172 # Compare manifests
175 # Compare manifests
173 for f, n in m1.iteritems():
176 for f, n in m1.iteritems():
174 if partial and not partial(f):
177 if partial and not partial(f):
175 continue
178 continue
176 if f in m2:
179 if f in m2:
177 rflags = fmerge(f, f, f)
180 rflags = fmerge(f, f, f)
178 # are files different?
181 # are files different?
179 if n != m2[f]:
182 if n != m2[f]:
180 a = ma.get(f, nullid)
183 a = ma.get(f, nullid)
181 # are both different from the ancestor?
184 # are both different from the ancestor?
182 if n != a and m2[f] != a:
185 if n != a and m2[f] != a:
183 act("versions differ", "m", f, f, f, rflags, False)
186 act("versions differ", "m", f, f, f, rflags, False)
184 # is remote's version newer?
187 # is remote's version newer?
185 elif m2[f] != a:
188 elif m2[f] != a:
186 # are we clobbering?
189 # are we clobbering?
187 if overwrite:
190 if overwrite:
188 act("clobbering", "g", f, rflags)
191 act("clobbering", "g", f, rflags)
189 # or are we going back in time and clean?
192 # or are we going back in time and clean?
190 elif backwards:
193 elif backwards:
191 if not n[20:] or not p2[f].cmp(p1[f].data()):
194 if not n[20:] or not p2[f].cmp(p1[f].data()):
192 act("reverting", "g", f, rflags)
195 act("reverting", "g", f, rflags)
193 else:
196 else:
194 act("remote is newer", "g", f, rflags)
197 act("remote is newer", "g", f, rflags)
195 # local is newer, not overwrite, check mode bits
198 # local is newer, not overwrite, check mode bits
196 elif m1.flags(f) != rflags:
199 elif m1.flags(f) != rflags:
197 act("update permissions", "e", f, rflags)
200 act("update permissions", "e", f, rflags)
198 # contents same, check mode bits
201 # contents same, check mode bits
199 elif m1.flags(f) != rflags:
202 elif m1.flags(f) != rflags:
200 act("update permissions", "e", f, rflags)
203 act("update permissions", "e", f, rflags)
201 elif f in copied:
204 elif f in copied:
202 continue
205 continue
203 elif f in copy:
206 elif f in copy:
204 f2 = copy[f]
207 f2 = copy[f]
205 if f2 not in m2: # directory rename
208 if f2 not in m2: # directory rename
206 act("remote renamed directory to " + f2, "d",
209 act("remote renamed directory to " + f2, "d",
207 f, None, f2, m1.flags(f))
210 f, None, f2, m1.flags(f))
208 elif f2 in m1: # case 2 A,B/B/B
211 elif f2 in m1: # case 2 A,B/B/B
209 act("local copied to " + f2, "m",
212 act("local copied to " + f2, "m",
210 f, f2, f, fmerge(f, f2, f2), False)
213 f, f2, f, fmerge(f, f2, f2), False)
211 else: # case 4,21 A/B/B
214 else: # case 4,21 A/B/B
212 act("local moved to " + f2, "m",
215 act("local moved to " + f2, "m",
213 f, f2, f, fmerge(f, f2, f2), False)
216 f, f2, f, fmerge(f, f2, f2), False)
214 elif f in ma and not n[20:]:
217 elif f in ma and not n[20:]:
215 if n != ma[f]:
218 if n != ma[f]:
216 if repo.ui.prompt(
219 if repo.ui.prompt(
217 _(" local changed %s which remote deleted\n"
220 _(" local changed %s which remote deleted\n"
218 "use (c)hanged version or (d)elete?") % f,
221 "use (c)hanged version or (d)elete?") % f,
219 (_("&Changed"), _("&Delete")), _("c")) == _("d"):
222 (_("&Changed"), _("&Delete")), _("c")) == _("d"):
220 act("prompt delete", "r", f)
223 act("prompt delete", "r", f)
221 else:
224 else:
222 act("prompt keep", "a", f)
225 act("prompt keep", "a", f)
223 else:
226 else:
224 act("other deleted", "r", f)
227 act("other deleted", "r", f)
225 elif n[20:] == "a": # only forget locally-added
228 elif n[20:] == "a": # only forget locally-added
226 act("remote deleted", "f", f)
229 act("remote deleted", "f", f)
227 else:
230 else:
228 # file is created on branch or in working directory
231 # file is created on branch or in working directory
229 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
232 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
230 act("remote deleted", "r", f)
233 act("remote deleted", "r", f)
231
234
232 for f, n in m2.iteritems():
235 for f, n in m2.iteritems():
233 if partial and not partial(f):
236 if partial and not partial(f):
234 continue
237 continue
235 if f in m1:
238 if f in m1:
236 continue
239 continue
237 if f in copied:
240 if f in copied:
238 continue
241 continue
239 if f in copy:
242 if f in copy:
240 f2 = copy[f]
243 f2 = copy[f]
241 if f2 not in m1: # directory rename
244 if f2 not in m1: # directory rename
242 act("local renamed directory to " + f2, "d",
245 act("local renamed directory to " + f2, "d",
243 None, f, f2, m2.flags(f))
246 None, f, f2, m2.flags(f))
244 elif f2 in m2: # rename case 1, A/A,B/A
247 elif f2 in m2: # rename case 1, A/A,B/A
245 act("remote copied to " + f, "m",
248 act("remote copied to " + f, "m",
246 f2, f, f, fmerge(f2, f, f2), False)
249 f2, f, f, fmerge(f2, f, f2), False)
247 else: # case 3,20 A/B/A
250 else: # case 3,20 A/B/A
248 act("remote moved to " + f, "m",
251 act("remote moved to " + f, "m",
249 f2, f, f, fmerge(f2, f, f2), True)
252 f2, f, f, fmerge(f2, f, f2), True)
250 elif f not in ma:
253 elif f not in ma:
251 act("remote created", "g", f, m2.flags(f))
254 act("remote created", "g", f, m2.flags(f))
252 elif n != ma[f]:
255 elif n != ma[f]:
253 if repo.ui.prompt(
256 if repo.ui.prompt(
254 _("remote changed %s which local deleted\n"
257 _("remote changed %s which local deleted\n"
255 "use (c)hanged version or leave (d)eleted?") % f,
258 "use (c)hanged version or leave (d)eleted?") % f,
256 (_("&Changed"), _("&Deleted")), _("c")) == _("c"):
259 (_("&Changed"), _("&Deleted")), _("c")) == _("c"):
257 act("prompt recreating", "g", f, m2.flags(f))
260 act("prompt recreating", "g", f, m2.flags(f))
258
261
259 return action
262 return action
260
263
261 def actionkey(a):
264 def actionkey(a):
262 return a[1] == 'r' and -1 or 0, a
265 return a[1] == 'r' and -1 or 0, a
263
266
264 def applyupdates(repo, action, wctx, mctx):
267 def applyupdates(repo, action, wctx, mctx):
265 "apply the merge action list to the working directory"
268 "apply the merge action list to the working directory"
266
269
267 updated, merged, removed, unresolved = 0, 0, 0, 0
270 updated, merged, removed, unresolved = 0, 0, 0, 0
268 ms = mergestate(repo)
271 ms = mergestate(repo)
269 ms.reset(wctx.parents()[0].node())
272 ms.reset(wctx.parents()[0].node())
270 moves = []
273 moves = []
271 action.sort(key=actionkey)
274 action.sort(key=actionkey)
272
275
273 # prescan for merges
276 # prescan for merges
274 for a in action:
277 for a in action:
275 f, m = a[:2]
278 f, m = a[:2]
276 if m == 'm': # merge
279 if m == 'm': # merge
277 f2, fd, flags, move = a[2:]
280 f2, fd, flags, move = a[2:]
278 repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd))
281 repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd))
279 fcl = wctx[f]
282 fcl = wctx[f]
280 fco = mctx[f2]
283 fco = mctx[f2]
281 fca = fcl.ancestor(fco) or repo.filectx(f, fileid=nullrev)
284 fca = fcl.ancestor(fco) or repo.filectx(f, fileid=nullrev)
282 ms.add(fcl, fco, fca, fd, flags)
285 ms.add(fcl, fco, fca, fd, flags)
283 if f != fd and move:
286 if f != fd and move:
284 moves.append(f)
287 moves.append(f)
285
288
286 # remove renamed files after safely stored
289 # remove renamed files after safely stored
287 for f in moves:
290 for f in moves:
288 if util.lexists(repo.wjoin(f)):
291 if util.lexists(repo.wjoin(f)):
289 repo.ui.debug(_("removing %s\n") % f)
292 repo.ui.debug(_("removing %s\n") % f)
290 os.unlink(repo.wjoin(f))
293 os.unlink(repo.wjoin(f))
291
294
292 audit_path = util.path_auditor(repo.root)
295 audit_path = util.path_auditor(repo.root)
293
296
294 for a in action:
297 for a in action:
295 f, m = a[:2]
298 f, m = a[:2]
296 if f and f[0] == "/":
299 if f and f[0] == "/":
297 continue
300 continue
298 if m == "r": # remove
301 if m == "r": # remove
299 repo.ui.note(_("removing %s\n") % f)
302 repo.ui.note(_("removing %s\n") % f)
300 audit_path(f)
303 audit_path(f)
301 try:
304 try:
302 util.unlink(repo.wjoin(f))
305 util.unlink(repo.wjoin(f))
303 except OSError, inst:
306 except OSError, inst:
304 if inst.errno != errno.ENOENT:
307 if inst.errno != errno.ENOENT:
305 repo.ui.warn(_("update failed to remove %s: %s!\n") %
308 repo.ui.warn(_("update failed to remove %s: %s!\n") %
306 (f, inst.strerror))
309 (f, inst.strerror))
307 removed += 1
310 removed += 1
308 elif m == "m": # merge
311 elif m == "m": # merge
309 f2, fd, flags, move = a[2:]
312 f2, fd, flags, move = a[2:]
310 r = ms.resolve(fd, wctx, mctx)
313 r = ms.resolve(fd, wctx, mctx)
311 if r > 0:
314 if r > 0:
312 unresolved += 1
315 unresolved += 1
313 else:
316 else:
314 if r is None:
317 if r is None:
315 updated += 1
318 updated += 1
316 else:
319 else:
317 merged += 1
320 merged += 1
318 util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
321 util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
319 if f != fd and move and util.lexists(repo.wjoin(f)):
322 if f != fd and move and util.lexists(repo.wjoin(f)):
320 repo.ui.debug(_("removing %s\n") % f)
323 repo.ui.debug(_("removing %s\n") % f)
321 os.unlink(repo.wjoin(f))
324 os.unlink(repo.wjoin(f))
322 elif m == "g": # get
325 elif m == "g": # get
323 flags = a[2]
326 flags = a[2]
324 repo.ui.note(_("getting %s\n") % f)
327 repo.ui.note(_("getting %s\n") % f)
325 t = mctx.filectx(f).data()
328 t = mctx.filectx(f).data()
326 repo.wwrite(f, t, flags)
329 repo.wwrite(f, t, flags)
327 updated += 1
330 updated += 1
328 elif m == "d": # directory rename
331 elif m == "d": # directory rename
329 f2, fd, flags = a[2:]
332 f2, fd, flags = a[2:]
330 if f:
333 if f:
331 repo.ui.note(_("moving %s to %s\n") % (f, fd))
334 repo.ui.note(_("moving %s to %s\n") % (f, fd))
332 t = wctx.filectx(f).data()
335 t = wctx.filectx(f).data()
333 repo.wwrite(fd, t, flags)
336 repo.wwrite(fd, t, flags)
334 util.unlink(repo.wjoin(f))
337 util.unlink(repo.wjoin(f))
335 if f2:
338 if f2:
336 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
339 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
337 t = mctx.filectx(f2).data()
340 t = mctx.filectx(f2).data()
338 repo.wwrite(fd, t, flags)
341 repo.wwrite(fd, t, flags)
339 updated += 1
342 updated += 1
340 elif m == "dr": # divergent renames
343 elif m == "dr": # divergent renames
341 fl = a[2]
344 fl = a[2]
342 repo.ui.warn(_("warning: detected divergent renames of %s to:\n") % f)
345 repo.ui.warn(_("warning: detected divergent renames of %s to:\n") % f)
343 for nf in fl:
346 for nf in fl:
344 repo.ui.warn(" %s\n" % nf)
347 repo.ui.warn(" %s\n" % nf)
345 elif m == "e": # exec
348 elif m == "e": # exec
346 flags = a[2]
349 flags = a[2]
347 util.set_flags(repo.wjoin(f), 'l' in flags, 'x' in flags)
350 util.set_flags(repo.wjoin(f), 'l' in flags, 'x' in flags)
348
351
349 return updated, merged, removed, unresolved
352 return updated, merged, removed, unresolved
350
353
351 def recordupdates(repo, action, branchmerge):
354 def recordupdates(repo, action, branchmerge):
352 "record merge actions to the dirstate"
355 "record merge actions to the dirstate"
353
356
354 for a in action:
357 for a in action:
355 f, m = a[:2]
358 f, m = a[:2]
356 if m == "r": # remove
359 if m == "r": # remove
357 if branchmerge:
360 if branchmerge:
358 repo.dirstate.remove(f)
361 repo.dirstate.remove(f)
359 else:
362 else:
360 repo.dirstate.forget(f)
363 repo.dirstate.forget(f)
361 elif m == "a": # re-add
364 elif m == "a": # re-add
362 if not branchmerge:
365 if not branchmerge:
363 repo.dirstate.add(f)
366 repo.dirstate.add(f)
364 elif m == "f": # forget
367 elif m == "f": # forget
365 repo.dirstate.forget(f)
368 repo.dirstate.forget(f)
366 elif m == "e": # exec change
369 elif m == "e": # exec change
367 repo.dirstate.normallookup(f)
370 repo.dirstate.normallookup(f)
368 elif m == "g": # get
371 elif m == "g": # get
369 if branchmerge:
372 if branchmerge:
370 repo.dirstate.normaldirty(f)
373 repo.dirstate.normaldirty(f)
371 else:
374 else:
372 repo.dirstate.normal(f)
375 repo.dirstate.normal(f)
373 elif m == "m": # merge
376 elif m == "m": # merge
374 f2, fd, flag, move = a[2:]
377 f2, fd, flag, move = a[2:]
375 if branchmerge:
378 if branchmerge:
376 # We've done a branch merge, mark this file as merged
379 # We've done a branch merge, mark this file as merged
377 # so that we properly record the merger later
380 # so that we properly record the merger later
378 repo.dirstate.merge(fd)
381 repo.dirstate.merge(fd)
379 if f != f2: # copy/rename
382 if f != f2: # copy/rename
380 if move:
383 if move:
381 repo.dirstate.remove(f)
384 repo.dirstate.remove(f)
382 if f != fd:
385 if f != fd:
383 repo.dirstate.copy(f, fd)
386 repo.dirstate.copy(f, fd)
384 else:
387 else:
385 repo.dirstate.copy(f2, fd)
388 repo.dirstate.copy(f2, fd)
386 else:
389 else:
387 # We've update-merged a locally modified file, so
390 # We've update-merged a locally modified file, so
388 # we set the dirstate to emulate a normal checkout
391 # we set the dirstate to emulate a normal checkout
389 # of that file some time in the past. Thus our
392 # of that file some time in the past. Thus our
390 # merge will appear as a normal local file
393 # merge will appear as a normal local file
391 # modification.
394 # modification.
392 repo.dirstate.normallookup(fd)
395 repo.dirstate.normallookup(fd)
393 if move:
396 if move:
394 repo.dirstate.forget(f)
397 repo.dirstate.forget(f)
395 elif m == "d": # directory rename
398 elif m == "d": # directory rename
396 f2, fd, flag = a[2:]
399 f2, fd, flag = a[2:]
397 if not f2 and f not in repo.dirstate:
400 if not f2 and f not in repo.dirstate:
398 # untracked file moved
401 # untracked file moved
399 continue
402 continue
400 if branchmerge:
403 if branchmerge:
401 repo.dirstate.add(fd)
404 repo.dirstate.add(fd)
402 if f:
405 if f:
403 repo.dirstate.remove(f)
406 repo.dirstate.remove(f)
404 repo.dirstate.copy(f, fd)
407 repo.dirstate.copy(f, fd)
405 if f2:
408 if f2:
406 repo.dirstate.copy(f2, fd)
409 repo.dirstate.copy(f2, fd)
407 else:
410 else:
408 repo.dirstate.normal(fd)
411 repo.dirstate.normal(fd)
409 if f:
412 if f:
410 repo.dirstate.forget(f)
413 repo.dirstate.forget(f)
411
414
412 def update(repo, node, branchmerge, force, partial):
415 def update(repo, node, branchmerge, force, partial):
413 """
416 """
414 Perform a merge between the working directory and the given node
417 Perform a merge between the working directory and the given node
415
418
416 branchmerge = whether to merge between branches
419 branchmerge = whether to merge between branches
417 force = whether to force branch merging or file overwriting
420 force = whether to force branch merging or file overwriting
418 partial = a function to filter file lists (dirstate not updated)
421 partial = a function to filter file lists (dirstate not updated)
419 """
422 """
420
423
421 wlock = repo.wlock()
424 wlock = repo.wlock()
422 try:
425 try:
423 wc = repo[None]
426 wc = repo[None]
424 if node is None:
427 if node is None:
425 # tip of current branch
428 # tip of current branch
426 try:
429 try:
427 node = repo.branchtags()[wc.branch()]
430 node = repo.branchtags()[wc.branch()]
428 except KeyError:
431 except KeyError:
429 if wc.branch() == "default": # no default branch!
432 if wc.branch() == "default": # no default branch!
430 node = repo.lookup("tip") # update to tip
433 node = repo.lookup("tip") # update to tip
431 else:
434 else:
432 raise util.Abort(_("branch %s not found") % wc.branch())
435 raise util.Abort(_("branch %s not found") % wc.branch())
433 overwrite = force and not branchmerge
436 overwrite = force and not branchmerge
434 pl = wc.parents()
437 pl = wc.parents()
435 p1, p2 = pl[0], repo[node]
438 p1, p2 = pl[0], repo[node]
436 pa = p1.ancestor(p2)
439 pa = p1.ancestor(p2)
437 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
440 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
438 fastforward = False
441 fastforward = False
439
442
440 ### check phase
443 ### check phase
441 if not overwrite and len(pl) > 1:
444 if not overwrite and len(pl) > 1:
442 raise util.Abort(_("outstanding uncommitted merges"))
445 raise util.Abort(_("outstanding uncommitted merges"))
443 if branchmerge:
446 if branchmerge:
444 if pa == p2:
447 if pa == p2:
445 raise util.Abort(_("can't merge with ancestor"))
448 raise util.Abort(_("can't merge with ancestor"))
446 elif pa == p1:
449 elif pa == p1:
447 if p1.branch() != p2.branch():
450 if p1.branch() != p2.branch():
448 fastforward = True
451 fastforward = True
449 else:
452 else:
450 raise util.Abort(_("nothing to merge (use 'hg update'"
453 raise util.Abort(_("nothing to merge (use 'hg update'"
451 " or check 'hg heads')"))
454 " or check 'hg heads')"))
452 if not force and (wc.files() or wc.deleted()):
455 if not force and (wc.files() or wc.deleted()):
453 raise util.Abort(_("outstanding uncommitted changes "
456 raise util.Abort(_("outstanding uncommitted changes "
454 "(use 'hg status' to list changes)"))
457 "(use 'hg status' to list changes)"))
455 elif not overwrite:
458 elif not overwrite:
456 if pa == p1 or pa == p2: # linear
459 if pa == p1 or pa == p2: # linear
457 pass # all good
460 pass # all good
458 elif p1.branch() == p2.branch():
461 elif p1.branch() == p2.branch():
459 if wc.files() or wc.deleted():
462 if wc.files() or wc.deleted():
460 raise util.Abort(_("crosses branches (use 'hg merge' or "
463 raise util.Abort(_("crosses branches (use 'hg merge' or "
461 "'hg update -C' to discard changes)"))
464 "'hg update -C' to discard changes)"))
462 raise util.Abort(_("crosses branches (use 'hg merge' "
465 raise util.Abort(_("crosses branches (use 'hg merge' "
463 "or 'hg update -C')"))
466 "or 'hg update -C')"))
464 elif wc.files() or wc.deleted():
467 elif wc.files() or wc.deleted():
465 raise util.Abort(_("crosses named branches (use "
468 raise util.Abort(_("crosses named branches (use "
466 "'hg update -C' to discard changes)"))
469 "'hg update -C' to discard changes)"))
467 else:
470 else:
468 # Allow jumping branches if there are no changes
471 # Allow jumping branches if there are no changes
469 overwrite = True
472 overwrite = True
470
473
471 ### calculate phase
474 ### calculate phase
472 action = []
475 action = []
473 if not force:
476 if not force:
474 _checkunknown(wc, p2)
477 _checkunknown(wc, p2)
475 if not util.checkcase(repo.path):
478 if not util.checkcase(repo.path):
476 _checkcollision(p2)
479 _checkcollision(p2)
477 action += _forgetremoved(wc, p2, branchmerge)
480 action += _forgetremoved(wc, p2, branchmerge)
478 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
481 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
479
482
480 ### apply phase
483 ### apply phase
481 if not branchmerge: # just jump to the new rev
484 if not branchmerge: # just jump to the new rev
482 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
485 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
483 if not partial:
486 if not partial:
484 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
487 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
485
488
486 stats = applyupdates(repo, action, wc, p2)
489 stats = applyupdates(repo, action, wc, p2)
487
490
488 if not partial:
491 if not partial:
489 recordupdates(repo, action, branchmerge)
492 recordupdates(repo, action, branchmerge)
490 repo.dirstate.setparents(fp1, fp2)
493 repo.dirstate.setparents(fp1, fp2)
491 if not branchmerge and not fastforward:
494 if not branchmerge and not fastforward:
492 repo.dirstate.setbranch(p2.branch())
495 repo.dirstate.setbranch(p2.branch())
493 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
496 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
494
497
495 return stats
498 return stats
496 finally:
499 finally:
497 wlock.release()
500 wlock.release()
@@ -1,60 +1,60 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 hg init
3 hg init
4
4
5 cat > .hg/hgrc <<EOF
5 cat > .hg/hgrc <<EOF
6 [extensions]
6 [extensions]
7 prefixfilter = prefix.py
7 prefixfilter = prefix.py
8 [encode]
8 [encode]
9 *.txt = stripprefix: Copyright 2046, The Masters
9 *.txt = stripprefix: Copyright 2046, The Masters
10 [decode]
10 [decode]
11 *.txt = insertprefix: Copyright 2046, The Masters
11 *.txt = insertprefix: Copyright 2046, The Masters
12 EOF
12 EOF
13
13
14 cat > prefix.py <<EOF
14 cat > prefix.py <<EOF
15 from mercurial import util
15 from mercurial import util
16 def stripprefix(s, cmd, filename, **kwargs):
16 def stripprefix(s, cmd, filename, **kwargs):
17 header = '%s\n' % cmd
17 header = '%s\n' % cmd
18 if s[:len(header)] != header:
18 if s[:len(header)] != header:
19 raise util.Abort('missing header "%s" in %s' % (cmd, filename))
19 raise util.Abort('missing header "%s" in %s' % (cmd, filename))
20 return s[len(header):]
20 return s[len(header):]
21 def insertprefix(s, cmd):
21 def insertprefix(s, cmd):
22 return '%s\n%s' % (cmd, s)
22 return '%s\n%s' % (cmd, s)
23 def reposetup(ui, repo):
23 def reposetup(ui, repo):
24 repo.adddatafilter('stripprefix:', stripprefix)
24 repo.adddatafilter('stripprefix:', stripprefix)
25 repo.adddatafilter('insertprefix:', insertprefix)
25 repo.adddatafilter('insertprefix:', insertprefix)
26 EOF
26 EOF
27
27
28 cat > .hgignore <<EOF
28 cat > .hgignore <<EOF
29 .hgignore
29 .hgignore
30 prefix.py
30 prefix.py
31 prefix.pyc
31 prefix.pyc
32 EOF
32 EOF
33
33
34 cat > stuff.txt <<EOF
34 cat > stuff.txt <<EOF
35 Copyright 2046, The Masters
35 Copyright 2046, The Masters
36 Some stuff to ponder very carefully.
36 Some stuff to ponder very carefully.
37 EOF
37 EOF
38 hg add stuff.txt
38 hg add stuff.txt
39 hg ci -m stuff
39 hg ci -m stuff
40
40
41 echo '% Repository data:'
41 echo '% Repository data:'
42 hg cat stuff.txt
42 hg cat stuff.txt
43
43
44 echo '% Fresh checkout:'
44 echo '% Fresh checkout:'
45 rm stuff.txt
45 rm stuff.txt
46 hg up
46 hg up -C
47 cat stuff.txt
47 cat stuff.txt
48 echo >> stuff.txt <<EOF
48 echo >> stuff.txt <<EOF
49 Very very carefully.
49 Very very carefully.
50 EOF
50 EOF
51 hg stat
51 hg stat
52
52
53 cat > morestuff.txt <<EOF
53 cat > morestuff.txt <<EOF
54 Unauthorized material subject to destruction.
54 Unauthorized material subject to destruction.
55 EOF
55 EOF
56
56
57 echo '% Problem encoding:'
57 echo '% Problem encoding:'
58 hg add morestuff.txt
58 hg add morestuff.txt
59 hg ci -m morestuff
59 hg ci -m morestuff
60 hg stat
60 hg stat
@@ -1,42 +1,42 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 hg init
3 hg init
4
4
5 cat > .hg/hgrc <<EOF
5 cat > .hg/hgrc <<EOF
6 [encode]
6 [encode]
7 *.gz = gzip -d
7 *.gz = gzip -d
8
8
9 [decode]
9 [decode]
10 *.gz = gzip
10 *.gz = gzip
11
11
12 EOF
12 EOF
13
13
14 echo "this is a test" | gzip > a.gz
14 echo "this is a test" | gzip > a.gz
15 hg add a.gz
15 hg add a.gz
16 hg ci -m "test" -d "1000000 0"
16 hg ci -m "test" -d "1000000 0"
17 echo %% no changes
17 echo %% no changes
18 hg status
18 hg status
19 touch a.gz
19 touch a.gz
20
20
21 echo %% no changes
21 echo %% no changes
22 hg status
22 hg status
23
23
24 echo %% uncompressed contents in repo
24 echo %% uncompressed contents in repo
25 hg debugdata .hg/store/data/a.gz.d 0
25 hg debugdata .hg/store/data/a.gz.d 0
26
26
27 echo %% uncompress our working dir copy
27 echo %% uncompress our working dir copy
28 gunzip < a.gz
28 gunzip < a.gz
29
29
30 rm a.gz
30 rm a.gz
31 hg co
31 hg co -C
32
32
33 echo %% uncompress our new working dir copy
33 echo %% uncompress our new working dir copy
34 gunzip < a.gz
34 gunzip < a.gz
35
35
36 echo %% check hg cat operation
36 echo %% check hg cat operation
37 hg cat a.gz
37 hg cat a.gz
38 hg cat --decode a.gz | gunzip
38 hg cat --decode a.gz | gunzip
39 mkdir subdir
39 mkdir subdir
40 cd subdir
40 cd subdir
41 hg -R .. cat ../a.gz
41 hg -R .. cat ../a.gz
42 hg -R .. cat --decode ../a.gz | gunzip
42 hg -R .. cat --decode ../a.gz | gunzip
@@ -1,8 +1,8 b''
1 adding a
1 adding a
2 79abf14474dc tip
2 79abf14474dc tip
3 % make sure we notice the change of mode if the cached size == -1
3 % make sure we notice the change of mode if the cached size == -1
4 n 0 -1 unset a
4 n 0 -1 unset a
5 M a
5 M a
6 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
6 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
7 d69afc33ff8a
7 d69afc33ff8a
8 not executable -- whew
8 not executable -- whew
@@ -1,343 +1,343 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 cat <<EOF >> $HGRCPATH
3 cat <<EOF >> $HGRCPATH
4 [extensions]
4 [extensions]
5 hgext.keyword =
5 hgext.keyword =
6 hgext.mq =
6 hgext.mq =
7 hgext.notify =
7 hgext.notify =
8 [keyword]
8 [keyword]
9 * =
9 * =
10 b = ignore
10 b = ignore
11 [hooks]
11 [hooks]
12 commit=
12 commit=
13 commit.test=cp a hooktest
13 commit.test=cp a hooktest
14 EOF
14 EOF
15
15
16 echo % help
16 echo % help
17 hg help keyword
17 hg help keyword
18
18
19 echo % hg kwdemo
19 echo % hg kwdemo
20 hg --quiet kwdemo --default \
20 hg --quiet kwdemo --default \
21 | sed -e 's![^ ][^ ]*demo.txt,v!/TMP/demo.txt,v!' \
21 | sed -e 's![^ ][^ ]*demo.txt,v!/TMP/demo.txt,v!' \
22 -e 's/,v [a-z0-9][a-z0-9]* /,v xxxxxxxxxxxx /' \
22 -e 's/,v [a-z0-9][a-z0-9]* /,v xxxxxxxxxxxx /' \
23 -e '/[$]Revision/ s/: [a-z0-9][a-z0-9]* /: xxxxxxxxxxxx /' \
23 -e '/[$]Revision/ s/: [a-z0-9][a-z0-9]* /: xxxxxxxxxxxx /' \
24 -e 's! 20[0-9][0-9]/[01][0-9]/[0-3][0-9] [0-2][0-9]:[0-6][0-9]:[0-6][0-9]! 2000/00/00 00:00:00!'
24 -e 's! 20[0-9][0-9]/[01][0-9]/[0-3][0-9] [0-2][0-9]:[0-6][0-9]:[0-6][0-9]! 2000/00/00 00:00:00!'
25
25
26 hg --quiet kwdemo "Branch = {branches}"
26 hg --quiet kwdemo "Branch = {branches}"
27
27
28 hg init Test-bndl
28 hg init Test-bndl
29 cd Test-bndl
29 cd Test-bndl
30
30
31 echo % kwshrink should exit silently in empty/invalid repo
31 echo % kwshrink should exit silently in empty/invalid repo
32 hg kwshrink
32 hg kwshrink
33
33
34 # Symlinks cannot be created on Windows. The bundle was made with:
34 # Symlinks cannot be created on Windows. The bundle was made with:
35 #
35 #
36 # hg init t
36 # hg init t
37 # cd t
37 # cd t
38 # echo a > a
38 # echo a > a
39 # ln -s a sym
39 # ln -s a sym
40 # hg add sym
40 # hg add sym
41 # hg ci -m addsym -u mercurial
41 # hg ci -m addsym -u mercurial
42 # hg bundle --base null ../test-keyword.hg
42 # hg bundle --base null ../test-keyword.hg
43 #
43 #
44 hg pull -u "$TESTDIR/test-keyword.hg" \
44 hg pull -u "$TESTDIR/test-keyword.hg" \
45 | sed 's/pulling from.*test-keyword.hg/pulling from test-keyword.hg/'
45 | sed 's/pulling from.*test-keyword.hg/pulling from test-keyword.hg/'
46
46
47 echo 'expand $Id$' > a
47 echo 'expand $Id$' > a
48 echo 'do not process $Id:' >> a
48 echo 'do not process $Id:' >> a
49 echo 'xxx $' >> a
49 echo 'xxx $' >> a
50 echo 'ignore $Id$' > b
50 echo 'ignore $Id$' > b
51 echo % cat
51 echo % cat
52 cat a b
52 cat a b
53
53
54 echo % addremove
54 echo % addremove
55 hg addremove
55 hg addremove
56 echo % status
56 echo % status
57 hg status
57 hg status
58
58
59 echo % default keyword expansion including commit hook
59 echo % default keyword expansion including commit hook
60 echo % interrupted commit should not change state or run commit hook
60 echo % interrupted commit should not change state or run commit hook
61 hg --debug commit
61 hg --debug commit
62 echo % status
62 echo % status
63 hg status
63 hg status
64
64
65 echo % commit
65 echo % commit
66 hg --debug commit -mabsym -u 'User Name <user@example.com>'
66 hg --debug commit -mabsym -u 'User Name <user@example.com>'
67 echo % status
67 echo % status
68 hg status
68 hg status
69 echo % identify
69 echo % identify
70 hg debugrebuildstate
70 hg debugrebuildstate
71 hg --quiet identify
71 hg --quiet identify
72 echo % cat
72 echo % cat
73 cat a b
73 cat a b
74 echo % hg cat
74 echo % hg cat
75 hg cat sym a b
75 hg cat sym a b
76
76
77 echo
77 echo
78 echo % diff a hooktest
78 echo % diff a hooktest
79 diff a hooktest
79 diff a hooktest
80
80
81 echo % removing commit hook from config
81 echo % removing commit hook from config
82 sed -e '/\[hooks\]/,$ d' $HGRCPATH > $HGRCPATH.nohook
82 sed -e '/\[hooks\]/,$ d' $HGRCPATH > $HGRCPATH.nohook
83 mv $HGRCPATH.nohook $HGRCPATH
83 mv $HGRCPATH.nohook $HGRCPATH
84 rm hooktest
84 rm hooktest
85
85
86 echo % bundle
86 echo % bundle
87 hg bundle --base null ../kw.hg
87 hg bundle --base null ../kw.hg
88
88
89 cd ..
89 cd ..
90 hg init Test
90 hg init Test
91 cd Test
91 cd Test
92
92
93 echo % notify on pull to check whether keywords stay as is in email
93 echo % notify on pull to check whether keywords stay as is in email
94 echo % ie. if patch.diff wrapper acts as it should
94 echo % ie. if patch.diff wrapper acts as it should
95
95
96 cat <<EOF >> $HGRCPATH
96 cat <<EOF >> $HGRCPATH
97 [hooks]
97 [hooks]
98 incoming.notify = python:hgext.notify.hook
98 incoming.notify = python:hgext.notify.hook
99 [notify]
99 [notify]
100 sources = pull
100 sources = pull
101 diffstat = False
101 diffstat = False
102 [reposubs]
102 [reposubs]
103 * = Test
103 * = Test
104 EOF
104 EOF
105
105
106 echo % pull from bundle
106 echo % pull from bundle
107 hg pull -u ../kw.hg 2>&1 | sed -e '/^Content-Type:/,/^diffs (/ d'
107 hg pull -u ../kw.hg 2>&1 | sed -e '/^Content-Type:/,/^diffs (/ d'
108
108
109 echo % remove notify config
109 echo % remove notify config
110 sed -e '/\[hooks\]/,$ d' $HGRCPATH > $HGRCPATH.nonotify
110 sed -e '/\[hooks\]/,$ d' $HGRCPATH > $HGRCPATH.nonotify
111 mv $HGRCPATH.nonotify $HGRCPATH
111 mv $HGRCPATH.nonotify $HGRCPATH
112
112
113 echo % touch
113 echo % touch
114 touch a b
114 touch a b
115 echo % status
115 echo % status
116 hg status
116 hg status
117
117
118 rm sym a b
118 rm sym a b
119 echo % update
119 echo % update
120 hg update
120 hg update -C
121 echo % cat
121 echo % cat
122 cat a b
122 cat a b
123
123
124 echo % check whether expansion is filewise
124 echo % check whether expansion is filewise
125 echo '$Id$' > c
125 echo '$Id$' > c
126 echo 'tests for different changenodes' >> c
126 echo 'tests for different changenodes' >> c
127 echo % commit c
127 echo % commit c
128 hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
128 hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
129 echo % force expansion
129 echo % force expansion
130 hg -v kwexpand
130 hg -v kwexpand
131 echo % compare changenodes in a c
131 echo % compare changenodes in a c
132 cat a c
132 cat a c
133
133
134 echo % qinit -c
134 echo % qinit -c
135 hg qinit -c
135 hg qinit -c
136 echo % qimport
136 echo % qimport
137 hg qimport -r tip -n mqtest.diff
137 hg qimport -r tip -n mqtest.diff
138 echo % qcommit
138 echo % qcommit
139 hg qcommit -mqtest
139 hg qcommit -mqtest
140 echo % keywords should not be expanded in patch
140 echo % keywords should not be expanded in patch
141 cat .hg/patches/mqtest.diff
141 cat .hg/patches/mqtest.diff
142 echo % qpop
142 echo % qpop
143 hg qpop
143 hg qpop
144 echo % qgoto - should imply qpush
144 echo % qgoto - should imply qpush
145 hg qgoto mqtest.diff
145 hg qgoto mqtest.diff
146 echo % cat
146 echo % cat
147 cat c
147 cat c
148 echo % qpop and move on
148 echo % qpop and move on
149 hg qpop
149 hg qpop
150
150
151 echo % copy
151 echo % copy
152 hg cp a c
152 hg cp a c
153
153
154 echo % kwfiles added
154 echo % kwfiles added
155 hg kwfiles
155 hg kwfiles
156
156
157 echo % commit
157 echo % commit
158 hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
158 hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
159 echo % cat a c
159 echo % cat a c
160 cat a c
160 cat a c
161 echo % touch copied c
161 echo % touch copied c
162 touch c
162 touch c
163 echo % status
163 echo % status
164 hg status
164 hg status
165
165
166 echo % kwfiles
166 echo % kwfiles
167 hg kwfiles
167 hg kwfiles
168
168
169 echo % diff --rev
169 echo % diff --rev
170 hg diff --rev 1 | grep -v 'b/c'
170 hg diff --rev 1 | grep -v 'b/c'
171
171
172 echo % rollback
172 echo % rollback
173 hg rollback
173 hg rollback
174 echo % status
174 echo % status
175 hg status
175 hg status
176 echo % update -C
176 echo % update -C
177 hg update --clean
177 hg update --clean
178
178
179 echo % custom keyword expansion
179 echo % custom keyword expansion
180 echo % try with kwdemo
180 echo % try with kwdemo
181 hg --quiet kwdemo "Xinfo = {author}: {desc}"
181 hg --quiet kwdemo "Xinfo = {author}: {desc}"
182
182
183 cat <<EOF >>$HGRCPATH
183 cat <<EOF >>$HGRCPATH
184 [keywordmaps]
184 [keywordmaps]
185 Id = {file} {node|short} {date|rfc822date} {author|user}
185 Id = {file} {node|short} {date|rfc822date} {author|user}
186 Xinfo = {author}: {desc}
186 Xinfo = {author}: {desc}
187 EOF
187 EOF
188
188
189 echo % cat
189 echo % cat
190 cat a b
190 cat a b
191 echo % hg cat
191 echo % hg cat
192 hg cat sym a b
192 hg cat sym a b
193
193
194 echo
194 echo
195 echo '$Xinfo$' >> a
195 echo '$Xinfo$' >> a
196 cat <<EOF >> log
196 cat <<EOF >> log
197 firstline
197 firstline
198 secondline
198 secondline
199 EOF
199 EOF
200
200
201 echo % interrupted commit should not change state
201 echo % interrupted commit should not change state
202 hg commit
202 hg commit
203 echo % status
203 echo % status
204 hg status
204 hg status
205
205
206 echo % commit
206 echo % commit
207 hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
207 hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
208 rm log
208 rm log
209 echo % status
209 echo % status
210 hg status
210 hg status
211 echo % verify
211 echo % verify
212 hg verify
212 hg verify
213
213
214 echo % cat
214 echo % cat
215 cat a b
215 cat a b
216 echo % hg cat
216 echo % hg cat
217 hg cat sym a b
217 hg cat sym a b
218 echo
218 echo
219 echo % annotate
219 echo % annotate
220 hg annotate a
220 hg annotate a
221
221
222 echo % remove
222 echo % remove
223 hg debugrebuildstate
223 hg debugrebuildstate
224 hg remove a
224 hg remove a
225 hg --debug commit -m rma
225 hg --debug commit -m rma
226 echo % status
226 echo % status
227 hg status
227 hg status
228 echo % rollback
228 echo % rollback
229 hg rollback
229 hg rollback
230 echo % status
230 echo % status
231 hg status
231 hg status
232 echo % revert a
232 echo % revert a
233 hg revert --no-backup --rev tip a
233 hg revert --no-backup --rev tip a
234 echo % cat a
234 echo % cat a
235 cat a
235 cat a
236
236
237 echo % clone to test incoming
237 echo % clone to test incoming
238 cd ..
238 cd ..
239 hg clone -r1 Test Test-a
239 hg clone -r1 Test Test-a
240 cd Test-a
240 cd Test-a
241 cat <<EOF >> .hg/hgrc
241 cat <<EOF >> .hg/hgrc
242 [paths]
242 [paths]
243 default = ../Test
243 default = ../Test
244 EOF
244 EOF
245 echo % incoming
245 echo % incoming
246 # remove path to temp dir
246 # remove path to temp dir
247 hg incoming | sed -e 's/^\(comparing with \).*\(test-keyword.*\)/\1\2/'
247 hg incoming | sed -e 's/^\(comparing with \).*\(test-keyword.*\)/\1\2/'
248
248
249 sed -e 's/Id.*/& rejecttest/' a > a.new
249 sed -e 's/Id.*/& rejecttest/' a > a.new
250 mv a.new a
250 mv a.new a
251 echo % commit rejecttest
251 echo % commit rejecttest
252 hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
252 hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
253 echo % export
253 echo % export
254 hg export -o ../rejecttest.diff tip
254 hg export -o ../rejecttest.diff tip
255
255
256 cd ../Test
256 cd ../Test
257 echo % import
257 echo % import
258 hg import ../rejecttest.diff
258 hg import ../rejecttest.diff
259 echo % cat
259 echo % cat
260 cat a b
260 cat a b
261 echo
261 echo
262 echo % rollback
262 echo % rollback
263 hg rollback
263 hg rollback
264 echo % clean update
264 echo % clean update
265 hg update --clean
265 hg update --clean
266
266
267 echo % kwexpand/kwshrink on selected files
267 echo % kwexpand/kwshrink on selected files
268 mkdir x
268 mkdir x
269 echo % copy a x/a
269 echo % copy a x/a
270 hg copy a x/a
270 hg copy a x/a
271 echo % kwexpand a
271 echo % kwexpand a
272 hg --verbose kwexpand a
272 hg --verbose kwexpand a
273 echo % kwexpand x/a should abort
273 echo % kwexpand x/a should abort
274 hg --verbose kwexpand x/a
274 hg --verbose kwexpand x/a
275 cd x
275 cd x
276 hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
276 hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
277 echo % cat a
277 echo % cat a
278 cat a
278 cat a
279 echo % kwshrink a inside directory x
279 echo % kwshrink a inside directory x
280 hg --verbose kwshrink a
280 hg --verbose kwshrink a
281 echo % cat a
281 echo % cat a
282 cat a
282 cat a
283 cd ..
283 cd ..
284
284
285 echo % kwexpand nonexistent
285 echo % kwexpand nonexistent
286 hg kwexpand nonexistent 2>&1 | sed 's/nonexistent:.*/nonexistent:/'
286 hg kwexpand nonexistent 2>&1 | sed 's/nonexistent:.*/nonexistent:/'
287
287
288 echo % hg serve
288 echo % hg serve
289 hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
289 hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
290 cat hg.pid >> $DAEMON_PIDS
290 cat hg.pid >> $DAEMON_PIDS
291 echo % expansion
291 echo % expansion
292 echo % hgweb file
292 echo % hgweb file
293 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/a/?style=raw')
293 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/a/?style=raw')
294 echo % no expansion
294 echo % no expansion
295 echo % hgweb annotate
295 echo % hgweb annotate
296 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/annotate/tip/a/?style=raw')
296 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/annotate/tip/a/?style=raw')
297 echo % hgweb changeset
297 echo % hgweb changeset
298 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/tip/?style=raw')
298 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rev/tip/?style=raw')
299 echo % hgweb filediff
299 echo % hgweb filediff
300 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/bb948857c743/a?style=raw')
300 ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/bb948857c743/a?style=raw')
301 echo % errors encountered
301 echo % errors encountered
302 cat errors.log
302 cat errors.log
303
303
304 echo % merge/resolve
304 echo % merge/resolve
305 echo '$Id$' > m
305 echo '$Id$' > m
306 hg add m
306 hg add m
307 hg commit -m 4kw
307 hg commit -m 4kw
308 echo foo >> m
308 echo foo >> m
309 hg commit -m 5foo
309 hg commit -m 5foo
310 echo % simplemerge
310 echo % simplemerge
311 hg update 4
311 hg update 4
312 echo foo >> m
312 echo foo >> m
313 hg commit -m 6foo
313 hg commit -m 6foo
314 hg merge
314 hg merge
315 hg commit -m simplemerge
315 hg commit -m simplemerge
316 cat m
316 cat m
317 echo % conflict
317 echo % conflict
318 hg update 4
318 hg update 4
319 echo bar >> m
319 echo bar >> m
320 hg commit -m 8bar
320 hg commit -m 8bar
321 hg merge
321 hg merge
322 echo % keyword stays outside conflict zone
322 echo % keyword stays outside conflict zone
323 cat m
323 cat m
324 echo % resolve to local
324 echo % resolve to local
325 HGMERGE=internal:local hg resolve -a
325 HGMERGE=internal:local hg resolve -a
326 hg commit -m localresolve
326 hg commit -m localresolve
327 cat m
327 cat m
328
328
329 echo % switch off expansion
329 echo % switch off expansion
330 echo % kwshrink with unknown file u
330 echo % kwshrink with unknown file u
331 cp a u
331 cp a u
332 hg --verbose kwshrink
332 hg --verbose kwshrink
333 echo % cat
333 echo % cat
334 cat a b
334 cat a b
335 echo % hg cat
335 echo % hg cat
336 hg cat sym a b
336 hg cat sym a b
337 echo
337 echo
338 rm $HGRCPATH
338 rm $HGRCPATH
339 echo % cat
339 echo % cat
340 cat a b
340 cat a b
341 echo % hg cat
341 echo % hg cat
342 hg cat sym a b
342 hg cat sym a b
343 echo
343 echo
@@ -1,63 +1,65 b''
1 # revision 0
1 # revision 0
2 adding copy
2 adding copy
3 adding move
3 adding move
4 adding remove
4 adding remove
5 adding unchanged
5 adding unchanged
6 adding zzz1_merge_ok
6 adding zzz1_merge_ok
7 adding zzz2_merge_bad
7 adding zzz2_merge_bad
8 # revision 1
8 # revision 1
9 # local changes to revision 0
9 # local changes to revision 0
10 4 files updated, 0 files merged, 3 files removed, 0 files unresolved
10 4 files updated, 0 files merged, 3 files removed, 0 files unresolved
11 --- a/zzz1_merge_ok
11 --- a/zzz1_merge_ok
12 +++ b/zzz1_merge_ok
12 +++ b/zzz1_merge_ok
13 +new last line
13 +new last line
14 --- a/zzz2_merge_bad
14 --- a/zzz2_merge_bad
15 +++ b/zzz2_merge_bad
15 +++ b/zzz2_merge_bad
16 +another last line
16 +another last line
17 M zzz1_merge_ok
17 M zzz1_merge_ok
18 M zzz2_merge_bad
18 M zzz2_merge_bad
19 # local merge with bad merge tool
19 # local merge with bad merge tool
20 merging zzz1_merge_ok
20 merging zzz1_merge_ok
21 merging zzz2_merge_bad
21 merging zzz2_merge_bad
22 merging zzz2_merge_bad failed!
22 merging zzz2_merge_bad failed!
23 3 files updated, 1 files merged, 2 files removed, 1 files unresolved
23 3 files updated, 1 files merged, 2 files removed, 1 files unresolved
24 use 'hg resolve' to retry unresolved file merges
24 use 'hg resolve' to retry unresolved file merges
25 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
25 merging zzz1_merge_ok
26 merging zzz2_merge_bad
27 2 files updated, 2 files merged, 3 files removed, 0 files unresolved
26 --- a/zzz1_merge_ok
28 --- a/zzz1_merge_ok
27 +++ b/zzz1_merge_ok
29 +++ b/zzz1_merge_ok
28 +new first line
30 +new first line
29 +new last line
31 +new last line
30 --- a/zzz2_merge_bad
32 --- a/zzz2_merge_bad
31 +++ b/zzz2_merge_bad
33 +++ b/zzz2_merge_bad
32 +another last line
34 +another last line
33 M zzz1_merge_ok
35 M zzz1_merge_ok
34 M zzz2_merge_bad
36 M zzz2_merge_bad
35 ? zzz2_merge_bad.orig
36 # local merge with conflicts
37 # local merge with conflicts
37 merging zzz1_merge_ok
38 merging zzz1_merge_ok
38 merging zzz2_merge_bad
39 merging zzz2_merge_bad
39 warning: conflicts during merge.
40 warning: conflicts during merge.
40 merging zzz2_merge_bad failed!
41 merging zzz2_merge_bad failed!
41 3 files updated, 1 files merged, 2 files removed, 1 files unresolved
42 3 files updated, 1 files merged, 2 files removed, 1 files unresolved
42 use 'hg resolve' to retry unresolved file merges
43 use 'hg resolve' to retry unresolved file merges
43 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
44 merging zzz1_merge_ok
45 merging zzz2_merge_bad
46 2 files updated, 2 files merged, 3 files removed, 0 files unresolved
44 --- a/zzz1_merge_ok
47 --- a/zzz1_merge_ok
45 +++ b/zzz1_merge_ok
48 +++ b/zzz1_merge_ok
46 +new first line
49 +new first line
47 +new last line
50 +new last line
48 --- a/zzz2_merge_bad
51 --- a/zzz2_merge_bad
49 +++ b/zzz2_merge_bad
52 +++ b/zzz2_merge_bad
50 +another last line
53 +another last line
51 +=======
54 +=======
52 +new last line
55 +new last line
53 M zzz1_merge_ok
56 M zzz1_merge_ok
54 M zzz2_merge_bad
57 M zzz2_merge_bad
55 ? zzz2_merge_bad.orig
56 # local merge without conflicts
58 # local merge without conflicts
57 merging zzz1_merge_ok
59 merging zzz1_merge_ok
58 4 files updated, 1 files merged, 2 files removed, 0 files unresolved
60 4 files updated, 1 files merged, 2 files removed, 0 files unresolved
59 --- a/zzz1_merge_ok
61 --- a/zzz1_merge_ok
60 +++ b/zzz1_merge_ok
62 +++ b/zzz1_merge_ok
61 +new last line
63 +new last line
62 M zzz1_merge_ok
64 M zzz1_merge_ok
63 ? zzz2_merge_bad.orig
65 ? zzz2_merge_bad.orig
@@ -1,153 +1,159 b''
1 adding a
1 adding a
2 updating working directory
2 updating working directory
3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
4 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
5 diff -r 33aaa84a386b a
5 diff -r 33aaa84a386b a
6 --- a/a
6 --- a/a
7 +++ b/a
7 +++ b/a
8 @@ -1,1 +1,1 @@
8 @@ -1,1 +1,1 @@
9 -a
9 -a
10 +abc
10 +abc
11 adding b
11 adding b
12 M a
12 M a
13 changeset: 0:33aaa84a386b
13 changeset: 0:33aaa84a386b
14 user: test
14 user: test
15 date: Mon Jan 12 13:46:40 1970 +0000
15 date: Mon Jan 12 13:46:40 1970 +0000
16 summary: 1
16 summary: 1
17
17
18 resolving manifests
18 resolving manifests
19 overwrite False partial False
19 overwrite False partial False
20 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
20 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
21 searching for copies back to rev 1
21 searching for copies back to rev 1
22 unmatched files in other:
22 unmatched files in other:
23 b
23 b
24 a: versions differ -> m
24 a: versions differ -> m
25 b: remote created -> g
25 b: remote created -> g
26 preserving a for resolve of a
26 preserving a for resolve of a
27 picked tool 'true' for a (binary False symlink False)
27 picked tool 'true' for a (binary False symlink False)
28 merging a
28 merging a
29 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
29 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
30 getting b
30 getting b
31 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
31 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
32 changeset: 1:802f095af299
32 changeset: 1:802f095af299
33 tag: tip
33 tag: tip
34 user: test
34 user: test
35 date: Mon Jan 12 13:46:40 1970 +0000
35 date: Mon Jan 12 13:46:40 1970 +0000
36 summary: 2
36 summary: 2
37
37
38 resolving manifests
38 resolving manifests
39 overwrite False partial False
39 overwrite False partial False
40 ancestor 33aaa84a386b local 802f095af299+ remote 33aaa84a386b
40 ancestor 33aaa84a386b local 802f095af299+ remote 33aaa84a386b
41 a: versions differ -> m
41 b: other deleted -> r
42 b: other deleted -> r
43 preserving a for resolve of a
42 removing b
44 removing b
43 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
45 picked tool 'true' for a (binary False symlink False)
46 merging a
47 my a@802f095af299+ other a@33aaa84a386b ancestor a@33aaa84a386b
48 premerge successful
49 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
44 changeset: 0:33aaa84a386b
50 changeset: 0:33aaa84a386b
45 user: test
51 user: test
46 date: Mon Jan 12 13:46:40 1970 +0000
52 date: Mon Jan 12 13:46:40 1970 +0000
47 summary: 1
53 summary: 1
48
54
49 abort: there is nothing to merge - use "hg update" instead
55 abort: there is nothing to merge - use "hg update" instead
50 failed
56 failed
51 changeset: 0:33aaa84a386b
57 changeset: 0:33aaa84a386b
52 user: test
58 user: test
53 date: Mon Jan 12 13:46:40 1970 +0000
59 date: Mon Jan 12 13:46:40 1970 +0000
54 summary: 1
60 summary: 1
55
61
56 resolving manifests
62 resolving manifests
57 overwrite False partial False
63 overwrite False partial False
58 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
64 ancestor 33aaa84a386b local 33aaa84a386b+ remote 802f095af299
59 searching for copies back to rev 1
65 searching for copies back to rev 1
60 unmatched files in other:
66 unmatched files in other:
61 b
67 b
62 a: versions differ -> m
68 a: versions differ -> m
63 b: remote created -> g
69 b: remote created -> g
64 preserving a for resolve of a
70 preserving a for resolve of a
65 picked tool 'true' for a (binary False symlink False)
71 picked tool 'true' for a (binary False symlink False)
66 merging a
72 merging a
67 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
73 my a@33aaa84a386b+ other a@802f095af299 ancestor a@33aaa84a386b
68 getting b
74 getting b
69 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
75 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
70 changeset: 1:802f095af299
76 changeset: 1:802f095af299
71 tag: tip
77 tag: tip
72 user: test
78 user: test
73 date: Mon Jan 12 13:46:40 1970 +0000
79 date: Mon Jan 12 13:46:40 1970 +0000
74 summary: 2
80 summary: 2
75
81
76 changeset: 1:802f095af299
82 changeset: 1:802f095af299
77 tag: tip
83 tag: tip
78 user: test
84 user: test
79 date: Mon Jan 12 13:46:40 1970 +0000
85 date: Mon Jan 12 13:46:40 1970 +0000
80 files: a b
86 files: a b
81 description:
87 description:
82 2
88 2
83
89
84
90
85 changeset: 0:33aaa84a386b
91 changeset: 0:33aaa84a386b
86 user: test
92 user: test
87 date: Mon Jan 12 13:46:40 1970 +0000
93 date: Mon Jan 12 13:46:40 1970 +0000
88 files: a
94 files: a
89 description:
95 description:
90 1
96 1
91
97
92
98
93 diff -r 802f095af299 a
99 diff -r 802f095af299 a
94 --- a/a
100 --- a/a
95 +++ b/a
101 +++ b/a
96 @@ -1,1 +1,1 @@
102 @@ -1,1 +1,1 @@
97 -a2
103 -a2
98 +abc
104 +abc
99 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
105 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
100 adding b
106 adding b
101 created new head
107 created new head
102 M a
108 M a
103 changeset: 1:802f095af299
109 changeset: 1:802f095af299
104 user: test
110 user: test
105 date: Mon Jan 12 13:46:40 1970 +0000
111 date: Mon Jan 12 13:46:40 1970 +0000
106 summary: 2
112 summary: 2
107
113
108 abort: crosses branches (use 'hg merge' or 'hg update -C' to discard changes)
114 abort: crosses branches (use 'hg merge' or 'hg update -C' to discard changes)
109 failed
115 failed
110 abort: outstanding uncommitted changes (use 'hg status' to list changes)
116 abort: outstanding uncommitted changes (use 'hg status' to list changes)
111 failed
117 failed
112 resolving manifests
118 resolving manifests
113 overwrite False partial False
119 overwrite False partial False
114 ancestor 33aaa84a386b local 802f095af299+ remote 030602aee63d
120 ancestor 33aaa84a386b local 802f095af299+ remote 030602aee63d
115 searching for copies back to rev 1
121 searching for copies back to rev 1
116 a: versions differ -> m
122 a: versions differ -> m
117 b: versions differ -> m
123 b: versions differ -> m
118 preserving a for resolve of a
124 preserving a for resolve of a
119 preserving b for resolve of b
125 preserving b for resolve of b
120 picked tool 'true' for a (binary False symlink False)
126 picked tool 'true' for a (binary False symlink False)
121 merging a
127 merging a
122 my a@802f095af299+ other a@030602aee63d ancestor a@33aaa84a386b
128 my a@802f095af299+ other a@030602aee63d ancestor a@33aaa84a386b
123 picked tool 'true' for b (binary False symlink False)
129 picked tool 'true' for b (binary False symlink False)
124 merging b
130 merging b
125 my b@802f095af299+ other b@030602aee63d ancestor b@000000000000
131 my b@802f095af299+ other b@030602aee63d ancestor b@000000000000
126 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
132 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
127 (branch merge, don't forget to commit)
133 (branch merge, don't forget to commit)
128 changeset: 1:802f095af299
134 changeset: 1:802f095af299
129 user: test
135 user: test
130 date: Mon Jan 12 13:46:40 1970 +0000
136 date: Mon Jan 12 13:46:40 1970 +0000
131 summary: 2
137 summary: 2
132
138
133 changeset: 2:030602aee63d
139 changeset: 2:030602aee63d
134 tag: tip
140 tag: tip
135 parent: 0:33aaa84a386b
141 parent: 0:33aaa84a386b
136 user: test
142 user: test
137 date: Mon Jan 12 13:46:40 1970 +0000
143 date: Mon Jan 12 13:46:40 1970 +0000
138 summary: 3
144 summary: 3
139
145
140 diff -r 802f095af299 a
146 diff -r 802f095af299 a
141 --- a/a
147 --- a/a
142 +++ b/a
148 +++ b/a
143 @@ -1,1 +1,1 @@
149 @@ -1,1 +1,1 @@
144 -a2
150 -a2
145 +abc
151 +abc
146 adding a
152 adding a
147 pulling from ../a
153 pulling from ../a
148 requesting all changes
154 requesting all changes
149 adding changesets
155 adding changesets
150 adding manifests
156 adding manifests
151 adding file changes
157 adding file changes
152 added 1 changesets with 1 changes to 1 files
158 added 1 changesets with 1 changes to 1 files
153 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1,160 +1,160 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 hg init t
3 hg init t
4 cd t
4 cd t
5
5
6 cat > unix2dos.py <<EOF
6 cat > unix2dos.py <<EOF
7 import sys
7 import sys
8
8
9 for path in sys.argv[1:]:
9 for path in sys.argv[1:]:
10 data = file(path, 'rb').read()
10 data = file(path, 'rb').read()
11 data = data.replace('\n', '\r\n')
11 data = data.replace('\n', '\r\n')
12 file(path, 'wb').write(data)
12 file(path, 'wb').write(data)
13 EOF
13 EOF
14
14
15 cat > print.py <<EOF
15 cat > print.py <<EOF
16 import sys
16 import sys
17 print(sys.stdin.read().replace('\n', '<LF>').replace('\r', '<CR>').replace('\0', '<NUL>'))
17 print(sys.stdin.read().replace('\n', '<LF>').replace('\r', '<CR>').replace('\0', '<NUL>'))
18 EOF
18 EOF
19
19
20 echo '[hooks]' >> .hg/hgrc
20 echo '[hooks]' >> .hg/hgrc
21 echo 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
21 echo 'pretxncommit.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
22 echo 'pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
22 echo 'pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf' >> .hg/hgrc
23 cat .hg/hgrc
23 cat .hg/hgrc
24 echo
24 echo
25
25
26 echo hello > f
26 echo hello > f
27 hg add f
27 hg add f
28 echo commit should succeed
28 echo commit should succeed
29 hg ci -m 1
29 hg ci -m 1
30 echo
30 echo
31
31
32 hg clone . ../zoz
32 hg clone . ../zoz
33 cp .hg/hgrc ../zoz/.hg
33 cp .hg/hgrc ../zoz/.hg
34
34
35 python unix2dos.py f
35 python unix2dos.py f
36 echo commit should fail
36 echo commit should fail
37 hg ci -m 2.1
37 hg ci -m 2.1
38 echo
38 echo
39
39
40 mv .hg/hgrc .hg/hgrc.bak
40 mv .hg/hgrc .hg/hgrc.bak
41 echo commits should succeed
41 echo commits should succeed
42 hg ci -m 2
42 hg ci -m 2
43 hg cp f g
43 hg cp f g
44 hg ci -m 2.2
44 hg ci -m 2.2
45 echo
45 echo
46
46
47 echo push should fail
47 echo push should fail
48 hg push ../zoz
48 hg push ../zoz
49 echo
49 echo
50
50
51 mv .hg/hgrc.bak .hg/hgrc
51 mv .hg/hgrc.bak .hg/hgrc
52 echo hello > f
52 echo hello > f
53 hg rm g
53 hg rm g
54 echo commit should succeed
54 echo commit should succeed
55 hg ci -m 2.3
55 hg ci -m 2.3
56 echo
56 echo
57
57
58 echo push should succeed
58 echo push should succeed
59 hg push ../zoz
59 hg push ../zoz
60 echo
60 echo
61
61
62 echo and now for something completely different
62 echo and now for something completely different
63 mkdir d
63 mkdir d
64 echo hello > d/f2
64 echo hello > d/f2
65 python unix2dos.py d/f2
65 python unix2dos.py d/f2
66 hg add d/f2
66 hg add d/f2
67 hg ci -m 3
67 hg ci -m 3
68 hg revert -a
68 hg revert -a
69 rm d/f2
69 rm d/f2
70 echo
70 echo
71
71
72 hg rem f
72 hg rem f
73 hg ci -m 4
73 hg ci -m 4
74 echo
74 echo
75
75
76 python -c 'file("bin", "wb").write("hello\x00\x0D\x0A")'
76 python -c 'file("bin", "wb").write("hello\x00\x0D\x0A")'
77 hg add bin
77 hg add bin
78 hg ci -m 5
78 hg ci -m 5
79 hg log -v
79 hg log -v
80 echo
80 echo
81
81
82 hg clone . dupe
82 hg clone . dupe
83 echo
83 echo
84 for x in a b c d; do echo content > dupe/$x; done
84 for x in a b c d; do echo content > dupe/$x; done
85 hg -R dupe add
85 hg -R dupe add
86 python unix2dos.py dupe/b dupe/c dupe/d
86 python unix2dos.py dupe/b dupe/c dupe/d
87 hg -R dupe ci -m a dupe/a
87 hg -R dupe ci -m a dupe/a
88 hg -R dupe ci -m b/c dupe/[bc]
88 hg -R dupe ci -m b/c dupe/[bc]
89 hg -R dupe ci -m d dupe/d
89 hg -R dupe ci -m d dupe/d
90 hg -R dupe log -v
90 hg -R dupe log -v
91 echo
91 echo
92
92
93 hg pull dupe
93 hg pull dupe
94 echo
94 echo
95
95
96 hg log -v
96 hg log -v
97 echo
97 echo
98
98
99 rm .hg/hgrc
99 rm .hg/hgrc
100 (echo some; echo text) > f3
100 (echo some; echo text) > f3
101 python -c 'file("f4.bat", "wb").write("rem empty\x0D\x0A")'
101 python -c 'file("f4.bat", "wb").write("rem empty\x0D\x0A")'
102 hg add f3 f4.bat
102 hg add f3 f4.bat
103 hg ci -m 6
103 hg ci -m 6
104
104
105 python print.py < bin
105 python print.py < bin
106 python print.py < f3
106 python print.py < f3
107 python print.py < f4.bat
107 python print.py < f4.bat
108 echo
108 echo
109
109
110 echo '[extensions]' >> .hg/hgrc
110 echo '[extensions]' >> .hg/hgrc
111 echo 'win32text = ' >> .hg/hgrc
111 echo 'win32text = ' >> .hg/hgrc
112 echo '[decode]' >> .hg/hgrc
112 echo '[decode]' >> .hg/hgrc
113 echo '** = cleverdecode:' >> .hg/hgrc
113 echo '** = cleverdecode:' >> .hg/hgrc
114 echo '[encode]' >> .hg/hgrc
114 echo '[encode]' >> .hg/hgrc
115 echo '** = cleverencode:' >> .hg/hgrc
115 echo '** = cleverencode:' >> .hg/hgrc
116 cat .hg/hgrc
116 cat .hg/hgrc
117 echo
117 echo
118
118
119 rm f3 f4.bat bin
119 rm f3 f4.bat bin
120 hg co 2>&1 | python -c 'import sys, os; sys.stdout.write(sys.stdin.read().replace(os.getcwd(), "...."))'
120 hg co -C 2>&1 | python -c 'import sys, os; sys.stdout.write(sys.stdin.read().replace(os.getcwd(), "...."))'
121 python print.py < bin
121 python print.py < bin
122 python print.py < f3
122 python print.py < f3
123 python print.py < f4.bat
123 python print.py < f4.bat
124 echo
124 echo
125
125
126 python -c 'file("f5.sh", "wb").write("# empty\x0D\x0A")'
126 python -c 'file("f5.sh", "wb").write("# empty\x0D\x0A")'
127 hg add f5.sh
127 hg add f5.sh
128 hg ci -m 7
128 hg ci -m 7
129 python print.py < f5.sh
129 python print.py < f5.sh
130 hg cat f5.sh | python print.py
130 hg cat f5.sh | python print.py
131
131
132 echo '% just linefeed' > linefeed
132 echo '% just linefeed' > linefeed
133 hg ci -qAm 8 linefeed
133 hg ci -qAm 8 linefeed
134 python print.py < linefeed
134 python print.py < linefeed
135 hg cat linefeed | python print.py
135 hg cat linefeed | python print.py
136 hg st -q
136 hg st -q
137 hg revert -a linefeed
137 hg revert -a linefeed
138 python print.py < linefeed
138 python print.py < linefeed
139 hg st -q
139 hg st -q
140 echo modified >> linefeed
140 echo modified >> linefeed
141 hg st -q
141 hg st -q
142 hg revert -a
142 hg revert -a
143 hg st -q
143 hg st -q
144 python print.py < linefeed
144 python print.py < linefeed
145
145
146 echo "# disable extension again"
146 echo "# disable extension again"
147 echo '[decode]' >> .hg/hgrc
147 echo '[decode]' >> .hg/hgrc
148 echo '** = !' >> .hg/hgrc
148 echo '** = !' >> .hg/hgrc
149 echo '[encode]' >> .hg/hgrc
149 echo '[encode]' >> .hg/hgrc
150 echo '** = !' >> .hg/hgrc
150 echo '** = !' >> .hg/hgrc
151 cat .hg/hgrc
151 cat .hg/hgrc
152 echo
152 echo
153
153
154 rm f3 f4.bat bin
154 rm f3 f4.bat bin
155 hg co 2>&1 | python -c 'import sys, os; sys.stdout.write(sys.stdin.read().replace(os.getcwd(), "...."))'
155 hg co -C 2>&1 | python -c 'import sys, os; sys.stdout.write(sys.stdin.read().replace(os.getcwd(), "...."))'
156 python print.py < bin
156 python print.py < bin
157 python print.py < f3
157 python print.py < f3
158 python print.py < f4.bat
158 python print.py < f4.bat
159 echo
159 echo
160
160
@@ -1,321 +1,321 b''
1 [hooks]
1 [hooks]
2 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
2 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
3 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
3 pretxnchangegroup.crlf = python:hgext.win32text.forbidcrlf
4
4
5 commit should succeed
5 commit should succeed
6
6
7 updating working directory
7 updating working directory
8 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
8 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
9 commit should fail
9 commit should fail
10 Attempt to commit or push text file(s) using CRLF line endings
10 Attempt to commit or push text file(s) using CRLF line endings
11 in f583ea08d42a: f
11 in f583ea08d42a: f
12 transaction abort!
12 transaction abort!
13 rollback completed
13 rollback completed
14 abort: pretxncommit.crlf hook failed
14 abort: pretxncommit.crlf hook failed
15
15
16 commits should succeed
16 commits should succeed
17
17
18 push should fail
18 push should fail
19 pushing to ../zoz
19 pushing to ../zoz
20 searching for changes
20 searching for changes
21 adding changesets
21 adding changesets
22 adding manifests
22 adding manifests
23 adding file changes
23 adding file changes
24 added 2 changesets with 2 changes to 2 files
24 added 2 changesets with 2 changes to 2 files
25 Attempt to commit or push text file(s) using CRLF line endings
25 Attempt to commit or push text file(s) using CRLF line endings
26 in b94ebd309a6d: g
26 in b94ebd309a6d: g
27 in b1aa5cde7ff4: f
27 in b1aa5cde7ff4: f
28
28
29 To prevent this mistake in your local repository,
29 To prevent this mistake in your local repository,
30 add to Mercurial.ini or .hg/hgrc:
30 add to Mercurial.ini or .hg/hgrc:
31
31
32 [hooks]
32 [hooks]
33 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
33 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
34
34
35 and also consider adding:
35 and also consider adding:
36
36
37 [extensions]
37 [extensions]
38 hgext.win32text =
38 hgext.win32text =
39 [encode]
39 [encode]
40 ** = cleverencode:
40 ** = cleverencode:
41 [decode]
41 [decode]
42 ** = cleverdecode:
42 ** = cleverdecode:
43 transaction abort!
43 transaction abort!
44 rollback completed
44 rollback completed
45 abort: pretxnchangegroup.crlf hook failed
45 abort: pretxnchangegroup.crlf hook failed
46
46
47 commit should succeed
47 commit should succeed
48
48
49 push should succeed
49 push should succeed
50 pushing to ../zoz
50 pushing to ../zoz
51 searching for changes
51 searching for changes
52 adding changesets
52 adding changesets
53 adding manifests
53 adding manifests
54 adding file changes
54 adding file changes
55 added 3 changesets with 3 changes to 2 files
55 added 3 changesets with 3 changes to 2 files
56
56
57 and now for something completely different
57 and now for something completely different
58 Attempt to commit or push text file(s) using CRLF line endings
58 Attempt to commit or push text file(s) using CRLF line endings
59 in cefdb8d0b741: d/f2
59 in cefdb8d0b741: d/f2
60 transaction abort!
60 transaction abort!
61 rollback completed
61 rollback completed
62 abort: pretxncommit.crlf hook failed
62 abort: pretxncommit.crlf hook failed
63 forgetting d/f2
63 forgetting d/f2
64
64
65
65
66 changeset: 5:d4ea9ae21be3
66 changeset: 5:d4ea9ae21be3
67 tag: tip
67 tag: tip
68 user: test
68 user: test
69 date: Thu Jan 01 00:00:00 1970 +0000
69 date: Thu Jan 01 00:00:00 1970 +0000
70 files: bin
70 files: bin
71 description:
71 description:
72 5
72 5
73
73
74
74
75 changeset: 4:6ba409927d51
75 changeset: 4:6ba409927d51
76 user: test
76 user: test
77 date: Thu Jan 01 00:00:00 1970 +0000
77 date: Thu Jan 01 00:00:00 1970 +0000
78 files: f
78 files: f
79 description:
79 description:
80 4
80 4
81
81
82
82
83 changeset: 3:788a4e595187
83 changeset: 3:788a4e595187
84 user: test
84 user: test
85 date: Thu Jan 01 00:00:00 1970 +0000
85 date: Thu Jan 01 00:00:00 1970 +0000
86 files: f g
86 files: f g
87 description:
87 description:
88 2.3
88 2.3
89
89
90
90
91 changeset: 2:b94ebd309a6d
91 changeset: 2:b94ebd309a6d
92 user: test
92 user: test
93 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
94 files: g
94 files: g
95 description:
95 description:
96 2.2
96 2.2
97
97
98
98
99 changeset: 1:b1aa5cde7ff4
99 changeset: 1:b1aa5cde7ff4
100 user: test
100 user: test
101 date: Thu Jan 01 00:00:00 1970 +0000
101 date: Thu Jan 01 00:00:00 1970 +0000
102 files: f
102 files: f
103 description:
103 description:
104 2
104 2
105
105
106
106
107 changeset: 0:fcf06d5c4e1d
107 changeset: 0:fcf06d5c4e1d
108 user: test
108 user: test
109 date: Thu Jan 01 00:00:00 1970 +0000
109 date: Thu Jan 01 00:00:00 1970 +0000
110 files: f
110 files: f
111 description:
111 description:
112 1
112 1
113
113
114
114
115
115
116 updating working directory
116 updating working directory
117 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
117 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
118
118
119 adding dupe/a
119 adding dupe/a
120 adding dupe/b
120 adding dupe/b
121 adding dupe/c
121 adding dupe/c
122 adding dupe/d
122 adding dupe/d
123 changeset: 8:7654104f33c3
123 changeset: 8:7654104f33c3
124 tag: tip
124 tag: tip
125 user: test
125 user: test
126 date: Thu Jan 01 00:00:00 1970 +0000
126 date: Thu Jan 01 00:00:00 1970 +0000
127 files: d
127 files: d
128 description:
128 description:
129 d
129 d
130
130
131
131
132 changeset: 7:9be4c2808cc9
132 changeset: 7:9be4c2808cc9
133 user: test
133 user: test
134 date: Thu Jan 01 00:00:00 1970 +0000
134 date: Thu Jan 01 00:00:00 1970 +0000
135 files: b c
135 files: b c
136 description:
136 description:
137 b/c
137 b/c
138
138
139
139
140 changeset: 6:aa4367ed325a
140 changeset: 6:aa4367ed325a
141 user: test
141 user: test
142 date: Thu Jan 01 00:00:00 1970 +0000
142 date: Thu Jan 01 00:00:00 1970 +0000
143 files: a
143 files: a
144 description:
144 description:
145 a
145 a
146
146
147
147
148 changeset: 5:d4ea9ae21be3
148 changeset: 5:d4ea9ae21be3
149 user: test
149 user: test
150 date: Thu Jan 01 00:00:00 1970 +0000
150 date: Thu Jan 01 00:00:00 1970 +0000
151 files: bin
151 files: bin
152 description:
152 description:
153 5
153 5
154
154
155
155
156 changeset: 4:6ba409927d51
156 changeset: 4:6ba409927d51
157 user: test
157 user: test
158 date: Thu Jan 01 00:00:00 1970 +0000
158 date: Thu Jan 01 00:00:00 1970 +0000
159 files: f
159 files: f
160 description:
160 description:
161 4
161 4
162
162
163
163
164 changeset: 3:788a4e595187
164 changeset: 3:788a4e595187
165 user: test
165 user: test
166 date: Thu Jan 01 00:00:00 1970 +0000
166 date: Thu Jan 01 00:00:00 1970 +0000
167 files: f g
167 files: f g
168 description:
168 description:
169 2.3
169 2.3
170
170
171
171
172 changeset: 2:b94ebd309a6d
172 changeset: 2:b94ebd309a6d
173 user: test
173 user: test
174 date: Thu Jan 01 00:00:00 1970 +0000
174 date: Thu Jan 01 00:00:00 1970 +0000
175 files: g
175 files: g
176 description:
176 description:
177 2.2
177 2.2
178
178
179
179
180 changeset: 1:b1aa5cde7ff4
180 changeset: 1:b1aa5cde7ff4
181 user: test
181 user: test
182 date: Thu Jan 01 00:00:00 1970 +0000
182 date: Thu Jan 01 00:00:00 1970 +0000
183 files: f
183 files: f
184 description:
184 description:
185 2
185 2
186
186
187
187
188 changeset: 0:fcf06d5c4e1d
188 changeset: 0:fcf06d5c4e1d
189 user: test
189 user: test
190 date: Thu Jan 01 00:00:00 1970 +0000
190 date: Thu Jan 01 00:00:00 1970 +0000
191 files: f
191 files: f
192 description:
192 description:
193 1
193 1
194
194
195
195
196
196
197 pulling from dupe
197 pulling from dupe
198 searching for changes
198 searching for changes
199 adding changesets
199 adding changesets
200 adding manifests
200 adding manifests
201 adding file changes
201 adding file changes
202 added 3 changesets with 4 changes to 4 files
202 added 3 changesets with 4 changes to 4 files
203 Attempt to commit or push text file(s) using CRLF line endings
203 Attempt to commit or push text file(s) using CRLF line endings
204 in 7654104f33c3: d
204 in 7654104f33c3: d
205 in 9be4c2808cc9: b
205 in 9be4c2808cc9: b
206 in 9be4c2808cc9: c
206 in 9be4c2808cc9: c
207
207
208 To prevent this mistake in your local repository,
208 To prevent this mistake in your local repository,
209 add to Mercurial.ini or .hg/hgrc:
209 add to Mercurial.ini or .hg/hgrc:
210
210
211 [hooks]
211 [hooks]
212 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
212 pretxncommit.crlf = python:hgext.win32text.forbidcrlf
213
213
214 and also consider adding:
214 and also consider adding:
215
215
216 [extensions]
216 [extensions]
217 hgext.win32text =
217 hgext.win32text =
218 [encode]
218 [encode]
219 ** = cleverencode:
219 ** = cleverencode:
220 [decode]
220 [decode]
221 ** = cleverdecode:
221 ** = cleverdecode:
222 transaction abort!
222 transaction abort!
223 rollback completed
223 rollback completed
224 abort: pretxnchangegroup.crlf hook failed
224 abort: pretxnchangegroup.crlf hook failed
225
225
226 changeset: 5:d4ea9ae21be3
226 changeset: 5:d4ea9ae21be3
227 tag: tip
227 tag: tip
228 user: test
228 user: test
229 date: Thu Jan 01 00:00:00 1970 +0000
229 date: Thu Jan 01 00:00:00 1970 +0000
230 files: bin
230 files: bin
231 description:
231 description:
232 5
232 5
233
233
234
234
235 changeset: 4:6ba409927d51
235 changeset: 4:6ba409927d51
236 user: test
236 user: test
237 date: Thu Jan 01 00:00:00 1970 +0000
237 date: Thu Jan 01 00:00:00 1970 +0000
238 files: f
238 files: f
239 description:
239 description:
240 4
240 4
241
241
242
242
243 changeset: 3:788a4e595187
243 changeset: 3:788a4e595187
244 user: test
244 user: test
245 date: Thu Jan 01 00:00:00 1970 +0000
245 date: Thu Jan 01 00:00:00 1970 +0000
246 files: f g
246 files: f g
247 description:
247 description:
248 2.3
248 2.3
249
249
250
250
251 changeset: 2:b94ebd309a6d
251 changeset: 2:b94ebd309a6d
252 user: test
252 user: test
253 date: Thu Jan 01 00:00:00 1970 +0000
253 date: Thu Jan 01 00:00:00 1970 +0000
254 files: g
254 files: g
255 description:
255 description:
256 2.2
256 2.2
257
257
258
258
259 changeset: 1:b1aa5cde7ff4
259 changeset: 1:b1aa5cde7ff4
260 user: test
260 user: test
261 date: Thu Jan 01 00:00:00 1970 +0000
261 date: Thu Jan 01 00:00:00 1970 +0000
262 files: f
262 files: f
263 description:
263 description:
264 2
264 2
265
265
266
266
267 changeset: 0:fcf06d5c4e1d
267 changeset: 0:fcf06d5c4e1d
268 user: test
268 user: test
269 date: Thu Jan 01 00:00:00 1970 +0000
269 date: Thu Jan 01 00:00:00 1970 +0000
270 files: f
270 files: f
271 description:
271 description:
272 1
272 1
273
273
274
274
275
275
276 hello<NUL><CR><LF>
276 hello<NUL><CR><LF>
277 some<LF>text<LF>
277 some<LF>text<LF>
278 rem empty<CR><LF>
278 rem empty<CR><LF>
279
279
280 [extensions]
280 [extensions]
281 win32text =
281 win32text =
282 [decode]
282 [decode]
283 ** = cleverdecode:
283 ** = cleverdecode:
284 [encode]
284 [encode]
285 ** = cleverencode:
285 ** = cleverencode:
286
286
287 WARNING: f4.bat already has CRLF line endings
287 WARNING: f4.bat already has CRLF line endings
288 and does not need EOL conversion by the win32text plugin.
288 and does not need EOL conversion by the win32text plugin.
289 Before your next commit, please reconsider your encode/decode settings in
289 Before your next commit, please reconsider your encode/decode settings in
290 Mercurial.ini or ..../.hg/hgrc.
290 Mercurial.ini or ..../.hg/hgrc.
291 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
292 hello<NUL><CR><LF>
292 hello<NUL><CR><LF>
293 some<CR><LF>text<CR><LF>
293 some<CR><LF>text<CR><LF>
294 rem empty<CR><LF>
294 rem empty<CR><LF>
295
295
296 # empty<CR><LF>
296 # empty<CR><LF>
297 # empty<LF>
297 # empty<LF>
298 % just linefeed<LF>
298 % just linefeed<LF>
299 % just linefeed<LF>
299 % just linefeed<LF>
300 no changes needed to linefeed
300 no changes needed to linefeed
301 % just linefeed<LF>
301 % just linefeed<LF>
302 M linefeed
302 M linefeed
303 reverting linefeed
303 reverting linefeed
304 % just linefeed<CR><LF>
304 % just linefeed<CR><LF>
305 # disable extension again
305 # disable extension again
306 [extensions]
306 [extensions]
307 win32text =
307 win32text =
308 [decode]
308 [decode]
309 ** = cleverdecode:
309 ** = cleverdecode:
310 [encode]
310 [encode]
311 ** = cleverencode:
311 ** = cleverencode:
312 [decode]
312 [decode]
313 ** = !
313 ** = !
314 [encode]
314 [encode]
315 ** = !
315 ** = !
316
316
317 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
317 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
318 hello<NUL><CR><LF>
318 hello<NUL><CR><LF>
319 some<LF>text<LF>
319 some<LF>text<LF>
320 rem empty<LF>
320 rem empty<LF>
321
321
General Comments 0
You need to be logged in to leave comments. Login now