##// END OF EJS Templates
merge: changing the mode of a file is also an update...
Mads Kiilerich -
r18334:44bda93d default
parent child Browse files
Show More
@@ -1,651 +1,652
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 or any later version.
6 # GNU General Public License version 2 or any later version.
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 error, util, filemerge, copies, subrepo
10 import error, util, filemerge, copies, subrepo
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._dirty = False
17 self._dirty = False
18 self._read()
18 self._read()
19 def reset(self, node=None):
19 def reset(self, node=None):
20 self._state = {}
20 self._state = {}
21 if node:
21 if node:
22 self._local = node
22 self._local = node
23 shutil.rmtree(self._repo.join("merge"), True)
23 shutil.rmtree(self._repo.join("merge"), True)
24 self._dirty = False
24 self._dirty = False
25 def _read(self):
25 def _read(self):
26 self._state = {}
26 self._state = {}
27 try:
27 try:
28 f = self._repo.opener("merge/state")
28 f = self._repo.opener("merge/state")
29 for i, l in enumerate(f):
29 for i, l in enumerate(f):
30 if i == 0:
30 if i == 0:
31 self._local = bin(l[:-1])
31 self._local = bin(l[:-1])
32 else:
32 else:
33 bits = l[:-1].split("\0")
33 bits = l[:-1].split("\0")
34 self._state[bits[0]] = bits[1:]
34 self._state[bits[0]] = bits[1:]
35 f.close()
35 f.close()
36 except IOError, err:
36 except IOError, err:
37 if err.errno != errno.ENOENT:
37 if err.errno != errno.ENOENT:
38 raise
38 raise
39 self._dirty = False
39 self._dirty = False
40 def commit(self):
40 def commit(self):
41 if self._dirty:
41 if self._dirty:
42 f = self._repo.opener("merge/state", "w")
42 f = self._repo.opener("merge/state", "w")
43 f.write(hex(self._local) + "\n")
43 f.write(hex(self._local) + "\n")
44 for d, v in self._state.iteritems():
44 for d, v in self._state.iteritems():
45 f.write("\0".join([d] + v) + "\n")
45 f.write("\0".join([d] + v) + "\n")
46 f.close()
46 f.close()
47 self._dirty = False
47 self._dirty = False
48 def add(self, fcl, fco, fca, fd, flags):
48 def add(self, fcl, fco, fca, fd, flags):
49 hash = util.sha1(fcl.path()).hexdigest()
49 hash = util.sha1(fcl.path()).hexdigest()
50 self._repo.opener.write("merge/" + hash, fcl.data())
50 self._repo.opener.write("merge/" + hash, fcl.data())
51 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
51 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
52 hex(fca.filenode()), fco.path(), flags]
52 hex(fca.filenode()), fco.path(), flags]
53 self._dirty = True
53 self._dirty = True
54 def __contains__(self, dfile):
54 def __contains__(self, dfile):
55 return dfile in self._state
55 return dfile in self._state
56 def __getitem__(self, dfile):
56 def __getitem__(self, dfile):
57 return self._state[dfile][0]
57 return self._state[dfile][0]
58 def __iter__(self):
58 def __iter__(self):
59 l = self._state.keys()
59 l = self._state.keys()
60 l.sort()
60 l.sort()
61 for f in l:
61 for f in l:
62 yield f
62 yield f
63 def mark(self, dfile, state):
63 def mark(self, dfile, state):
64 self._state[dfile][0] = state
64 self._state[dfile][0] = state
65 self._dirty = True
65 self._dirty = True
66 def resolve(self, dfile, wctx, octx):
66 def resolve(self, dfile, wctx, octx):
67 if self[dfile] == 'r':
67 if self[dfile] == 'r':
68 return 0
68 return 0
69 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
69 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
70 f = self._repo.opener("merge/" + hash)
70 f = self._repo.opener("merge/" + hash)
71 self._repo.wwrite(dfile, f.read(), flags)
71 self._repo.wwrite(dfile, f.read(), flags)
72 f.close()
72 f.close()
73 fcd = wctx[dfile]
73 fcd = wctx[dfile]
74 fco = octx[ofile]
74 fco = octx[ofile]
75 fca = self._repo.filectx(afile, fileid=anode)
75 fca = self._repo.filectx(afile, fileid=anode)
76 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
76 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
77 if r is None:
77 if r is None:
78 # no real conflict
78 # no real conflict
79 del self._state[dfile]
79 del self._state[dfile]
80 elif not r:
80 elif not r:
81 self.mark(dfile, 'r')
81 self.mark(dfile, 'r')
82 return r
82 return r
83
83
84 def _checkunknownfile(repo, wctx, mctx, f):
84 def _checkunknownfile(repo, wctx, mctx, f):
85 return (not repo.dirstate._ignore(f)
85 return (not repo.dirstate._ignore(f)
86 and os.path.isfile(repo.wjoin(f))
86 and os.path.isfile(repo.wjoin(f))
87 and repo.dirstate.normalize(f) not in repo.dirstate
87 and repo.dirstate.normalize(f) not in repo.dirstate
88 and mctx[f].cmp(wctx[f]))
88 and mctx[f].cmp(wctx[f]))
89
89
90 def _checkunknown(repo, wctx, mctx):
90 def _checkunknown(repo, wctx, mctx):
91 "check for collisions between unknown files and files in mctx"
91 "check for collisions between unknown files and files in mctx"
92
92
93 error = False
93 error = False
94 for f in mctx:
94 for f in mctx:
95 if f not in wctx and _checkunknownfile(repo, wctx, mctx, f):
95 if f not in wctx and _checkunknownfile(repo, wctx, mctx, f):
96 error = True
96 error = True
97 wctx._repo.ui.warn(_("%s: untracked file differs\n") % f)
97 wctx._repo.ui.warn(_("%s: untracked file differs\n") % f)
98 if error:
98 if error:
99 raise util.Abort(_("untracked files in working directory differ "
99 raise util.Abort(_("untracked files in working directory differ "
100 "from files in requested revision"))
100 "from files in requested revision"))
101
101
102 def _remains(f, m, ma, workingctx=False):
102 def _remains(f, m, ma, workingctx=False):
103 """check whether specified file remains after merge.
103 """check whether specified file remains after merge.
104
104
105 It is assumed that specified file is not contained in the manifest
105 It is assumed that specified file is not contained in the manifest
106 of the other context.
106 of the other context.
107 """
107 """
108 if f in ma:
108 if f in ma:
109 n = m[f]
109 n = m[f]
110 if n != ma[f]:
110 if n != ma[f]:
111 return True # because it is changed locally
111 return True # because it is changed locally
112 # even though it doesn't remain, if "remote deleted" is
112 # even though it doesn't remain, if "remote deleted" is
113 # chosen in manifestmerge()
113 # chosen in manifestmerge()
114 elif workingctx and n[20:] == "a":
114 elif workingctx and n[20:] == "a":
115 return True # because it is added locally (linear merge specific)
115 return True # because it is added locally (linear merge specific)
116 else:
116 else:
117 return False # because it is removed remotely
117 return False # because it is removed remotely
118 else:
118 else:
119 return True # because it is added locally
119 return True # because it is added locally
120
120
121 def _checkcollision(mctx, extractxs):
121 def _checkcollision(mctx, extractxs):
122 "check for case folding collisions in the destination context"
122 "check for case folding collisions in the destination context"
123 folded = {}
123 folded = {}
124 for fn in mctx:
124 for fn in mctx:
125 fold = util.normcase(fn)
125 fold = util.normcase(fn)
126 if fold in folded:
126 if fold in folded:
127 raise util.Abort(_("case-folding collision between %s and %s")
127 raise util.Abort(_("case-folding collision between %s and %s")
128 % (fn, folded[fold]))
128 % (fn, folded[fold]))
129 folded[fold] = fn
129 folded[fold] = fn
130
130
131 if extractxs:
131 if extractxs:
132 wctx, actx = extractxs
132 wctx, actx = extractxs
133 # class to delay looking up copy mapping
133 # class to delay looking up copy mapping
134 class pathcopies(object):
134 class pathcopies(object):
135 @util.propertycache
135 @util.propertycache
136 def map(self):
136 def map(self):
137 # {dst@mctx: src@wctx} copy mapping
137 # {dst@mctx: src@wctx} copy mapping
138 return copies.pathcopies(wctx, mctx)
138 return copies.pathcopies(wctx, mctx)
139 pc = pathcopies()
139 pc = pathcopies()
140
140
141 for fn in wctx:
141 for fn in wctx:
142 fold = util.normcase(fn)
142 fold = util.normcase(fn)
143 mfn = folded.get(fold, None)
143 mfn = folded.get(fold, None)
144 if (mfn and mfn != fn and pc.map.get(mfn) != fn and
144 if (mfn and mfn != fn and pc.map.get(mfn) != fn and
145 _remains(fn, wctx.manifest(), actx.manifest(), True) and
145 _remains(fn, wctx.manifest(), actx.manifest(), True) and
146 _remains(mfn, mctx.manifest(), actx.manifest())):
146 _remains(mfn, mctx.manifest(), actx.manifest())):
147 raise util.Abort(_("case-folding collision between %s and %s")
147 raise util.Abort(_("case-folding collision between %s and %s")
148 % (mfn, fn))
148 % (mfn, fn))
149
149
150 def _forgetremoved(wctx, mctx, branchmerge):
150 def _forgetremoved(wctx, mctx, branchmerge):
151 """
151 """
152 Forget removed files
152 Forget removed files
153
153
154 If we're jumping between revisions (as opposed to merging), and if
154 If we're jumping between revisions (as opposed to merging), and if
155 neither the working directory nor the target rev has the file,
155 neither the working directory nor the target rev has the file,
156 then we need to remove it from the dirstate, to prevent the
156 then we need to remove it from the dirstate, to prevent the
157 dirstate from listing the file when it is no longer in the
157 dirstate from listing the file when it is no longer in the
158 manifest.
158 manifest.
159
159
160 If we're merging, and the other revision has removed a file
160 If we're merging, and the other revision has removed a file
161 that is not present in the working directory, we need to mark it
161 that is not present in the working directory, we need to mark it
162 as removed.
162 as removed.
163 """
163 """
164
164
165 actions = []
165 actions = []
166 state = branchmerge and 'r' or 'f'
166 state = branchmerge and 'r' or 'f'
167 for f in wctx.deleted():
167 for f in wctx.deleted():
168 if f not in mctx:
168 if f not in mctx:
169 actions.append((f, state))
169 actions.append((f, state))
170
170
171 if not branchmerge:
171 if not branchmerge:
172 for f in wctx.removed():
172 for f in wctx.removed():
173 if f not in mctx:
173 if f not in mctx:
174 actions.append((f, "f"))
174 actions.append((f, "f"))
175
175
176 return actions
176 return actions
177
177
178 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
178 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
179 """
179 """
180 Merge p1 and p2 with ancestor pa and generate merge action list
180 Merge p1 and p2 with ancestor pa and generate merge action list
181
181
182 overwrite = whether we clobber working files
182 overwrite = whether we clobber working files
183 partial = function to filter file lists
183 partial = function to filter file lists
184 """
184 """
185
185
186 def fmerge(f, f2, fa):
186 def fmerge(f, f2, fa):
187 """merge flags"""
187 """merge flags"""
188 a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
188 a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
189 if m == n: # flags agree
189 if m == n: # flags agree
190 return m # unchanged
190 return m # unchanged
191 if m and n and not a: # flags set, don't agree, differ from parent
191 if m and n and not a: # flags set, don't agree, differ from parent
192 r = repo.ui.promptchoice(
192 r = repo.ui.promptchoice(
193 _(" conflicting flags for %s\n"
193 _(" conflicting flags for %s\n"
194 "(n)one, e(x)ec or sym(l)ink?") % f,
194 "(n)one, e(x)ec or sym(l)ink?") % f,
195 (_("&None"), _("E&xec"), _("Sym&link")), 0)
195 (_("&None"), _("E&xec"), _("Sym&link")), 0)
196 if r == 1:
196 if r == 1:
197 return "x" # Exec
197 return "x" # Exec
198 if r == 2:
198 if r == 2:
199 return "l" # Symlink
199 return "l" # Symlink
200 return ""
200 return ""
201 if m and m != a: # changed from a to m
201 if m and m != a: # changed from a to m
202 return m
202 return m
203 if n and n != a: # changed from a to n
203 if n and n != a: # changed from a to n
204 if (n == 'l' or a == 'l') and m1.get(f) != ma.get(f):
204 if (n == 'l' or a == 'l') and m1.get(f) != ma.get(f):
205 # can't automatically merge symlink flag when there
205 # can't automatically merge symlink flag when there
206 # are file-level conflicts here, let filemerge take
206 # are file-level conflicts here, let filemerge take
207 # care of it
207 # care of it
208 return m
208 return m
209 return n
209 return n
210 return '' # flag was cleared
210 return '' # flag was cleared
211
211
212 def act(msg, m, f, *args):
212 def act(msg, m, f, *args):
213 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
213 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
214 actions.append((f, m) + args)
214 actions.append((f, m) + args)
215
215
216 actions, copy, movewithdir = [], {}, {}
216 actions, copy, movewithdir = [], {}, {}
217
217
218 if overwrite:
218 if overwrite:
219 pa = p1
219 pa = p1
220 elif pa == p2: # backwards
220 elif pa == p2: # backwards
221 pa = p1.p1()
221 pa = p1.p1()
222 elif pa and repo.ui.configbool("merge", "followcopies", True):
222 elif pa and repo.ui.configbool("merge", "followcopies", True):
223 ret = copies.mergecopies(repo, p1, p2, pa)
223 ret = copies.mergecopies(repo, p1, p2, pa)
224 copy, movewithdir, diverge, renamedelete = ret
224 copy, movewithdir, diverge, renamedelete = ret
225 for of, fl in diverge.iteritems():
225 for of, fl in diverge.iteritems():
226 act("divergent renames", "dr", of, fl)
226 act("divergent renames", "dr", of, fl)
227 for of, fl in renamedelete.iteritems():
227 for of, fl in renamedelete.iteritems():
228 act("rename and delete", "rd", of, fl)
228 act("rename and delete", "rd", of, fl)
229
229
230 repo.ui.note(_("resolving manifests\n"))
230 repo.ui.note(_("resolving manifests\n"))
231 repo.ui.debug(" overwrite: %s, partial: %s\n"
231 repo.ui.debug(" overwrite: %s, partial: %s\n"
232 % (bool(overwrite), bool(partial)))
232 % (bool(overwrite), bool(partial)))
233 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, p1, p2))
233 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, p1, p2))
234
234
235 m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest()
235 m1, m2, ma = p1.manifest(), p2.manifest(), pa.manifest()
236 copied = set(copy.values())
236 copied = set(copy.values())
237 copied.update(movewithdir.values())
237 copied.update(movewithdir.values())
238
238
239 if '.hgsubstate' in m1:
239 if '.hgsubstate' in m1:
240 # check whether sub state is modified
240 # check whether sub state is modified
241 for s in p1.substate:
241 for s in p1.substate:
242 if p1.sub(s).dirty():
242 if p1.sub(s).dirty():
243 m1['.hgsubstate'] += "+"
243 m1['.hgsubstate'] += "+"
244 break
244 break
245
245
246 # Compare manifests
246 # Compare manifests
247 for f, n in m1.iteritems():
247 for f, n in m1.iteritems():
248 if partial and not partial(f):
248 if partial and not partial(f):
249 continue
249 continue
250 if f in m2:
250 if f in m2:
251 rflags = fmerge(f, f, f)
251 rflags = fmerge(f, f, f)
252 a = ma.get(f, nullid)
252 a = ma.get(f, nullid)
253 if n == m2[f] or m2[f] == a: # same or local newer
253 if n == m2[f] or m2[f] == a: # same or local newer
254 # is file locally modified or flags need changing?
254 # is file locally modified or flags need changing?
255 # dirstate flags may need to be made current
255 # dirstate flags may need to be made current
256 if m1.flags(f) != rflags or n[20:]:
256 if m1.flags(f) != rflags or n[20:]:
257 act("update permissions", "e", f, rflags)
257 act("update permissions", "e", f, rflags)
258 elif n == a: # remote newer
258 elif n == a: # remote newer
259 act("remote is newer", "g", f, rflags)
259 act("remote is newer", "g", f, rflags)
260 else: # both changed
260 else: # both changed
261 act("versions differ", "m", f, f, f, rflags, False)
261 act("versions differ", "m", f, f, f, rflags, False)
262 elif f in copied: # files we'll deal with on m2 side
262 elif f in copied: # files we'll deal with on m2 side
263 pass
263 pass
264 elif f in movewithdir: # directory rename
264 elif f in movewithdir: # directory rename
265 f2 = movewithdir[f]
265 f2 = movewithdir[f]
266 act("remote renamed directory to " + f2, "d", f, None, f2,
266 act("remote renamed directory to " + f2, "d", f, None, f2,
267 m1.flags(f))
267 m1.flags(f))
268 elif f in copy: # case 2 A,B/B/B or case 4,21 A/B/B
268 elif f in copy: # case 2 A,B/B/B or case 4,21 A/B/B
269 f2 = copy[f]
269 f2 = copy[f]
270 act("local copied/moved to " + f2, "m", f, f2, f,
270 act("local copied/moved to " + f2, "m", f, f2, f,
271 fmerge(f, f2, f2), False)
271 fmerge(f, f2, f2), False)
272 elif f in ma: # clean, a different, no remote
272 elif f in ma: # clean, a different, no remote
273 if n != ma[f]:
273 if n != ma[f]:
274 if repo.ui.promptchoice(
274 if repo.ui.promptchoice(
275 _(" local changed %s which remote deleted\n"
275 _(" local changed %s which remote deleted\n"
276 "use (c)hanged version or (d)elete?") % f,
276 "use (c)hanged version or (d)elete?") % f,
277 (_("&Changed"), _("&Delete")), 0):
277 (_("&Changed"), _("&Delete")), 0):
278 act("prompt delete", "r", f)
278 act("prompt delete", "r", f)
279 else:
279 else:
280 act("prompt keep", "a", f)
280 act("prompt keep", "a", f)
281 elif n[20:] == "a": # added, no remote
281 elif n[20:] == "a": # added, no remote
282 act("remote deleted", "f", f)
282 act("remote deleted", "f", f)
283 else:
283 else:
284 act("other deleted", "r", f)
284 act("other deleted", "r", f)
285
285
286 for f, n in m2.iteritems():
286 for f, n in m2.iteritems():
287 if partial and not partial(f):
287 if partial and not partial(f):
288 continue
288 continue
289 if f in m1 or f in copied: # files already visited
289 if f in m1 or f in copied: # files already visited
290 continue
290 continue
291 if f in movewithdir:
291 if f in movewithdir:
292 f2 = movewithdir[f]
292 f2 = movewithdir[f]
293 act("local renamed directory to " + f2, "d", None, f, f2,
293 act("local renamed directory to " + f2, "d", None, f, f2,
294 m2.flags(f))
294 m2.flags(f))
295 elif f in copy:
295 elif f in copy:
296 f2 = copy[f]
296 f2 = copy[f]
297 if f2 in m2: # rename case 1, A/A,B/A
297 if f2 in m2: # rename case 1, A/A,B/A
298 act("remote copied to " + f, "m",
298 act("remote copied to " + f, "m",
299 f2, f, f, fmerge(f2, f, f2), False)
299 f2, f, f, fmerge(f2, f, f2), False)
300 else: # case 3,20 A/B/A
300 else: # case 3,20 A/B/A
301 act("remote moved to " + f, "m",
301 act("remote moved to " + f, "m",
302 f2, f, f, fmerge(f2, f, f2), True)
302 f2, f, f, fmerge(f2, f, f2), True)
303 elif f not in ma:
303 elif f not in ma:
304 if (not overwrite
304 if (not overwrite
305 and _checkunknownfile(repo, p1, p2, f)):
305 and _checkunknownfile(repo, p1, p2, f)):
306 rflags = fmerge(f, f, f)
306 rflags = fmerge(f, f, f)
307 act("remote differs from untracked local",
307 act("remote differs from untracked local",
308 "m", f, f, f, rflags, False)
308 "m", f, f, f, rflags, False)
309 else:
309 else:
310 act("remote created", "g", f, m2.flags(f))
310 act("remote created", "g", f, m2.flags(f))
311 elif n != ma[f]:
311 elif n != ma[f]:
312 if repo.ui.promptchoice(
312 if repo.ui.promptchoice(
313 _("remote changed %s which local deleted\n"
313 _("remote changed %s which local deleted\n"
314 "use (c)hanged version or leave (d)eleted?") % f,
314 "use (c)hanged version or leave (d)eleted?") % f,
315 (_("&Changed"), _("&Deleted")), 0) == 0:
315 (_("&Changed"), _("&Deleted")), 0) == 0:
316 act("prompt recreating", "g", f, m2.flags(f))
316 act("prompt recreating", "g", f, m2.flags(f))
317
317
318 return actions
318 return actions
319
319
320 def actionkey(a):
320 def actionkey(a):
321 return a[1] == "r" and -1 or 0, a
321 return a[1] == "r" and -1 or 0, a
322
322
323 def applyupdates(repo, actions, wctx, mctx, actx, overwrite):
323 def applyupdates(repo, actions, wctx, mctx, actx, overwrite):
324 """apply the merge action list to the working directory
324 """apply the merge action list to the working directory
325
325
326 wctx is the working copy context
326 wctx is the working copy context
327 mctx is the context to be merged into the working copy
327 mctx is the context to be merged into the working copy
328 actx is the context of the common ancestor
328 actx is the context of the common ancestor
329
329
330 Return a tuple of counts (updated, merged, removed, unresolved) that
330 Return a tuple of counts (updated, merged, removed, unresolved) that
331 describes how many files were affected by the update.
331 describes how many files were affected by the update.
332 """
332 """
333
333
334 updated, merged, removed, unresolved = 0, 0, 0, 0
334 updated, merged, removed, unresolved = 0, 0, 0, 0
335 ms = mergestate(repo)
335 ms = mergestate(repo)
336 ms.reset(wctx.p1().node())
336 ms.reset(wctx.p1().node())
337 moves = []
337 moves = []
338 actions.sort(key=actionkey)
338 actions.sort(key=actionkey)
339
339
340 # prescan for merges
340 # prescan for merges
341 for a in actions:
341 for a in actions:
342 f, m = a[:2]
342 f, m = a[:2]
343 if m == "m": # merge
343 if m == "m": # merge
344 f2, fd, flags, move = a[2:]
344 f2, fd, flags, move = a[2:]
345 if fd == '.hgsubstate': # merged internally
345 if fd == '.hgsubstate': # merged internally
346 continue
346 continue
347 repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd))
347 repo.ui.debug("preserving %s for resolve of %s\n" % (f, fd))
348 fcl = wctx[f]
348 fcl = wctx[f]
349 fco = mctx[f2]
349 fco = mctx[f2]
350 if mctx == actx: # backwards, use working dir parent as ancestor
350 if mctx == actx: # backwards, use working dir parent as ancestor
351 if fcl.parents():
351 if fcl.parents():
352 fca = fcl.p1()
352 fca = fcl.p1()
353 else:
353 else:
354 fca = repo.filectx(f, fileid=nullrev)
354 fca = repo.filectx(f, fileid=nullrev)
355 else:
355 else:
356 fca = fcl.ancestor(fco, actx)
356 fca = fcl.ancestor(fco, actx)
357 if not fca:
357 if not fca:
358 fca = repo.filectx(f, fileid=nullrev)
358 fca = repo.filectx(f, fileid=nullrev)
359 ms.add(fcl, fco, fca, fd, flags)
359 ms.add(fcl, fco, fca, fd, flags)
360 if f != fd and move:
360 if f != fd and move:
361 moves.append(f)
361 moves.append(f)
362
362
363 audit = repo.wopener.audit
363 audit = repo.wopener.audit
364
364
365 # remove renamed files after safely stored
365 # remove renamed files after safely stored
366 for f in moves:
366 for f in moves:
367 if os.path.lexists(repo.wjoin(f)):
367 if os.path.lexists(repo.wjoin(f)):
368 repo.ui.debug("removing %s\n" % f)
368 repo.ui.debug("removing %s\n" % f)
369 audit(f)
369 audit(f)
370 util.unlinkpath(repo.wjoin(f))
370 util.unlinkpath(repo.wjoin(f))
371
371
372 numupdates = len(actions)
372 numupdates = len(actions)
373 for i, a in enumerate(actions):
373 for i, a in enumerate(actions):
374 f, m = a[:2]
374 f, m = a[:2]
375 repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates,
375 repo.ui.progress(_('updating'), i + 1, item=f, total=numupdates,
376 unit=_('files'))
376 unit=_('files'))
377 if f and f[0] == "/":
377 if f and f[0] == "/":
378 continue
378 continue
379 if m == "r": # remove
379 if m == "r": # remove
380 repo.ui.note(_("removing %s\n") % f)
380 repo.ui.note(_("removing %s\n") % f)
381 audit(f)
381 audit(f)
382 if f == '.hgsubstate': # subrepo states need updating
382 if f == '.hgsubstate': # subrepo states need updating
383 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
383 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
384 try:
384 try:
385 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
385 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
386 except OSError, inst:
386 except OSError, inst:
387 repo.ui.warn(_("update failed to remove %s: %s!\n") %
387 repo.ui.warn(_("update failed to remove %s: %s!\n") %
388 (f, inst.strerror))
388 (f, inst.strerror))
389 removed += 1
389 removed += 1
390 elif m == "m": # merge
390 elif m == "m": # merge
391 if fd == '.hgsubstate': # subrepo states need updating
391 if fd == '.hgsubstate': # subrepo states need updating
392 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
392 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
393 overwrite)
393 overwrite)
394 continue
394 continue
395 f2, fd, flags, move = a[2:]
395 f2, fd, flags, move = a[2:]
396 audit(fd)
396 audit(fd)
397 r = ms.resolve(fd, wctx, mctx)
397 r = ms.resolve(fd, wctx, mctx)
398 if r is not None and r > 0:
398 if r is not None and r > 0:
399 unresolved += 1
399 unresolved += 1
400 else:
400 else:
401 if r is None:
401 if r is None:
402 updated += 1
402 updated += 1
403 else:
403 else:
404 merged += 1
404 merged += 1
405 elif m == "g": # get
405 elif m == "g": # get
406 flags = a[2]
406 flags = a[2]
407 repo.ui.note(_("getting %s\n") % f)
407 repo.ui.note(_("getting %s\n") % f)
408 t = mctx.filectx(f).data()
408 t = mctx.filectx(f).data()
409 repo.wwrite(f, t, flags)
409 repo.wwrite(f, t, flags)
410 t = None
410 t = None
411 updated += 1
411 updated += 1
412 if f == '.hgsubstate': # subrepo states need updating
412 if f == '.hgsubstate': # subrepo states need updating
413 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
413 subrepo.submerge(repo, wctx, mctx, wctx, overwrite)
414 elif m == "d": # directory rename
414 elif m == "d": # directory rename
415 f2, fd, flags = a[2:]
415 f2, fd, flags = a[2:]
416 if f:
416 if f:
417 repo.ui.note(_("moving %s to %s\n") % (f, fd))
417 repo.ui.note(_("moving %s to %s\n") % (f, fd))
418 audit(f)
418 audit(f)
419 t = wctx.filectx(f).data()
419 t = wctx.filectx(f).data()
420 repo.wwrite(fd, t, flags)
420 repo.wwrite(fd, t, flags)
421 util.unlinkpath(repo.wjoin(f))
421 util.unlinkpath(repo.wjoin(f))
422 if f2:
422 if f2:
423 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
423 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
424 t = mctx.filectx(f2).data()
424 t = mctx.filectx(f2).data()
425 repo.wwrite(fd, t, flags)
425 repo.wwrite(fd, t, flags)
426 updated += 1
426 updated += 1
427 elif m == "dr": # divergent renames
427 elif m == "dr": # divergent renames
428 fl = a[2]
428 fl = a[2]
429 repo.ui.warn(_("note: possible conflict - %s was renamed "
429 repo.ui.warn(_("note: possible conflict - %s was renamed "
430 "multiple times to:\n") % f)
430 "multiple times to:\n") % f)
431 for nf in fl:
431 for nf in fl:
432 repo.ui.warn(" %s\n" % nf)
432 repo.ui.warn(" %s\n" % nf)
433 elif m == "rd": # rename and delete
433 elif m == "rd": # rename and delete
434 fl = a[2]
434 fl = a[2]
435 repo.ui.warn(_("note: possible conflict - %s was deleted "
435 repo.ui.warn(_("note: possible conflict - %s was deleted "
436 "and renamed to:\n") % f)
436 "and renamed to:\n") % f)
437 for nf in fl:
437 for nf in fl:
438 repo.ui.warn(" %s\n" % nf)
438 repo.ui.warn(" %s\n" % nf)
439 elif m == "e": # exec
439 elif m == "e": # exec
440 flags = a[2]
440 flags = a[2]
441 audit(f)
441 audit(f)
442 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
442 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags)
443 updated += 1
443 ms.commit()
444 ms.commit()
444 repo.ui.progress(_('updating'), None, total=numupdates, unit=_('files'))
445 repo.ui.progress(_('updating'), None, total=numupdates, unit=_('files'))
445
446
446 return updated, merged, removed, unresolved
447 return updated, merged, removed, unresolved
447
448
448 def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial):
449 def calculateupdates(repo, tctx, mctx, ancestor, branchmerge, force, partial):
449 "Calculate the actions needed to merge mctx into tctx"
450 "Calculate the actions needed to merge mctx into tctx"
450 actions = []
451 actions = []
451 folding = not util.checkcase(repo.path)
452 folding = not util.checkcase(repo.path)
452 if folding:
453 if folding:
453 # collision check is not needed for clean update
454 # collision check is not needed for clean update
454 if (not branchmerge and
455 if (not branchmerge and
455 (force or not tctx.dirty(missing=True, branch=False))):
456 (force or not tctx.dirty(missing=True, branch=False))):
456 _checkcollision(mctx, None)
457 _checkcollision(mctx, None)
457 else:
458 else:
458 _checkcollision(mctx, (tctx, ancestor))
459 _checkcollision(mctx, (tctx, ancestor))
459 if not force:
460 if not force:
460 _checkunknown(repo, tctx, mctx)
461 _checkunknown(repo, tctx, mctx)
461 if tctx.rev() is None:
462 if tctx.rev() is None:
462 actions += _forgetremoved(tctx, mctx, branchmerge)
463 actions += _forgetremoved(tctx, mctx, branchmerge)
463 actions += manifestmerge(repo, tctx, mctx,
464 actions += manifestmerge(repo, tctx, mctx,
464 ancestor,
465 ancestor,
465 force and not branchmerge,
466 force and not branchmerge,
466 partial)
467 partial)
467 return actions
468 return actions
468
469
469 def recordupdates(repo, actions, branchmerge):
470 def recordupdates(repo, actions, branchmerge):
470 "record merge actions to the dirstate"
471 "record merge actions to the dirstate"
471
472
472 for a in actions:
473 for a in actions:
473 f, m = a[:2]
474 f, m = a[:2]
474 if m == "r": # remove
475 if m == "r": # remove
475 if branchmerge:
476 if branchmerge:
476 repo.dirstate.remove(f)
477 repo.dirstate.remove(f)
477 else:
478 else:
478 repo.dirstate.drop(f)
479 repo.dirstate.drop(f)
479 elif m == "a": # re-add
480 elif m == "a": # re-add
480 if not branchmerge:
481 if not branchmerge:
481 repo.dirstate.add(f)
482 repo.dirstate.add(f)
482 elif m == "f": # forget
483 elif m == "f": # forget
483 repo.dirstate.drop(f)
484 repo.dirstate.drop(f)
484 elif m == "e": # exec change
485 elif m == "e": # exec change
485 repo.dirstate.normallookup(f)
486 repo.dirstate.normallookup(f)
486 elif m == "g": # get
487 elif m == "g": # get
487 if branchmerge:
488 if branchmerge:
488 repo.dirstate.otherparent(f)
489 repo.dirstate.otherparent(f)
489 else:
490 else:
490 repo.dirstate.normal(f)
491 repo.dirstate.normal(f)
491 elif m == "m": # merge
492 elif m == "m": # merge
492 f2, fd, flag, move = a[2:]
493 f2, fd, flag, move = a[2:]
493 if branchmerge:
494 if branchmerge:
494 # We've done a branch merge, mark this file as merged
495 # We've done a branch merge, mark this file as merged
495 # so that we properly record the merger later
496 # so that we properly record the merger later
496 repo.dirstate.merge(fd)
497 repo.dirstate.merge(fd)
497 if f != f2: # copy/rename
498 if f != f2: # copy/rename
498 if move:
499 if move:
499 repo.dirstate.remove(f)
500 repo.dirstate.remove(f)
500 if f != fd:
501 if f != fd:
501 repo.dirstate.copy(f, fd)
502 repo.dirstate.copy(f, fd)
502 else:
503 else:
503 repo.dirstate.copy(f2, fd)
504 repo.dirstate.copy(f2, fd)
504 else:
505 else:
505 # We've update-merged a locally modified file, so
506 # We've update-merged a locally modified file, so
506 # we set the dirstate to emulate a normal checkout
507 # we set the dirstate to emulate a normal checkout
507 # of that file some time in the past. Thus our
508 # of that file some time in the past. Thus our
508 # merge will appear as a normal local file
509 # merge will appear as a normal local file
509 # modification.
510 # modification.
510 if f2 == fd: # file not locally copied/moved
511 if f2 == fd: # file not locally copied/moved
511 repo.dirstate.normallookup(fd)
512 repo.dirstate.normallookup(fd)
512 if move:
513 if move:
513 repo.dirstate.drop(f)
514 repo.dirstate.drop(f)
514 elif m == "d": # directory rename
515 elif m == "d": # directory rename
515 f2, fd, flag = a[2:]
516 f2, fd, flag = a[2:]
516 if not f2 and f not in repo.dirstate:
517 if not f2 and f not in repo.dirstate:
517 # untracked file moved
518 # untracked file moved
518 continue
519 continue
519 if branchmerge:
520 if branchmerge:
520 repo.dirstate.add(fd)
521 repo.dirstate.add(fd)
521 if f:
522 if f:
522 repo.dirstate.remove(f)
523 repo.dirstate.remove(f)
523 repo.dirstate.copy(f, fd)
524 repo.dirstate.copy(f, fd)
524 if f2:
525 if f2:
525 repo.dirstate.copy(f2, fd)
526 repo.dirstate.copy(f2, fd)
526 else:
527 else:
527 repo.dirstate.normal(fd)
528 repo.dirstate.normal(fd)
528 if f:
529 if f:
529 repo.dirstate.drop(f)
530 repo.dirstate.drop(f)
530
531
531 def update(repo, node, branchmerge, force, partial, ancestor=None,
532 def update(repo, node, branchmerge, force, partial, ancestor=None,
532 mergeancestor=False):
533 mergeancestor=False):
533 """
534 """
534 Perform a merge between the working directory and the given node
535 Perform a merge between the working directory and the given node
535
536
536 node = the node to update to, or None if unspecified
537 node = the node to update to, or None if unspecified
537 branchmerge = whether to merge between branches
538 branchmerge = whether to merge between branches
538 force = whether to force branch merging or file overwriting
539 force = whether to force branch merging or file overwriting
539 partial = a function to filter file lists (dirstate not updated)
540 partial = a function to filter file lists (dirstate not updated)
540 mergeancestor = if false, merging with an ancestor (fast-forward)
541 mergeancestor = if false, merging with an ancestor (fast-forward)
541 is only allowed between different named branches. This flag
542 is only allowed between different named branches. This flag
542 is used by rebase extension as a temporary fix and should be
543 is used by rebase extension as a temporary fix and should be
543 avoided in general.
544 avoided in general.
544
545
545 The table below shows all the behaviors of the update command
546 The table below shows all the behaviors of the update command
546 given the -c and -C or no options, whether the working directory
547 given the -c and -C or no options, whether the working directory
547 is dirty, whether a revision is specified, and the relationship of
548 is dirty, whether a revision is specified, and the relationship of
548 the parent rev to the target rev (linear, on the same named
549 the parent rev to the target rev (linear, on the same named
549 branch, or on another named branch).
550 branch, or on another named branch).
550
551
551 This logic is tested by test-update-branches.t.
552 This logic is tested by test-update-branches.t.
552
553
553 -c -C dirty rev | linear same cross
554 -c -C dirty rev | linear same cross
554 n n n n | ok (1) x
555 n n n n | ok (1) x
555 n n n y | ok ok ok
556 n n n y | ok ok ok
556 n n y * | merge (2) (2)
557 n n y * | merge (2) (2)
557 n y * * | --- discard ---
558 n y * * | --- discard ---
558 y n y * | --- (3) ---
559 y n y * | --- (3) ---
559 y n n * | --- ok ---
560 y n n * | --- ok ---
560 y y * * | --- (4) ---
561 y y * * | --- (4) ---
561
562
562 x = can't happen
563 x = can't happen
563 * = don't-care
564 * = don't-care
564 1 = abort: crosses branches (use 'hg merge' or 'hg update -c')
565 1 = abort: crosses branches (use 'hg merge' or 'hg update -c')
565 2 = abort: crosses branches (use 'hg merge' to merge or
566 2 = abort: crosses branches (use 'hg merge' to merge or
566 use 'hg update -C' to discard changes)
567 use 'hg update -C' to discard changes)
567 3 = abort: uncommitted local changes
568 3 = abort: uncommitted local changes
568 4 = incompatible options (checked in commands.py)
569 4 = incompatible options (checked in commands.py)
569
570
570 Return the same tuple as applyupdates().
571 Return the same tuple as applyupdates().
571 """
572 """
572
573
573 onode = node
574 onode = node
574 wlock = repo.wlock()
575 wlock = repo.wlock()
575 try:
576 try:
576 wc = repo[None]
577 wc = repo[None]
577 if node is None:
578 if node is None:
578 # tip of current branch
579 # tip of current branch
579 try:
580 try:
580 node = repo.branchtip(wc.branch())
581 node = repo.branchtip(wc.branch())
581 except error.RepoLookupError:
582 except error.RepoLookupError:
582 if wc.branch() == "default": # no default branch!
583 if wc.branch() == "default": # no default branch!
583 node = repo.lookup("tip") # update to tip
584 node = repo.lookup("tip") # update to tip
584 else:
585 else:
585 raise util.Abort(_("branch %s not found") % wc.branch())
586 raise util.Abort(_("branch %s not found") % wc.branch())
586 overwrite = force and not branchmerge
587 overwrite = force and not branchmerge
587 pl = wc.parents()
588 pl = wc.parents()
588 p1, p2 = pl[0], repo[node]
589 p1, p2 = pl[0], repo[node]
589 if ancestor:
590 if ancestor:
590 pa = repo[ancestor]
591 pa = repo[ancestor]
591 else:
592 else:
592 pa = p1.ancestor(p2)
593 pa = p1.ancestor(p2)
593
594
594 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
595 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
595
596
596 ### check phase
597 ### check phase
597 if not overwrite and len(pl) > 1:
598 if not overwrite and len(pl) > 1:
598 raise util.Abort(_("outstanding uncommitted merges"))
599 raise util.Abort(_("outstanding uncommitted merges"))
599 if branchmerge:
600 if branchmerge:
600 if pa == p2:
601 if pa == p2:
601 raise util.Abort(_("merging with a working directory ancestor"
602 raise util.Abort(_("merging with a working directory ancestor"
602 " has no effect"))
603 " has no effect"))
603 elif pa == p1:
604 elif pa == p1:
604 if not mergeancestor and p1.branch() == p2.branch():
605 if not mergeancestor and p1.branch() == p2.branch():
605 raise util.Abort(_("nothing to merge"),
606 raise util.Abort(_("nothing to merge"),
606 hint=_("use 'hg update' "
607 hint=_("use 'hg update' "
607 "or check 'hg heads'"))
608 "or check 'hg heads'"))
608 if not force and (wc.files() or wc.deleted()):
609 if not force and (wc.files() or wc.deleted()):
609 raise util.Abort(_("outstanding uncommitted changes"),
610 raise util.Abort(_("outstanding uncommitted changes"),
610 hint=_("use 'hg status' to list changes"))
611 hint=_("use 'hg status' to list changes"))
611 for s in wc.substate:
612 for s in wc.substate:
612 if wc.sub(s).dirty():
613 if wc.sub(s).dirty():
613 raise util.Abort(_("outstanding uncommitted changes in "
614 raise util.Abort(_("outstanding uncommitted changes in "
614 "subrepository '%s'") % s)
615 "subrepository '%s'") % s)
615
616
616 elif not overwrite:
617 elif not overwrite:
617 if pa == p1 or pa == p2: # linear
618 if pa == p1 or pa == p2: # linear
618 pass # all good
619 pass # all good
619 elif wc.dirty(missing=True):
620 elif wc.dirty(missing=True):
620 raise util.Abort(_("crosses branches (merge branches or use"
621 raise util.Abort(_("crosses branches (merge branches or use"
621 " --clean to discard changes)"))
622 " --clean to discard changes)"))
622 elif onode is None:
623 elif onode is None:
623 raise util.Abort(_("crosses branches (merge branches or update"
624 raise util.Abort(_("crosses branches (merge branches or update"
624 " --check to force update)"))
625 " --check to force update)"))
625 else:
626 else:
626 # Allow jumping branches if clean and specific rev given
627 # Allow jumping branches if clean and specific rev given
627 pa = p1
628 pa = p1
628
629
629 ### calculate phase
630 ### calculate phase
630 actions = calculateupdates(repo, wc, p2, pa,
631 actions = calculateupdates(repo, wc, p2, pa,
631 branchmerge, force, partial)
632 branchmerge, force, partial)
632
633
633 ### apply phase
634 ### apply phase
634 if not branchmerge: # just jump to the new rev
635 if not branchmerge: # just jump to the new rev
635 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
636 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
636 if not partial:
637 if not partial:
637 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
638 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
638
639
639 stats = applyupdates(repo, actions, wc, p2, pa, overwrite)
640 stats = applyupdates(repo, actions, wc, p2, pa, overwrite)
640
641
641 if not partial:
642 if not partial:
642 repo.setparents(fp1, fp2)
643 repo.setparents(fp1, fp2)
643 recordupdates(repo, actions, branchmerge)
644 recordupdates(repo, actions, branchmerge)
644 if not branchmerge:
645 if not branchmerge:
645 repo.dirstate.setbranch(p2.branch())
646 repo.dirstate.setbranch(p2.branch())
646 finally:
647 finally:
647 wlock.release()
648 wlock.release()
648
649
649 if not partial:
650 if not partial:
650 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
651 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
651 return stats
652 return stats
@@ -1,28 +1,28
1 $ "$TESTDIR/hghave" execbit || exit 80
1 $ "$TESTDIR/hghave" execbit || exit 80
2
2
3 $ hg init
3 $ hg init
4 $ echo a > a
4 $ echo a > a
5 $ hg ci -Am'not executable'
5 $ hg ci -Am'not executable'
6 adding a
6 adding a
7
7
8 $ chmod +x a
8 $ chmod +x a
9 $ hg ci -m'executable'
9 $ hg ci -m'executable'
10 $ hg id
10 $ hg id
11 79abf14474dc tip
11 79abf14474dc tip
12
12
13 Make sure we notice the change of mode if the cached size == -1:
13 Make sure we notice the change of mode if the cached size == -1:
14
14
15 $ hg rm a
15 $ hg rm a
16 $ hg revert -r 0 a
16 $ hg revert -r 0 a
17 $ hg debugstate
17 $ hg debugstate
18 n 0 -1 unset a
18 n 0 -1 unset a
19 $ hg status
19 $ hg status
20 M a
20 M a
21
21
22 $ hg up 0
22 $ hg up 0
23 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 $ hg id
24 $ hg id
25 d69afc33ff8a
25 d69afc33ff8a
26 $ test -x a && echo executable -- bad || echo not executable -- good
26 $ test -x a && echo executable -- bad || echo not executable -- good
27 not executable -- good
27 not executable -- good
28
28
@@ -1,151 +1,151
1 $ "$TESTDIR/hghave" execbit || exit 80
1 $ "$TESTDIR/hghave" execbit || exit 80
2
2
3 $ umask 027
3 $ umask 027
4
4
5 $ hg init test1
5 $ hg init test1
6 $ cd test1
6 $ cd test1
7 $ touch a b
7 $ touch a b
8 $ hg add a b
8 $ hg add a b
9 $ hg ci -m "added a b"
9 $ hg ci -m "added a b"
10
10
11 $ cd ..
11 $ cd ..
12 $ hg clone test1 test3
12 $ hg clone test1 test3
13 updating to branch default
13 updating to branch default
14 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
15
15
16 $ hg init test2
16 $ hg init test2
17 $ cd test2
17 $ cd test2
18 $ hg pull ../test1
18 $ hg pull ../test1
19 pulling from ../test1
19 pulling from ../test1
20 requesting all changes
20 requesting all changes
21 adding changesets
21 adding changesets
22 adding manifests
22 adding manifests
23 adding file changes
23 adding file changes
24 added 1 changesets with 2 changes to 2 files
24 added 1 changesets with 2 changes to 2 files
25 (run 'hg update' to get a working copy)
25 (run 'hg update' to get a working copy)
26 $ hg co
26 $ hg co
27 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
27 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 $ chmod +x a
28 $ chmod +x a
29 $ hg ci -m "chmod +x a"
29 $ hg ci -m "chmod +x a"
30
30
31 the changelog should mention file a:
31 the changelog should mention file a:
32
32
33 $ hg tip --template '{files}\n'
33 $ hg tip --template '{files}\n'
34 a
34 a
35
35
36 $ cd ../test1
36 $ cd ../test1
37 $ echo 123 >>a
37 $ echo 123 >>a
38 $ hg ci -m "a updated"
38 $ hg ci -m "a updated"
39
39
40 $ hg pull ../test2
40 $ hg pull ../test2
41 pulling from ../test2
41 pulling from ../test2
42 searching for changes
42 searching for changes
43 adding changesets
43 adding changesets
44 adding manifests
44 adding manifests
45 adding file changes
45 adding file changes
46 added 1 changesets with 0 changes to 0 files (+1 heads)
46 added 1 changesets with 0 changes to 0 files (+1 heads)
47 (run 'hg heads' to see heads, 'hg merge' to merge)
47 (run 'hg heads' to see heads, 'hg merge' to merge)
48 $ hg heads
48 $ hg heads
49 changeset: 2:7f4313b42a34
49 changeset: 2:7f4313b42a34
50 tag: tip
50 tag: tip
51 parent: 0:22a449e20da5
51 parent: 0:22a449e20da5
52 user: test
52 user: test
53 date: Thu Jan 01 00:00:00 1970 +0000
53 date: Thu Jan 01 00:00:00 1970 +0000
54 summary: chmod +x a
54 summary: chmod +x a
55
55
56 changeset: 1:c6ecefc45368
56 changeset: 1:c6ecefc45368
57 user: test
57 user: test
58 date: Thu Jan 01 00:00:00 1970 +0000
58 date: Thu Jan 01 00:00:00 1970 +0000
59 summary: a updated
59 summary: a updated
60
60
61 $ hg history
61 $ hg history
62 changeset: 2:7f4313b42a34
62 changeset: 2:7f4313b42a34
63 tag: tip
63 tag: tip
64 parent: 0:22a449e20da5
64 parent: 0:22a449e20da5
65 user: test
65 user: test
66 date: Thu Jan 01 00:00:00 1970 +0000
66 date: Thu Jan 01 00:00:00 1970 +0000
67 summary: chmod +x a
67 summary: chmod +x a
68
68
69 changeset: 1:c6ecefc45368
69 changeset: 1:c6ecefc45368
70 user: test
70 user: test
71 date: Thu Jan 01 00:00:00 1970 +0000
71 date: Thu Jan 01 00:00:00 1970 +0000
72 summary: a updated
72 summary: a updated
73
73
74 changeset: 0:22a449e20da5
74 changeset: 0:22a449e20da5
75 user: test
75 user: test
76 date: Thu Jan 01 00:00:00 1970 +0000
76 date: Thu Jan 01 00:00:00 1970 +0000
77 summary: added a b
77 summary: added a b
78
78
79
79
80 $ hg -v merge
80 $ hg -v merge
81 resolving manifests
81 resolving manifests
82 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
82 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
83 (branch merge, don't forget to commit)
83 (branch merge, don't forget to commit)
84
84
85 $ cd ../test3
85 $ cd ../test3
86 $ echo 123 >>b
86 $ echo 123 >>b
87 $ hg ci -m "b updated"
87 $ hg ci -m "b updated"
88
88
89 $ hg pull ../test2
89 $ hg pull ../test2
90 pulling from ../test2
90 pulling from ../test2
91 searching for changes
91 searching for changes
92 adding changesets
92 adding changesets
93 adding manifests
93 adding manifests
94 adding file changes
94 adding file changes
95 added 1 changesets with 0 changes to 0 files (+1 heads)
95 added 1 changesets with 0 changes to 0 files (+1 heads)
96 (run 'hg heads' to see heads, 'hg merge' to merge)
96 (run 'hg heads' to see heads, 'hg merge' to merge)
97 $ hg heads
97 $ hg heads
98 changeset: 2:7f4313b42a34
98 changeset: 2:7f4313b42a34
99 tag: tip
99 tag: tip
100 parent: 0:22a449e20da5
100 parent: 0:22a449e20da5
101 user: test
101 user: test
102 date: Thu Jan 01 00:00:00 1970 +0000
102 date: Thu Jan 01 00:00:00 1970 +0000
103 summary: chmod +x a
103 summary: chmod +x a
104
104
105 changeset: 1:dc57ead75f79
105 changeset: 1:dc57ead75f79
106 user: test
106 user: test
107 date: Thu Jan 01 00:00:00 1970 +0000
107 date: Thu Jan 01 00:00:00 1970 +0000
108 summary: b updated
108 summary: b updated
109
109
110 $ hg history
110 $ hg history
111 changeset: 2:7f4313b42a34
111 changeset: 2:7f4313b42a34
112 tag: tip
112 tag: tip
113 parent: 0:22a449e20da5
113 parent: 0:22a449e20da5
114 user: test
114 user: test
115 date: Thu Jan 01 00:00:00 1970 +0000
115 date: Thu Jan 01 00:00:00 1970 +0000
116 summary: chmod +x a
116 summary: chmod +x a
117
117
118 changeset: 1:dc57ead75f79
118 changeset: 1:dc57ead75f79
119 user: test
119 user: test
120 date: Thu Jan 01 00:00:00 1970 +0000
120 date: Thu Jan 01 00:00:00 1970 +0000
121 summary: b updated
121 summary: b updated
122
122
123 changeset: 0:22a449e20da5
123 changeset: 0:22a449e20da5
124 user: test
124 user: test
125 date: Thu Jan 01 00:00:00 1970 +0000
125 date: Thu Jan 01 00:00:00 1970 +0000
126 summary: added a b
126 summary: added a b
127
127
128
128
129 $ hg -v merge
129 $ hg -v merge
130 resolving manifests
130 resolving manifests
131 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
131 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
132 (branch merge, don't forget to commit)
132 (branch merge, don't forget to commit)
133
133
134 $ ls -l ../test[123]/a > foo
134 $ ls -l ../test[123]/a > foo
135 $ cut -b 1-10 < foo
135 $ cut -b 1-10 < foo
136 -rwxr-x---
136 -rwxr-x---
137 -rwxr-x---
137 -rwxr-x---
138 -rwxr-x---
138 -rwxr-x---
139
139
140 $ hg debugindex a
140 $ hg debugindex a
141 rev offset length ..... linkrev nodeid p1 p2 (re)
141 rev offset length ..... linkrev nodeid p1 p2 (re)
142 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
142 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
143 $ hg debugindex -R ../test2 a
143 $ hg debugindex -R ../test2 a
144 rev offset length ..... linkrev nodeid p1 p2 (re)
144 rev offset length ..... linkrev nodeid p1 p2 (re)
145 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
145 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
146 $ hg debugindex -R ../test1 a
146 $ hg debugindex -R ../test1 a
147 rev offset length ..... linkrev nodeid p1 p2 (re)
147 rev offset length ..... linkrev nodeid p1 p2 (re)
148 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
148 0 0 0 ..... 0 b80de5d13875 000000000000 000000000000 (re)
149 1 0 5 ..... 1 7fe919cc0336 b80de5d13875 000000000000 (re)
149 1 0 5 ..... 1 7fe919cc0336 b80de5d13875 000000000000 (re)
150
150
151 $ cd ..
151 $ cd ..
@@ -1,1002 +1,1002
1 $ "$TESTDIR/hghave" serve || exit 80
1 $ "$TESTDIR/hghave" serve || exit 80
2
2
3 setting up repo
3 setting up repo
4
4
5 $ hg init test
5 $ hg init test
6 $ cd test
6 $ cd test
7 $ echo a > a
7 $ echo a > a
8 $ echo b > b
8 $ echo b > b
9 $ hg ci -Ama
9 $ hg ci -Ama
10 adding a
10 adding a
11 adding b
11 adding b
12
12
13 change permissions for git diffs
13 change permissions for git diffs
14
14
15 $ hg import -q --bypass - <<EOF
15 $ hg import -q --bypass - <<EOF
16 > # HG changeset patch
16 > # HG changeset patch
17 > # User test
17 > # User test
18 > # Date 0 0
18 > # Date 0 0
19 > b
19 > b
20 >
20 >
21 > diff --git a/a b/a
21 > diff --git a/a b/a
22 > old mode 100644
22 > old mode 100644
23 > new mode 100755
23 > new mode 100755
24 > diff --git a/b b/b
24 > diff --git a/b b/b
25 > deleted file mode 100644
25 > deleted file mode 100644
26 > --- a/b
26 > --- a/b
27 > +++ /dev/null
27 > +++ /dev/null
28 > @@ -1,1 +0,0 @@
28 > @@ -1,1 +0,0 @@
29 > -b
29 > -b
30 > EOF
30 > EOF
31
31
32 set up hgweb
32 set up hgweb
33
33
34 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
34 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
35 $ cat hg.pid >> $DAEMON_PIDS
35 $ cat hg.pid >> $DAEMON_PIDS
36
36
37 revision
37 revision
38
38
39 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'rev/0'
39 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'rev/0'
40 200 Script output follows
40 200 Script output follows
41
41
42 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
42 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
43 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
43 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
44 <head>
44 <head>
45 <link rel="icon" href="/static/hgicon.png" type="image/png" />
45 <link rel="icon" href="/static/hgicon.png" type="image/png" />
46 <meta name="robots" content="index, nofollow" />
46 <meta name="robots" content="index, nofollow" />
47 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
47 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
48 <script type="text/javascript" src="/static/mercurial.js"></script>
48 <script type="text/javascript" src="/static/mercurial.js"></script>
49
49
50 <title>test: 0cd96de13884</title>
50 <title>test: 0cd96de13884</title>
51 </head>
51 </head>
52 <body>
52 <body>
53 <div class="container">
53 <div class="container">
54 <div class="menu">
54 <div class="menu">
55 <div class="logo">
55 <div class="logo">
56 <a href="http://mercurial.selenic.com/">
56 <a href="http://mercurial.selenic.com/">
57 <img src="/static/hglogo.png" alt="mercurial" /></a>
57 <img src="/static/hglogo.png" alt="mercurial" /></a>
58 </div>
58 </div>
59 <ul>
59 <ul>
60 <li><a href="/shortlog/0cd96de13884">log</a></li>
60 <li><a href="/shortlog/0cd96de13884">log</a></li>
61 <li><a href="/graph/0cd96de13884">graph</a></li>
61 <li><a href="/graph/0cd96de13884">graph</a></li>
62 <li><a href="/tags">tags</a></li>
62 <li><a href="/tags">tags</a></li>
63 <li><a href="/bookmarks">bookmarks</a></li>
63 <li><a href="/bookmarks">bookmarks</a></li>
64 <li><a href="/branches">branches</a></li>
64 <li><a href="/branches">branches</a></li>
65 </ul>
65 </ul>
66 <ul>
66 <ul>
67 <li class="active">changeset</li>
67 <li class="active">changeset</li>
68 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
68 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
69 <li><a href="/file/0cd96de13884">browse</a></li>
69 <li><a href="/file/0cd96de13884">browse</a></li>
70 </ul>
70 </ul>
71 <ul>
71 <ul>
72
72
73 </ul>
73 </ul>
74 <ul>
74 <ul>
75 <li><a href="/help">help</a></li>
75 <li><a href="/help">help</a></li>
76 </ul>
76 </ul>
77 </div>
77 </div>
78
78
79 <div class="main">
79 <div class="main">
80
80
81 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
81 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
82 <h3>changeset 0:0cd96de13884 </h3>
82 <h3>changeset 0:0cd96de13884 </h3>
83
83
84 <form class="search" action="/log">
84 <form class="search" action="/log">
85
85
86 <p><input name="rev" id="search1" type="text" size="30" /></p>
86 <p><input name="rev" id="search1" type="text" size="30" /></p>
87 <div id="hint">find changesets by author, revision,
87 <div id="hint">find changesets by author, revision,
88 files, or words in the commit message</div>
88 files, or words in the commit message</div>
89 </form>
89 </form>
90
90
91 <div class="description">a</div>
91 <div class="description">a</div>
92
92
93 <table id="changesetEntry">
93 <table id="changesetEntry">
94 <tr>
94 <tr>
95 <th class="author">author</th>
95 <th class="author">author</th>
96 <td class="author">&#116;&#101;&#115;&#116;</td>
96 <td class="author">&#116;&#101;&#115;&#116;</td>
97 </tr>
97 </tr>
98 <tr>
98 <tr>
99 <th class="date">date</th>
99 <th class="date">date</th>
100 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
100 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
101 <tr>
101 <tr>
102 <th class="author">parents</th>
102 <th class="author">parents</th>
103 <td class="author"></td>
103 <td class="author"></td>
104 </tr>
104 </tr>
105 <tr>
105 <tr>
106 <th class="author">children</th>
106 <th class="author">children</th>
107 <td class="author"> <a href="/rev/559edbd9ed20">559edbd9ed20</a></td>
107 <td class="author"> <a href="/rev/559edbd9ed20">559edbd9ed20</a></td>
108 </tr>
108 </tr>
109 <tr>
109 <tr>
110 <th class="files">files</th>
110 <th class="files">files</th>
111 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
111 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
112 </tr>
112 </tr>
113 <tr>
113 <tr>
114 <th class="diffstat">diffstat</th>
114 <th class="diffstat">diffstat</th>
115 <td class="diffstat">
115 <td class="diffstat">
116 2 files changed, 2 insertions(+), 0 deletions(-)
116 2 files changed, 2 insertions(+), 0 deletions(-)
117
117
118 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
118 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
119 <div id="diffstatdetails" style="display:none;">
119 <div id="diffstatdetails" style="display:none;">
120 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
120 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
121 <p>
121 <p>
122 <table> <tr class="parity0">
122 <table> <tr class="parity0">
123 <td class="diffstat-file"><a href="#l1.1">a</a></td>
123 <td class="diffstat-file"><a href="#l1.1">a</a></td>
124 <td class="diffstat-total" align="right">1</td>
124 <td class="diffstat-total" align="right">1</td>
125 <td class="diffstat-graph">
125 <td class="diffstat-graph">
126 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
126 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
127 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
127 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
128 </td>
128 </td>
129 </tr>
129 </tr>
130 <tr class="parity1">
130 <tr class="parity1">
131 <td class="diffstat-file"><a href="#l2.1">b</a></td>
131 <td class="diffstat-file"><a href="#l2.1">b</a></td>
132 <td class="diffstat-total" align="right">1</td>
132 <td class="diffstat-total" align="right">1</td>
133 <td class="diffstat-graph">
133 <td class="diffstat-graph">
134 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
134 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
135 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
135 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
136 </td>
136 </td>
137 </tr>
137 </tr>
138 </table>
138 </table>
139 </div>
139 </div>
140 </td>
140 </td>
141 </tr>
141 </tr>
142 <tr>
142 <tr>
143 <th class="author">change baseline</th>
143 <th class="author">change baseline</th>
144 <td class="author"></td>
144 <td class="author"></td>
145 </tr>
145 </tr>
146 <tr>
146 <tr>
147 <th class="author">current baseline</th>
147 <th class="author">current baseline</th>
148 <td class="author"><a href="/rev/000000000000">000000000000</a></td>
148 <td class="author"><a href="/rev/000000000000">000000000000</a></td>
149 </tr>
149 </tr>
150 </table>
150 </table>
151
151
152 <div class="overflow">
152 <div class="overflow">
153 <div class="sourcefirst"> line diff</div>
153 <div class="sourcefirst"> line diff</div>
154
154
155 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
155 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
156 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000
156 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ b/a Thu Jan 01 00:00:00 1970 +0000
157 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
157 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -0,0 +1,1 @@
158 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+a
158 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="plusline">+a
159 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
159 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> <span class="minusline">--- /dev/null Thu Jan 01 00:00:00 1970 +0000
160 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/b Thu Jan 01 00:00:00 1970 +0000
160 </span><a href="#l2.2" id="l2.2"> 2.2</a> <span class="plusline">+++ b/b Thu Jan 01 00:00:00 1970 +0000
161 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
161 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="atline">@@ -0,0 +1,1 @@
162 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+b
162 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="plusline">+b
163 </span></pre></div>
163 </span></pre></div>
164 </div>
164 </div>
165
165
166 </div>
166 </div>
167 </div>
167 </div>
168 <script type="text/javascript">process_dates()</script>
168 <script type="text/javascript">process_dates()</script>
169
169
170
170
171 </body>
171 </body>
172 </html>
172 </html>
173
173
174
174
175 raw revision
175 raw revision
176
176
177 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
177 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
178 200 Script output follows
178 200 Script output follows
179
179
180
180
181 # HG changeset patch
181 # HG changeset patch
182 # User test
182 # User test
183 # Date 0 0
183 # Date 0 0
184 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
184 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
185
185
186 a
186 a
187
187
188 diff -r 000000000000 -r 0cd96de13884 a
188 diff -r 000000000000 -r 0cd96de13884 a
189 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
189 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
190 +++ b/a Thu Jan 01 00:00:00 1970 +0000
190 +++ b/a Thu Jan 01 00:00:00 1970 +0000
191 @@ -0,0 +1,1 @@
191 @@ -0,0 +1,1 @@
192 +a
192 +a
193 diff -r 000000000000 -r 0cd96de13884 b
193 diff -r 000000000000 -r 0cd96de13884 b
194 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
194 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
195 +++ b/b Thu Jan 01 00:00:00 1970 +0000
195 +++ b/b Thu Jan 01 00:00:00 1970 +0000
196 @@ -0,0 +1,1 @@
196 @@ -0,0 +1,1 @@
197 +b
197 +b
198
198
199
199
200 diff removed file
200 diff removed file
201
201
202 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'diff/tip/b'
202 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'diff/tip/b'
203 200 Script output follows
203 200 Script output follows
204
204
205 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
205 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
206 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
206 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
207 <head>
207 <head>
208 <link rel="icon" href="/static/hgicon.png" type="image/png" />
208 <link rel="icon" href="/static/hgicon.png" type="image/png" />
209 <meta name="robots" content="index, nofollow" />
209 <meta name="robots" content="index, nofollow" />
210 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
210 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
211 <script type="text/javascript" src="/static/mercurial.js"></script>
211 <script type="text/javascript" src="/static/mercurial.js"></script>
212
212
213 <title>test: b diff</title>
213 <title>test: b diff</title>
214 </head>
214 </head>
215 <body>
215 <body>
216
216
217 <div class="container">
217 <div class="container">
218 <div class="menu">
218 <div class="menu">
219 <div class="logo">
219 <div class="logo">
220 <a href="http://mercurial.selenic.com/">
220 <a href="http://mercurial.selenic.com/">
221 <img src="/static/hglogo.png" alt="mercurial" /></a>
221 <img src="/static/hglogo.png" alt="mercurial" /></a>
222 </div>
222 </div>
223 <ul>
223 <ul>
224 <li><a href="/shortlog/559edbd9ed20">log</a></li>
224 <li><a href="/shortlog/559edbd9ed20">log</a></li>
225 <li><a href="/graph/559edbd9ed20">graph</a></li>
225 <li><a href="/graph/559edbd9ed20">graph</a></li>
226 <li><a href="/tags">tags</a></li>
226 <li><a href="/tags">tags</a></li>
227 <li><a href="/bookmarks">bookmarks</a></li>
227 <li><a href="/bookmarks">bookmarks</a></li>
228 <li><a href="/branches">branches</a></li>
228 <li><a href="/branches">branches</a></li>
229 </ul>
229 </ul>
230 <ul>
230 <ul>
231 <li><a href="/rev/559edbd9ed20">changeset</a></li>
231 <li><a href="/rev/559edbd9ed20">changeset</a></li>
232 <li><a href="/file/559edbd9ed20">browse</a></li>
232 <li><a href="/file/559edbd9ed20">browse</a></li>
233 </ul>
233 </ul>
234 <ul>
234 <ul>
235 <li><a href="/file/559edbd9ed20/b">file</a></li>
235 <li><a href="/file/559edbd9ed20/b">file</a></li>
236 <li><a href="/file/tip/b">latest</a></li>
236 <li><a href="/file/tip/b">latest</a></li>
237 <li class="active">diff</li>
237 <li class="active">diff</li>
238 <li><a href="/comparison/559edbd9ed20/b">comparison</a></li>
238 <li><a href="/comparison/559edbd9ed20/b">comparison</a></li>
239 <li><a href="/annotate/559edbd9ed20/b">annotate</a></li>
239 <li><a href="/annotate/559edbd9ed20/b">annotate</a></li>
240 <li><a href="/log/559edbd9ed20/b">file log</a></li>
240 <li><a href="/log/559edbd9ed20/b">file log</a></li>
241 <li><a href="/raw-file/559edbd9ed20/b">raw</a></li>
241 <li><a href="/raw-file/559edbd9ed20/b">raw</a></li>
242 </ul>
242 </ul>
243 <ul>
243 <ul>
244 <li><a href="/help">help</a></li>
244 <li><a href="/help">help</a></li>
245 </ul>
245 </ul>
246 </div>
246 </div>
247
247
248 <div class="main">
248 <div class="main">
249 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
249 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
250 <h3>diff b @ 1:559edbd9ed20</h3>
250 <h3>diff b @ 1:559edbd9ed20</h3>
251
251
252 <form class="search" action="/log">
252 <form class="search" action="/log">
253 <p></p>
253 <p></p>
254 <p><input name="rev" id="search1" type="text" size="30" /></p>
254 <p><input name="rev" id="search1" type="text" size="30" /></p>
255 <div id="hint">find changesets by author, revision,
255 <div id="hint">find changesets by author, revision,
256 files, or words in the commit message</div>
256 files, or words in the commit message</div>
257 </form>
257 </form>
258
258
259 <div class="description">b</div>
259 <div class="description">b</div>
260
260
261 <table id="changesetEntry">
261 <table id="changesetEntry">
262 <tr>
262 <tr>
263 <th>author</th>
263 <th>author</th>
264 <td>&#116;&#101;&#115;&#116;</td>
264 <td>&#116;&#101;&#115;&#116;</td>
265 </tr>
265 </tr>
266 <tr>
266 <tr>
267 <th>date</th>
267 <th>date</th>
268 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
268 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
269 </tr>
269 </tr>
270 <tr>
270 <tr>
271 <th>parents</th>
271 <th>parents</th>
272 <td><a href="/file/0cd96de13884/b">0cd96de13884</a> </td>
272 <td><a href="/file/0cd96de13884/b">0cd96de13884</a> </td>
273 </tr>
273 </tr>
274 <tr>
274 <tr>
275 <th>children</th>
275 <th>children</th>
276 <td></td>
276 <td></td>
277 </tr>
277 </tr>
278
278
279 </table>
279 </table>
280
280
281 <div class="overflow">
281 <div class="overflow">
282 <div class="sourcefirst"> line diff</div>
282 <div class="sourcefirst"> line diff</div>
283
283
284 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- a/b Thu Jan 01 00:00:00 1970 +0000
284 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> <span class="minusline">--- a/b Thu Jan 01 00:00:00 1970 +0000
285 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
285 </span><a href="#l1.2" id="l1.2"> 1.2</a> <span class="plusline">+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
286 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -1,1 +0,0 @@
286 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="atline">@@ -1,1 +0,0 @@
287 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="minusline">-b
287 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="minusline">-b
288 </span></pre></div>
288 </span></pre></div>
289 </div>
289 </div>
290 </div>
290 </div>
291 </div>
291 </div>
292
292
293 <script type="text/javascript">process_dates()</script>
293 <script type="text/javascript">process_dates()</script>
294
294
295
295
296 </body>
296 </body>
297 </html>
297 </html>
298
298
299
299
300 set up hgweb with git diffs
300 set up hgweb with git diffs
301
301
302 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
302 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
303 $ hg serve --config 'diff.git=1' -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
303 $ hg serve --config 'diff.git=1' -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
304 $ cat hg.pid >> $DAEMON_PIDS
304 $ cat hg.pid >> $DAEMON_PIDS
305
305
306 revision
306 revision
307
307
308 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'rev/0'
308 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'rev/0'
309 200 Script output follows
309 200 Script output follows
310
310
311 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
311 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
312 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
312 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
313 <head>
313 <head>
314 <link rel="icon" href="/static/hgicon.png" type="image/png" />
314 <link rel="icon" href="/static/hgicon.png" type="image/png" />
315 <meta name="robots" content="index, nofollow" />
315 <meta name="robots" content="index, nofollow" />
316 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
316 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
317 <script type="text/javascript" src="/static/mercurial.js"></script>
317 <script type="text/javascript" src="/static/mercurial.js"></script>
318
318
319 <title>test: 0cd96de13884</title>
319 <title>test: 0cd96de13884</title>
320 </head>
320 </head>
321 <body>
321 <body>
322 <div class="container">
322 <div class="container">
323 <div class="menu">
323 <div class="menu">
324 <div class="logo">
324 <div class="logo">
325 <a href="http://mercurial.selenic.com/">
325 <a href="http://mercurial.selenic.com/">
326 <img src="/static/hglogo.png" alt="mercurial" /></a>
326 <img src="/static/hglogo.png" alt="mercurial" /></a>
327 </div>
327 </div>
328 <ul>
328 <ul>
329 <li><a href="/shortlog/0cd96de13884">log</a></li>
329 <li><a href="/shortlog/0cd96de13884">log</a></li>
330 <li><a href="/graph/0cd96de13884">graph</a></li>
330 <li><a href="/graph/0cd96de13884">graph</a></li>
331 <li><a href="/tags">tags</a></li>
331 <li><a href="/tags">tags</a></li>
332 <li><a href="/bookmarks">bookmarks</a></li>
332 <li><a href="/bookmarks">bookmarks</a></li>
333 <li><a href="/branches">branches</a></li>
333 <li><a href="/branches">branches</a></li>
334 </ul>
334 </ul>
335 <ul>
335 <ul>
336 <li class="active">changeset</li>
336 <li class="active">changeset</li>
337 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
337 <li><a href="/raw-rev/0cd96de13884">raw</a></li>
338 <li><a href="/file/0cd96de13884">browse</a></li>
338 <li><a href="/file/0cd96de13884">browse</a></li>
339 </ul>
339 </ul>
340 <ul>
340 <ul>
341
341
342 </ul>
342 </ul>
343 <ul>
343 <ul>
344 <li><a href="/help">help</a></li>
344 <li><a href="/help">help</a></li>
345 </ul>
345 </ul>
346 </div>
346 </div>
347
347
348 <div class="main">
348 <div class="main">
349
349
350 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
350 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
351 <h3>changeset 0:0cd96de13884 </h3>
351 <h3>changeset 0:0cd96de13884 </h3>
352
352
353 <form class="search" action="/log">
353 <form class="search" action="/log">
354
354
355 <p><input name="rev" id="search1" type="text" size="30" /></p>
355 <p><input name="rev" id="search1" type="text" size="30" /></p>
356 <div id="hint">find changesets by author, revision,
356 <div id="hint">find changesets by author, revision,
357 files, or words in the commit message</div>
357 files, or words in the commit message</div>
358 </form>
358 </form>
359
359
360 <div class="description">a</div>
360 <div class="description">a</div>
361
361
362 <table id="changesetEntry">
362 <table id="changesetEntry">
363 <tr>
363 <tr>
364 <th class="author">author</th>
364 <th class="author">author</th>
365 <td class="author">&#116;&#101;&#115;&#116;</td>
365 <td class="author">&#116;&#101;&#115;&#116;</td>
366 </tr>
366 </tr>
367 <tr>
367 <tr>
368 <th class="date">date</th>
368 <th class="date">date</th>
369 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
369 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td></tr>
370 <tr>
370 <tr>
371 <th class="author">parents</th>
371 <th class="author">parents</th>
372 <td class="author"></td>
372 <td class="author"></td>
373 </tr>
373 </tr>
374 <tr>
374 <tr>
375 <th class="author">children</th>
375 <th class="author">children</th>
376 <td class="author"> <a href="/rev/559edbd9ed20">559edbd9ed20</a></td>
376 <td class="author"> <a href="/rev/559edbd9ed20">559edbd9ed20</a></td>
377 </tr>
377 </tr>
378 <tr>
378 <tr>
379 <th class="files">files</th>
379 <th class="files">files</th>
380 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
380 <td class="files"><a href="/file/0cd96de13884/a">a</a> <a href="/file/0cd96de13884/b">b</a> </td>
381 </tr>
381 </tr>
382 <tr>
382 <tr>
383 <th class="diffstat">diffstat</th>
383 <th class="diffstat">diffstat</th>
384 <td class="diffstat">
384 <td class="diffstat">
385 2 files changed, 2 insertions(+), 0 deletions(-)
385 2 files changed, 2 insertions(+), 0 deletions(-)
386
386
387 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
387 <a id="diffstatexpand" href="javascript:showDiffstat()"/>[<tt>+</tt>]</a>
388 <div id="diffstatdetails" style="display:none;">
388 <div id="diffstatdetails" style="display:none;">
389 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
389 <a href="javascript:hideDiffstat()"/>[<tt>-</tt>]</a>
390 <p>
390 <p>
391 <table> <tr class="parity0">
391 <table> <tr class="parity0">
392 <td class="diffstat-file"><a href="#l1.1">a</a></td>
392 <td class="diffstat-file"><a href="#l1.1">a</a></td>
393 <td class="diffstat-total" align="right">1</td>
393 <td class="diffstat-total" align="right">1</td>
394 <td class="diffstat-graph">
394 <td class="diffstat-graph">
395 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
395 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
396 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
396 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
397 </td>
397 </td>
398 </tr>
398 </tr>
399 <tr class="parity1">
399 <tr class="parity1">
400 <td class="diffstat-file"><a href="#l2.1">b</a></td>
400 <td class="diffstat-file"><a href="#l2.1">b</a></td>
401 <td class="diffstat-total" align="right">1</td>
401 <td class="diffstat-total" align="right">1</td>
402 <td class="diffstat-graph">
402 <td class="diffstat-graph">
403 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
403 <span class="diffstat-add" style="width:100.0%;">&nbsp;</span>
404 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
404 <span class="diffstat-remove" style="width:0.0%;">&nbsp;</span>
405 </td>
405 </td>
406 </tr>
406 </tr>
407 </table>
407 </table>
408 </div>
408 </div>
409 </td>
409 </td>
410 </tr>
410 </tr>
411 <tr>
411 <tr>
412 <th class="author">change baseline</th>
412 <th class="author">change baseline</th>
413 <td class="author"></td>
413 <td class="author"></td>
414 </tr>
414 </tr>
415 <tr>
415 <tr>
416 <th class="author">current baseline</th>
416 <th class="author">current baseline</th>
417 <td class="author"><a href="/rev/000000000000">000000000000</a></td>
417 <td class="author"><a href="/rev/000000000000">000000000000</a></td>
418 </tr>
418 </tr>
419 </table>
419 </table>
420
420
421 <div class="overflow">
421 <div class="overflow">
422 <div class="sourcefirst"> line diff</div>
422 <div class="sourcefirst"> line diff</div>
423
423
424 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> new file mode 100644
424 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> new file mode 100644
425 <a href="#l1.2" id="l1.2"> 1.2</a> <span class="minusline">--- /dev/null
425 <a href="#l1.2" id="l1.2"> 1.2</a> <span class="minusline">--- /dev/null
426 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="plusline">+++ b/a
426 </span><a href="#l1.3" id="l1.3"> 1.3</a> <span class="plusline">+++ b/a
427 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="atline">@@ -0,0 +1,1 @@
427 </span><a href="#l1.4" id="l1.4"> 1.4</a> <span class="atline">@@ -0,0 +1,1 @@
428 </span><a href="#l1.5" id="l1.5"> 1.5</a> <span class="plusline">+a
428 </span><a href="#l1.5" id="l1.5"> 1.5</a> <span class="plusline">+a
429 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> new file mode 100644
429 </span></pre></div><div class="source bottomline parity1"><pre><a href="#l2.1" id="l2.1"> 2.1</a> new file mode 100644
430 <a href="#l2.2" id="l2.2"> 2.2</a> <span class="minusline">--- /dev/null
430 <a href="#l2.2" id="l2.2"> 2.2</a> <span class="minusline">--- /dev/null
431 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="plusline">+++ b/b
431 </span><a href="#l2.3" id="l2.3"> 2.3</a> <span class="plusline">+++ b/b
432 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="atline">@@ -0,0 +1,1 @@
432 </span><a href="#l2.4" id="l2.4"> 2.4</a> <span class="atline">@@ -0,0 +1,1 @@
433 </span><a href="#l2.5" id="l2.5"> 2.5</a> <span class="plusline">+b
433 </span><a href="#l2.5" id="l2.5"> 2.5</a> <span class="plusline">+b
434 </span></pre></div>
434 </span></pre></div>
435 </div>
435 </div>
436
436
437 </div>
437 </div>
438 </div>
438 </div>
439 <script type="text/javascript">process_dates()</script>
439 <script type="text/javascript">process_dates()</script>
440
440
441
441
442 </body>
442 </body>
443 </html>
443 </html>
444
444
445
445
446 revision
446 revision
447
447
448 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
448 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
449 200 Script output follows
449 200 Script output follows
450
450
451
451
452 # HG changeset patch
452 # HG changeset patch
453 # User test
453 # User test
454 # Date 0 0
454 # Date 0 0
455 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
455 # Node ID 0cd96de13884b090099512d4794ae87ad067ea8e
456
456
457 a
457 a
458
458
459 diff --git a/a b/a
459 diff --git a/a b/a
460 new file mode 100644
460 new file mode 100644
461 --- /dev/null
461 --- /dev/null
462 +++ b/a
462 +++ b/a
463 @@ -0,0 +1,1 @@
463 @@ -0,0 +1,1 @@
464 +a
464 +a
465 diff --git a/b b/b
465 diff --git a/b b/b
466 new file mode 100644
466 new file mode 100644
467 --- /dev/null
467 --- /dev/null
468 +++ b/b
468 +++ b/b
469 @@ -0,0 +1,1 @@
469 @@ -0,0 +1,1 @@
470 +b
470 +b
471
471
472
472
473 diff removed file
473 diff removed file
474
474
475 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'diff/tip/a'
475 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'diff/tip/a'
476 200 Script output follows
476 200 Script output follows
477
477
478 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
478 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
479 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
479 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
480 <head>
480 <head>
481 <link rel="icon" href="/static/hgicon.png" type="image/png" />
481 <link rel="icon" href="/static/hgicon.png" type="image/png" />
482 <meta name="robots" content="index, nofollow" />
482 <meta name="robots" content="index, nofollow" />
483 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
483 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
484 <script type="text/javascript" src="/static/mercurial.js"></script>
484 <script type="text/javascript" src="/static/mercurial.js"></script>
485
485
486 <title>test: a diff</title>
486 <title>test: a diff</title>
487 </head>
487 </head>
488 <body>
488 <body>
489
489
490 <div class="container">
490 <div class="container">
491 <div class="menu">
491 <div class="menu">
492 <div class="logo">
492 <div class="logo">
493 <a href="http://mercurial.selenic.com/">
493 <a href="http://mercurial.selenic.com/">
494 <img src="/static/hglogo.png" alt="mercurial" /></a>
494 <img src="/static/hglogo.png" alt="mercurial" /></a>
495 </div>
495 </div>
496 <ul>
496 <ul>
497 <li><a href="/shortlog/559edbd9ed20">log</a></li>
497 <li><a href="/shortlog/559edbd9ed20">log</a></li>
498 <li><a href="/graph/559edbd9ed20">graph</a></li>
498 <li><a href="/graph/559edbd9ed20">graph</a></li>
499 <li><a href="/tags">tags</a></li>
499 <li><a href="/tags">tags</a></li>
500 <li><a href="/bookmarks">bookmarks</a></li>
500 <li><a href="/bookmarks">bookmarks</a></li>
501 <li><a href="/branches">branches</a></li>
501 <li><a href="/branches">branches</a></li>
502 </ul>
502 </ul>
503 <ul>
503 <ul>
504 <li><a href="/rev/559edbd9ed20">changeset</a></li>
504 <li><a href="/rev/559edbd9ed20">changeset</a></li>
505 <li><a href="/file/559edbd9ed20">browse</a></li>
505 <li><a href="/file/559edbd9ed20">browse</a></li>
506 </ul>
506 </ul>
507 <ul>
507 <ul>
508 <li><a href="/file/559edbd9ed20/a">file</a></li>
508 <li><a href="/file/559edbd9ed20/a">file</a></li>
509 <li><a href="/file/tip/a">latest</a></li>
509 <li><a href="/file/tip/a">latest</a></li>
510 <li class="active">diff</li>
510 <li class="active">diff</li>
511 <li><a href="/comparison/559edbd9ed20/a">comparison</a></li>
511 <li><a href="/comparison/559edbd9ed20/a">comparison</a></li>
512 <li><a href="/annotate/559edbd9ed20/a">annotate</a></li>
512 <li><a href="/annotate/559edbd9ed20/a">annotate</a></li>
513 <li><a href="/log/559edbd9ed20/a">file log</a></li>
513 <li><a href="/log/559edbd9ed20/a">file log</a></li>
514 <li><a href="/raw-file/559edbd9ed20/a">raw</a></li>
514 <li><a href="/raw-file/559edbd9ed20/a">raw</a></li>
515 </ul>
515 </ul>
516 <ul>
516 <ul>
517 <li><a href="/help">help</a></li>
517 <li><a href="/help">help</a></li>
518 </ul>
518 </ul>
519 </div>
519 </div>
520
520
521 <div class="main">
521 <div class="main">
522 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
522 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
523 <h3>diff a @ 1:559edbd9ed20</h3>
523 <h3>diff a @ 1:559edbd9ed20</h3>
524
524
525 <form class="search" action="/log">
525 <form class="search" action="/log">
526 <p></p>
526 <p></p>
527 <p><input name="rev" id="search1" type="text" size="30" /></p>
527 <p><input name="rev" id="search1" type="text" size="30" /></p>
528 <div id="hint">find changesets by author, revision,
528 <div id="hint">find changesets by author, revision,
529 files, or words in the commit message</div>
529 files, or words in the commit message</div>
530 </form>
530 </form>
531
531
532 <div class="description">b</div>
532 <div class="description">b</div>
533
533
534 <table id="changesetEntry">
534 <table id="changesetEntry">
535 <tr>
535 <tr>
536 <th>author</th>
536 <th>author</th>
537 <td>&#116;&#101;&#115;&#116;</td>
537 <td>&#116;&#101;&#115;&#116;</td>
538 </tr>
538 </tr>
539 <tr>
539 <tr>
540 <th>date</th>
540 <th>date</th>
541 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
541 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
542 </tr>
542 </tr>
543 <tr>
543 <tr>
544 <th>parents</th>
544 <th>parents</th>
545 <td></td>
545 <td></td>
546 </tr>
546 </tr>
547 <tr>
547 <tr>
548 <th>children</th>
548 <th>children</th>
549 <td></td>
549 <td></td>
550 </tr>
550 </tr>
551
551
552 </table>
552 </table>
553
553
554 <div class="overflow">
554 <div class="overflow">
555 <div class="sourcefirst"> line diff</div>
555 <div class="sourcefirst"> line diff</div>
556
556
557 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> old mode 100644
557 <div class="source bottomline parity0"><pre><a href="#l1.1" id="l1.1"> 1.1</a> old mode 100644
558 <a href="#l1.2" id="l1.2"> 1.2</a> new mode 100755
558 <a href="#l1.2" id="l1.2"> 1.2</a> new mode 100755
559 </pre></div>
559 </pre></div>
560 </div>
560 </div>
561 </div>
561 </div>
562 </div>
562 </div>
563
563
564 <script type="text/javascript">process_dates()</script>
564 <script type="text/javascript">process_dates()</script>
565
565
566
566
567 </body>
567 </body>
568 </html>
568 </html>
569
569
570
570
571 comparison new file
571 comparison new file
572
572
573 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/0/a'
573 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/0/a'
574 200 Script output follows
574 200 Script output follows
575
575
576 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
576 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
577 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
577 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
578 <head>
578 <head>
579 <link rel="icon" href="/static/hgicon.png" type="image/png" />
579 <link rel="icon" href="/static/hgicon.png" type="image/png" />
580 <meta name="robots" content="index, nofollow" />
580 <meta name="robots" content="index, nofollow" />
581 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
581 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
582 <script type="text/javascript" src="/static/mercurial.js"></script>
582 <script type="text/javascript" src="/static/mercurial.js"></script>
583
583
584 <title>test: a comparison</title>
584 <title>test: a comparison</title>
585 </head>
585 </head>
586 <body>
586 <body>
587
587
588 <div class="container">
588 <div class="container">
589 <div class="menu">
589 <div class="menu">
590 <div class="logo">
590 <div class="logo">
591 <a href="http://mercurial.selenic.com/">
591 <a href="http://mercurial.selenic.com/">
592 <img src="/static/hglogo.png" alt="mercurial" /></a>
592 <img src="/static/hglogo.png" alt="mercurial" /></a>
593 </div>
593 </div>
594 <ul>
594 <ul>
595 <li><a href="/shortlog/0cd96de13884">log</a></li>
595 <li><a href="/shortlog/0cd96de13884">log</a></li>
596 <li><a href="/graph/0cd96de13884">graph</a></li>
596 <li><a href="/graph/0cd96de13884">graph</a></li>
597 <li><a href="/tags">tags</a></li>
597 <li><a href="/tags">tags</a></li>
598 <li><a href="/bookmarks">bookmarks</a></li>
598 <li><a href="/bookmarks">bookmarks</a></li>
599 <li><a href="/branches">branches</a></li>
599 <li><a href="/branches">branches</a></li>
600 </ul>
600 </ul>
601 <ul>
601 <ul>
602 <li><a href="/rev/0cd96de13884">changeset</a></li>
602 <li><a href="/rev/0cd96de13884">changeset</a></li>
603 <li><a href="/file/0cd96de13884">browse</a></li>
603 <li><a href="/file/0cd96de13884">browse</a></li>
604 </ul>
604 </ul>
605 <ul>
605 <ul>
606 <li><a href="/file/0cd96de13884/a">file</a></li>
606 <li><a href="/file/0cd96de13884/a">file</a></li>
607 <li><a href="/file/tip/a">latest</a></li>
607 <li><a href="/file/tip/a">latest</a></li>
608 <li><a href="/diff/0cd96de13884/a">diff</a></li>
608 <li><a href="/diff/0cd96de13884/a">diff</a></li>
609 <li class="active">comparison</li>
609 <li class="active">comparison</li>
610 <li><a href="/annotate/0cd96de13884/a">annotate</a></li>
610 <li><a href="/annotate/0cd96de13884/a">annotate</a></li>
611 <li><a href="/log/0cd96de13884/a">file log</a></li>
611 <li><a href="/log/0cd96de13884/a">file log</a></li>
612 <li><a href="/raw-file/0cd96de13884/a">raw</a></li>
612 <li><a href="/raw-file/0cd96de13884/a">raw</a></li>
613 </ul>
613 </ul>
614 <ul>
614 <ul>
615 <li><a href="/help">help</a></li>
615 <li><a href="/help">help</a></li>
616 </ul>
616 </ul>
617 </div>
617 </div>
618
618
619 <div class="main">
619 <div class="main">
620 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
620 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
621 <h3>comparison a @ 0:0cd96de13884</h3>
621 <h3>comparison a @ 0:0cd96de13884</h3>
622
622
623 <form class="search" action="/log">
623 <form class="search" action="/log">
624 <p></p>
624 <p></p>
625 <p><input name="rev" id="search1" type="text" size="30" /></p>
625 <p><input name="rev" id="search1" type="text" size="30" /></p>
626 <div id="hint">find changesets by author, revision,
626 <div id="hint">find changesets by author, revision,
627 files, or words in the commit message</div>
627 files, or words in the commit message</div>
628 </form>
628 </form>
629
629
630 <div class="description">a</div>
630 <div class="description">a</div>
631
631
632 <table id="changesetEntry">
632 <table id="changesetEntry">
633 <tr>
633 <tr>
634 <th>author</th>
634 <th>author</th>
635 <td>&#116;&#101;&#115;&#116;</td>
635 <td>&#116;&#101;&#115;&#116;</td>
636 </tr>
636 </tr>
637 <tr>
637 <tr>
638 <th>date</th>
638 <th>date</th>
639 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
639 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
640 </tr>
640 </tr>
641 <tr>
641 <tr>
642 <th>parents</th>
642 <th>parents</th>
643 <td></td>
643 <td></td>
644 </tr>
644 </tr>
645 <tr>
645 <tr>
646 <th>children</th>
646 <th>children</th>
647 <td></td>
647 <td></td>
648 </tr>
648 </tr>
649
649
650 </table>
650 </table>
651
651
652 <div class="overflow">
652 <div class="overflow">
653 <div class="sourcefirst"> comparison</div>
653 <div class="sourcefirst"> comparison</div>
654 <div class="legend">
654 <div class="legend">
655 <span class="legendinfo equal">equal</span>
655 <span class="legendinfo equal">equal</span>
656 <span class="legendinfo delete">deleted</span>
656 <span class="legendinfo delete">deleted</span>
657 <span class="legendinfo insert">inserted</span>
657 <span class="legendinfo insert">inserted</span>
658 <span class="legendinfo replace">replaced</span>
658 <span class="legendinfo replace">replaced</span>
659 </div>
659 </div>
660
660
661 <table class="bigtable">
661 <table class="bigtable">
662 <thead class="header">
662 <thead class="header">
663 <tr>
663 <tr>
664 <th>-1:000000000000</th>
664 <th>-1:000000000000</th>
665 <th>0:b789fdd96dc2</th>
665 <th>0:b789fdd96dc2</th>
666 </tr>
666 </tr>
667 </thead>
667 </thead>
668
668
669 <tbody class="block">
669 <tbody class="block">
670
670
671 <tr>
671 <tr>
672 <td class="source insert"><a href="#r1" id="r1"> </a> </td>
672 <td class="source insert"><a href="#r1" id="r1"> </a> </td>
673 <td class="source insert"><a href="#r1" id="r1"> 1</a> a</td>
673 <td class="source insert"><a href="#r1" id="r1"> 1</a> a</td>
674 </tr>
674 </tr>
675 </tbody>
675 </tbody>
676 </table>
676 </table>
677
677
678 </div>
678 </div>
679 </div>
679 </div>
680 </div>
680 </div>
681
681
682 <script type="text/javascript">process_dates()</script>
682 <script type="text/javascript">process_dates()</script>
683
683
684
684
685 </body>
685 </body>
686 </html>
686 </html>
687
687
688
688
689 comparison existing file
689 comparison existing file
690
690
691 $ hg up
691 $ hg up
692 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
692 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
693 $ echo a >> a
693 $ echo a >> a
694 $ hg ci -mc
694 $ hg ci -mc
695 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/tip/a'
695 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/tip/a'
696 200 Script output follows
696 200 Script output follows
697
697
698 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
698 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
699 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
699 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
700 <head>
700 <head>
701 <link rel="icon" href="/static/hgicon.png" type="image/png" />
701 <link rel="icon" href="/static/hgicon.png" type="image/png" />
702 <meta name="robots" content="index, nofollow" />
702 <meta name="robots" content="index, nofollow" />
703 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
703 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
704 <script type="text/javascript" src="/static/mercurial.js"></script>
704 <script type="text/javascript" src="/static/mercurial.js"></script>
705
705
706 <title>test: a comparison</title>
706 <title>test: a comparison</title>
707 </head>
707 </head>
708 <body>
708 <body>
709
709
710 <div class="container">
710 <div class="container">
711 <div class="menu">
711 <div class="menu">
712 <div class="logo">
712 <div class="logo">
713 <a href="http://mercurial.selenic.com/">
713 <a href="http://mercurial.selenic.com/">
714 <img src="/static/hglogo.png" alt="mercurial" /></a>
714 <img src="/static/hglogo.png" alt="mercurial" /></a>
715 </div>
715 </div>
716 <ul>
716 <ul>
717 <li><a href="/shortlog/d73db4d812ff">log</a></li>
717 <li><a href="/shortlog/d73db4d812ff">log</a></li>
718 <li><a href="/graph/d73db4d812ff">graph</a></li>
718 <li><a href="/graph/d73db4d812ff">graph</a></li>
719 <li><a href="/tags">tags</a></li>
719 <li><a href="/tags">tags</a></li>
720 <li><a href="/bookmarks">bookmarks</a></li>
720 <li><a href="/bookmarks">bookmarks</a></li>
721 <li><a href="/branches">branches</a></li>
721 <li><a href="/branches">branches</a></li>
722 </ul>
722 </ul>
723 <ul>
723 <ul>
724 <li><a href="/rev/d73db4d812ff">changeset</a></li>
724 <li><a href="/rev/d73db4d812ff">changeset</a></li>
725 <li><a href="/file/d73db4d812ff">browse</a></li>
725 <li><a href="/file/d73db4d812ff">browse</a></li>
726 </ul>
726 </ul>
727 <ul>
727 <ul>
728 <li><a href="/file/d73db4d812ff/a">file</a></li>
728 <li><a href="/file/d73db4d812ff/a">file</a></li>
729 <li><a href="/file/tip/a">latest</a></li>
729 <li><a href="/file/tip/a">latest</a></li>
730 <li><a href="/diff/d73db4d812ff/a">diff</a></li>
730 <li><a href="/diff/d73db4d812ff/a">diff</a></li>
731 <li class="active">comparison</li>
731 <li class="active">comparison</li>
732 <li><a href="/annotate/d73db4d812ff/a">annotate</a></li>
732 <li><a href="/annotate/d73db4d812ff/a">annotate</a></li>
733 <li><a href="/log/d73db4d812ff/a">file log</a></li>
733 <li><a href="/log/d73db4d812ff/a">file log</a></li>
734 <li><a href="/raw-file/d73db4d812ff/a">raw</a></li>
734 <li><a href="/raw-file/d73db4d812ff/a">raw</a></li>
735 </ul>
735 </ul>
736 <ul>
736 <ul>
737 <li><a href="/help">help</a></li>
737 <li><a href="/help">help</a></li>
738 </ul>
738 </ul>
739 </div>
739 </div>
740
740
741 <div class="main">
741 <div class="main">
742 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
742 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
743 <h3>comparison a @ 2:d73db4d812ff</h3>
743 <h3>comparison a @ 2:d73db4d812ff</h3>
744
744
745 <form class="search" action="/log">
745 <form class="search" action="/log">
746 <p></p>
746 <p></p>
747 <p><input name="rev" id="search1" type="text" size="30" /></p>
747 <p><input name="rev" id="search1" type="text" size="30" /></p>
748 <div id="hint">find changesets by author, revision,
748 <div id="hint">find changesets by author, revision,
749 files, or words in the commit message</div>
749 files, or words in the commit message</div>
750 </form>
750 </form>
751
751
752 <div class="description">c</div>
752 <div class="description">c</div>
753
753
754 <table id="changesetEntry">
754 <table id="changesetEntry">
755 <tr>
755 <tr>
756 <th>author</th>
756 <th>author</th>
757 <td>&#116;&#101;&#115;&#116;</td>
757 <td>&#116;&#101;&#115;&#116;</td>
758 </tr>
758 </tr>
759 <tr>
759 <tr>
760 <th>date</th>
760 <th>date</th>
761 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
761 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
762 </tr>
762 </tr>
763 <tr>
763 <tr>
764 <th>parents</th>
764 <th>parents</th>
765 <td><a href="/file/0cd96de13884/a">0cd96de13884</a> </td>
765 <td><a href="/file/0cd96de13884/a">0cd96de13884</a> </td>
766 </tr>
766 </tr>
767 <tr>
767 <tr>
768 <th>children</th>
768 <th>children</th>
769 <td></td>
769 <td></td>
770 </tr>
770 </tr>
771
771
772 </table>
772 </table>
773
773
774 <div class="overflow">
774 <div class="overflow">
775 <div class="sourcefirst"> comparison</div>
775 <div class="sourcefirst"> comparison</div>
776 <div class="legend">
776 <div class="legend">
777 <span class="legendinfo equal">equal</span>
777 <span class="legendinfo equal">equal</span>
778 <span class="legendinfo delete">deleted</span>
778 <span class="legendinfo delete">deleted</span>
779 <span class="legendinfo insert">inserted</span>
779 <span class="legendinfo insert">inserted</span>
780 <span class="legendinfo replace">replaced</span>
780 <span class="legendinfo replace">replaced</span>
781 </div>
781 </div>
782
782
783 <table class="bigtable">
783 <table class="bigtable">
784 <thead class="header">
784 <thead class="header">
785 <tr>
785 <tr>
786 <th>0:b789fdd96dc2</th>
786 <th>0:b789fdd96dc2</th>
787 <th>1:a80d06849b33</th>
787 <th>1:a80d06849b33</th>
788 </tr>
788 </tr>
789 </thead>
789 </thead>
790
790
791 <tbody class="block">
791 <tbody class="block">
792
792
793 <tr>
793 <tr>
794 <td class="source equal"><a href="#l1r1" id="l1r1"> 1</a> a</td>
794 <td class="source equal"><a href="#l1r1" id="l1r1"> 1</a> a</td>
795 <td class="source equal"><a href="#l1r1" id="l1r1"> 1</a> a</td>
795 <td class="source equal"><a href="#l1r1" id="l1r1"> 1</a> a</td>
796 </tr>
796 </tr>
797 <tr>
797 <tr>
798 <td class="source insert"><a href="#r2" id="r2"> </a> </td>
798 <td class="source insert"><a href="#r2" id="r2"> </a> </td>
799 <td class="source insert"><a href="#r2" id="r2"> 2</a> a</td>
799 <td class="source insert"><a href="#r2" id="r2"> 2</a> a</td>
800 </tr>
800 </tr>
801 </tbody>
801 </tbody>
802 </table>
802 </table>
803
803
804 </div>
804 </div>
805 </div>
805 </div>
806 </div>
806 </div>
807
807
808 <script type="text/javascript">process_dates()</script>
808 <script type="text/javascript">process_dates()</script>
809
809
810
810
811 </body>
811 </body>
812 </html>
812 </html>
813
813
814
814
815 comparison removed file
815 comparison removed file
816
816
817 $ hg rm a
817 $ hg rm a
818 $ hg ci -md
818 $ hg ci -md
819 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/tip/a'
819 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'comparison/tip/a'
820 200 Script output follows
820 200 Script output follows
821
821
822 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
822 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
823 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
823 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
824 <head>
824 <head>
825 <link rel="icon" href="/static/hgicon.png" type="image/png" />
825 <link rel="icon" href="/static/hgicon.png" type="image/png" />
826 <meta name="robots" content="index, nofollow" />
826 <meta name="robots" content="index, nofollow" />
827 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
827 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
828 <script type="text/javascript" src="/static/mercurial.js"></script>
828 <script type="text/javascript" src="/static/mercurial.js"></script>
829
829
830 <title>test: a comparison</title>
830 <title>test: a comparison</title>
831 </head>
831 </head>
832 <body>
832 <body>
833
833
834 <div class="container">
834 <div class="container">
835 <div class="menu">
835 <div class="menu">
836 <div class="logo">
836 <div class="logo">
837 <a href="http://mercurial.selenic.com/">
837 <a href="http://mercurial.selenic.com/">
838 <img src="/static/hglogo.png" alt="mercurial" /></a>
838 <img src="/static/hglogo.png" alt="mercurial" /></a>
839 </div>
839 </div>
840 <ul>
840 <ul>
841 <li><a href="/shortlog/20e80271eb7a">log</a></li>
841 <li><a href="/shortlog/20e80271eb7a">log</a></li>
842 <li><a href="/graph/20e80271eb7a">graph</a></li>
842 <li><a href="/graph/20e80271eb7a">graph</a></li>
843 <li><a href="/tags">tags</a></li>
843 <li><a href="/tags">tags</a></li>
844 <li><a href="/bookmarks">bookmarks</a></li>
844 <li><a href="/bookmarks">bookmarks</a></li>
845 <li><a href="/branches">branches</a></li>
845 <li><a href="/branches">branches</a></li>
846 </ul>
846 </ul>
847 <ul>
847 <ul>
848 <li><a href="/rev/20e80271eb7a">changeset</a></li>
848 <li><a href="/rev/20e80271eb7a">changeset</a></li>
849 <li><a href="/file/20e80271eb7a">browse</a></li>
849 <li><a href="/file/20e80271eb7a">browse</a></li>
850 </ul>
850 </ul>
851 <ul>
851 <ul>
852 <li><a href="/file/20e80271eb7a/a">file</a></li>
852 <li><a href="/file/20e80271eb7a/a">file</a></li>
853 <li><a href="/file/tip/a">latest</a></li>
853 <li><a href="/file/tip/a">latest</a></li>
854 <li><a href="/diff/20e80271eb7a/a">diff</a></li>
854 <li><a href="/diff/20e80271eb7a/a">diff</a></li>
855 <li class="active">comparison</li>
855 <li class="active">comparison</li>
856 <li><a href="/annotate/20e80271eb7a/a">annotate</a></li>
856 <li><a href="/annotate/20e80271eb7a/a">annotate</a></li>
857 <li><a href="/log/20e80271eb7a/a">file log</a></li>
857 <li><a href="/log/20e80271eb7a/a">file log</a></li>
858 <li><a href="/raw-file/20e80271eb7a/a">raw</a></li>
858 <li><a href="/raw-file/20e80271eb7a/a">raw</a></li>
859 </ul>
859 </ul>
860 <ul>
860 <ul>
861 <li><a href="/help">help</a></li>
861 <li><a href="/help">help</a></li>
862 </ul>
862 </ul>
863 </div>
863 </div>
864
864
865 <div class="main">
865 <div class="main">
866 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
866 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
867 <h3>comparison a @ 3:20e80271eb7a</h3>
867 <h3>comparison a @ 3:20e80271eb7a</h3>
868
868
869 <form class="search" action="/log">
869 <form class="search" action="/log">
870 <p></p>
870 <p></p>
871 <p><input name="rev" id="search1" type="text" size="30" /></p>
871 <p><input name="rev" id="search1" type="text" size="30" /></p>
872 <div id="hint">find changesets by author, revision,
872 <div id="hint">find changesets by author, revision,
873 files, or words in the commit message</div>
873 files, or words in the commit message</div>
874 </form>
874 </form>
875
875
876 <div class="description">d</div>
876 <div class="description">d</div>
877
877
878 <table id="changesetEntry">
878 <table id="changesetEntry">
879 <tr>
879 <tr>
880 <th>author</th>
880 <th>author</th>
881 <td>&#116;&#101;&#115;&#116;</td>
881 <td>&#116;&#101;&#115;&#116;</td>
882 </tr>
882 </tr>
883 <tr>
883 <tr>
884 <th>date</th>
884 <th>date</th>
885 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
885 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
886 </tr>
886 </tr>
887 <tr>
887 <tr>
888 <th>parents</th>
888 <th>parents</th>
889 <td><a href="/file/0cd96de13884/a">0cd96de13884</a> </td>
889 <td><a href="/file/0cd96de13884/a">0cd96de13884</a> </td>
890 </tr>
890 </tr>
891 <tr>
891 <tr>
892 <th>children</th>
892 <th>children</th>
893 <td></td>
893 <td></td>
894 </tr>
894 </tr>
895
895
896 </table>
896 </table>
897
897
898 <div class="overflow">
898 <div class="overflow">
899 <div class="sourcefirst"> comparison</div>
899 <div class="sourcefirst"> comparison</div>
900 <div class="legend">
900 <div class="legend">
901 <span class="legendinfo equal">equal</span>
901 <span class="legendinfo equal">equal</span>
902 <span class="legendinfo delete">deleted</span>
902 <span class="legendinfo delete">deleted</span>
903 <span class="legendinfo insert">inserted</span>
903 <span class="legendinfo insert">inserted</span>
904 <span class="legendinfo replace">replaced</span>
904 <span class="legendinfo replace">replaced</span>
905 </div>
905 </div>
906
906
907 <table class="bigtable">
907 <table class="bigtable">
908 <thead class="header">
908 <thead class="header">
909 <tr>
909 <tr>
910 <th>1:a80d06849b33</th>
910 <th>1:a80d06849b33</th>
911 <th>-1:000000000000</th>
911 <th>-1:000000000000</th>
912 </tr>
912 </tr>
913 </thead>
913 </thead>
914
914
915 <tbody class="block">
915 <tbody class="block">
916
916
917 <tr>
917 <tr>
918 <td class="source delete"><a href="#l1" id="l1"> 1</a> a</td>
918 <td class="source delete"><a href="#l1" id="l1"> 1</a> a</td>
919 <td class="source delete"><a href="#l1" id="l1"> </a> </td>
919 <td class="source delete"><a href="#l1" id="l1"> </a> </td>
920 </tr>
920 </tr>
921 <tr>
921 <tr>
922 <td class="source delete"><a href="#l2" id="l2"> 2</a> a</td>
922 <td class="source delete"><a href="#l2" id="l2"> 2</a> a</td>
923 <td class="source delete"><a href="#l2" id="l2"> </a> </td>
923 <td class="source delete"><a href="#l2" id="l2"> </a> </td>
924 </tr>
924 </tr>
925 </tbody>
925 </tbody>
926 </table>
926 </table>
927
927
928 </div>
928 </div>
929 </div>
929 </div>
930 </div>
930 </div>
931
931
932 <script type="text/javascript">process_dates()</script>
932 <script type="text/javascript">process_dates()</script>
933
933
934
934
935 </body>
935 </body>
936 </html>
936 </html>
937
937
938
938
939 $ cd ..
939 $ cd ..
940
940
941 test import rev as raw-rev
941 test import rev as raw-rev
942
942
943 $ hg clone -r0 test test1
943 $ hg clone -r0 test test1
944 adding changesets
944 adding changesets
945 adding manifests
945 adding manifests
946 adding file changes
946 adding file changes
947 added 1 changesets with 2 changes to 2 files
947 added 1 changesets with 2 changes to 2 files
948 updating to branch default
948 updating to branch default
949 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
949 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
950 $ cd test1
950 $ cd test1
951 $ hg import -q --bypass --exact http://localhost:$HGPORT/rev/1
951 $ hg import -q --bypass --exact http://localhost:$HGPORT/rev/1
952
952
953 raw revision with diff block numbers
953 raw revision with diff block numbers
954
954
955 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
955 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
956 $ cat <<EOF > .hg/hgrc
956 $ cat <<EOF > .hg/hgrc
957 > [web]
957 > [web]
958 > templates = rawdiff
958 > templates = rawdiff
959 > EOF
959 > EOF
960 $ mkdir rawdiff
960 $ mkdir rawdiff
961 $ cat <<EOF > rawdiff/map
961 $ cat <<EOF > rawdiff/map
962 > mimetype = 'text/plain; charset={encoding}'
962 > mimetype = 'text/plain; charset={encoding}'
963 > changeset = '{diff}'
963 > changeset = '{diff}'
964 > difflineplus = '{line}'
964 > difflineplus = '{line}'
965 > difflineminus = '{line}'
965 > difflineminus = '{line}'
966 > difflineat = '{line}'
966 > difflineat = '{line}'
967 > diffline = '{line}'
967 > diffline = '{line}'
968 > filenodelink = ''
968 > filenodelink = ''
969 > filenolink = ''
969 > filenolink = ''
970 > fileline = '{line}'
970 > fileline = '{line}'
971 > diffblock = 'Block: {blockno}\n{lines}\n'
971 > diffblock = 'Block: {blockno}\n{lines}\n'
972 > EOF
972 > EOF
973 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
973 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
974 $ cat hg.pid >> $DAEMON_PIDS
974 $ cat hg.pid >> $DAEMON_PIDS
975 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
975 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'raw-rev/0'
976 200 Script output follows
976 200 Script output follows
977
977
978 Block: 1
978 Block: 1
979 diff -r 000000000000 -r 0cd96de13884 a
979 diff -r 000000000000 -r 0cd96de13884 a
980 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
980 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
981 +++ b/a Thu Jan 01 00:00:00 1970 +0000
981 +++ b/a Thu Jan 01 00:00:00 1970 +0000
982 @@ -0,0 +1,1 @@
982 @@ -0,0 +1,1 @@
983 +a
983 +a
984
984
985 Block: 2
985 Block: 2
986 diff -r 000000000000 -r 0cd96de13884 b
986 diff -r 000000000000 -r 0cd96de13884 b
987 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
987 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
988 +++ b/b Thu Jan 01 00:00:00 1970 +0000
988 +++ b/b Thu Jan 01 00:00:00 1970 +0000
989 @@ -0,0 +1,1 @@
989 @@ -0,0 +1,1 @@
990 +b
990 +b
991
991
992 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
992 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
993 $ rm .hg/hgrc rawdiff/map
993 $ rm .hg/hgrc rawdiff/map
994 $ rmdir rawdiff
994 $ rmdir rawdiff
995 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
995 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
996 $ cat hg.pid >> $DAEMON_PIDS
996 $ cat hg.pid >> $DAEMON_PIDS
997
997
998 errors
998 errors
999
999
1000 $ cat ../test/errors.log
1000 $ cat ../test/errors.log
1001
1001
1002 $ cd ..
1002 $ cd ..
@@ -1,73 +1,73
1 $ "$TESTDIR/hghave" execbit || exit 80
1 $ "$TESTDIR/hghave" execbit || exit 80
2
2
3 Create extension that can disable exec checks:
3 Create extension that can disable exec checks:
4
4
5 $ cat > noexec.py <<EOF
5 $ cat > noexec.py <<EOF
6 > from mercurial import extensions, util
6 > from mercurial import extensions, util
7 > def setflags(orig, f, l, x):
7 > def setflags(orig, f, l, x):
8 > pass
8 > pass
9 > def checkexec(orig, path):
9 > def checkexec(orig, path):
10 > return False
10 > return False
11 > def extsetup(ui):
11 > def extsetup(ui):
12 > extensions.wrapfunction(util, 'setflags', setflags)
12 > extensions.wrapfunction(util, 'setflags', setflags)
13 > extensions.wrapfunction(util, 'checkexec', checkexec)
13 > extensions.wrapfunction(util, 'checkexec', checkexec)
14 > EOF
14 > EOF
15
15
16 $ hg init unix-repo
16 $ hg init unix-repo
17 $ cd unix-repo
17 $ cd unix-repo
18 $ touch a
18 $ touch a
19 $ hg add a
19 $ hg add a
20 $ hg commit -m 'unix: add a'
20 $ hg commit -m 'unix: add a'
21 $ hg clone . ../win-repo
21 $ hg clone . ../win-repo
22 updating to branch default
22 updating to branch default
23 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
23 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 $ chmod +x a
24 $ chmod +x a
25 $ hg commit -m 'unix: chmod a'
25 $ hg commit -m 'unix: chmod a'
26 $ hg manifest -v
26 $ hg manifest -v
27 755 * a
27 755 * a
28
28
29 $ cd ../win-repo
29 $ cd ../win-repo
30
30
31 $ touch b
31 $ touch b
32 $ hg add b
32 $ hg add b
33 $ hg commit -m 'win: add b'
33 $ hg commit -m 'win: add b'
34
34
35 $ hg manifest -v
35 $ hg manifest -v
36 644 a
36 644 a
37 644 b
37 644 b
38
38
39 $ hg pull
39 $ hg pull
40 pulling from $TESTTMP/unix-repo
40 pulling from $TESTTMP/unix-repo
41 searching for changes
41 searching for changes
42 adding changesets
42 adding changesets
43 adding manifests
43 adding manifests
44 adding file changes
44 adding file changes
45 added 1 changesets with 0 changes to 0 files (+1 heads)
45 added 1 changesets with 0 changes to 0 files (+1 heads)
46 (run 'hg heads' to see heads, 'hg merge' to merge)
46 (run 'hg heads' to see heads, 'hg merge' to merge)
47
47
48 $ hg manifest -v -r tip
48 $ hg manifest -v -r tip
49 755 * a
49 755 * a
50
50
51 Simulate a Windows merge:
51 Simulate a Windows merge:
52
52
53 $ hg --config extensions.n=$TESTTMP/noexec.py merge --debug
53 $ hg --config extensions.n=$TESTTMP/noexec.py merge --debug
54 searching for copies back to rev 1
54 searching for copies back to rev 1
55 unmatched files in local:
55 unmatched files in local:
56 b
56 b
57 resolving manifests
57 resolving manifests
58 overwrite: False, partial: False
58 overwrite: False, partial: False
59 ancestor: a03b0deabf2b, local: d6fa54f68ae1+, remote: 2d8bcf2dda39
59 ancestor: a03b0deabf2b, local: d6fa54f68ae1+, remote: 2d8bcf2dda39
60 a: update permissions -> e
60 a: update permissions -> e
61 updating: a 1/1 files (100.00%)
61 updating: a 1/1 files (100.00%)
62 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 (branch merge, don't forget to commit)
63 (branch merge, don't forget to commit)
64
64
65 Simulate a Windows commit:
65 Simulate a Windows commit:
66
66
67 $ hg --config extensions.n=$TESTTMP/noexec.py commit -m 'win: merge'
67 $ hg --config extensions.n=$TESTTMP/noexec.py commit -m 'win: merge'
68
68
69 $ hg manifest -v
69 $ hg manifest -v
70 755 * a
70 755 * a
71 644 b
71 644 b
72
72
73 $ cd ..
73 $ cd ..
@@ -1,110 +1,110
1 $ "$TESTDIR/hghave" symlink execbit || exit 80
1 $ "$TESTDIR/hghave" symlink execbit || exit 80
2
2
3 $ hg init
3 $ hg init
4
4
5 $ echo a > a
5 $ echo a > a
6 $ hg ci -Amadd
6 $ hg ci -Amadd
7 adding a
7 adding a
8
8
9 $ chmod +x a
9 $ chmod +x a
10 $ hg ci -mexecutable
10 $ hg ci -mexecutable
11
11
12 $ hg up 0
12 $ hg up 0
13 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 $ rm a
14 $ rm a
15 $ ln -s symlink a
15 $ ln -s symlink a
16 $ hg ci -msymlink
16 $ hg ci -msymlink
17 created new head
17 created new head
18
18
19 $ hg merge --debug
19 $ hg merge --debug
20 searching for copies back to rev 1
20 searching for copies back to rev 1
21 resolving manifests
21 resolving manifests
22 overwrite: False, partial: False
22 overwrite: False, partial: False
23 ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c
23 ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c
24 conflicting flags for a
24 conflicting flags for a
25 (n)one, e(x)ec or sym(l)ink? n
25 (n)one, e(x)ec or sym(l)ink? n
26 a: update permissions -> e
26 a: update permissions -> e
27 updating: a 1/1 files (100.00%)
27 updating: a 1/1 files (100.00%)
28 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
29 (branch merge, don't forget to commit)
29 (branch merge, don't forget to commit)
30
30
31
31
32 Symlink is local parent, executable is other:
32 Symlink is local parent, executable is other:
33
33
34 $ if [ -h a ]; then
34 $ if [ -h a ]; then
35 > echo a is a symlink
35 > echo a is a symlink
36 > $TESTDIR/readlink.py a
36 > $TESTDIR/readlink.py a
37 > elif [ -x a ]; then
37 > elif [ -x a ]; then
38 > echo a is executable
38 > echo a is executable
39 > else
39 > else
40 > echo "a has no flags (default for conflicts)"
40 > echo "a has no flags (default for conflicts)"
41 > fi
41 > fi
42 a has no flags (default for conflicts)
42 a has no flags (default for conflicts)
43
43
44 $ hg update -C 1
44 $ hg update -C 1
45 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
46
46
47 $ hg merge --debug
47 $ hg merge --debug
48 searching for copies back to rev 1
48 searching for copies back to rev 1
49 resolving manifests
49 resolving manifests
50 overwrite: False, partial: False
50 overwrite: False, partial: False
51 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
51 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
52 conflicting flags for a
52 conflicting flags for a
53 (n)one, e(x)ec or sym(l)ink? n
53 (n)one, e(x)ec or sym(l)ink? n
54 a: remote is newer -> g
54 a: remote is newer -> g
55 updating: a 1/1 files (100.00%)
55 updating: a 1/1 files (100.00%)
56 getting a
56 getting a
57 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
58 (branch merge, don't forget to commit)
58 (branch merge, don't forget to commit)
59
59
60
60
61 Symlink is other parent, executable is local:
61 Symlink is other parent, executable is local:
62
62
63 $ if [ -h a ]; then
63 $ if [ -h a ]; then
64 > echo a is a symlink
64 > echo a is a symlink
65 > $TESTDIR/readlink.py a
65 > $TESTDIR/readlink.py a
66 > elif [ -x a ]; then
66 > elif [ -x a ]; then
67 > echo a is executable
67 > echo a is executable
68 > else
68 > else
69 > echo "a has no flags (default for conflicts)"
69 > echo "a has no flags (default for conflicts)"
70 > fi
70 > fi
71 a has no flags (default for conflicts)
71 a has no flags (default for conflicts)
72
72
73 Update to link without local change should get us a symlink (issue3316):
73 Update to link without local change should get us a symlink (issue3316):
74
74
75 $ hg up -C 0
75 $ hg up -C 0
76 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
76 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 $ hg up
77 $ hg up
78 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 $ hg st
79 $ hg st
80
80
81 Update to link with local change should cause a merge prompt (issue3200):
81 Update to link with local change should cause a merge prompt (issue3200):
82
82
83 $ hg up -C 0
83 $ hg up -C 0
84 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
84 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
85 $ echo data > a
85 $ echo data > a
86 $ HGMERGE= hg up -y --debug
86 $ HGMERGE= hg up -y --debug
87 searching for copies back to rev 2
87 searching for copies back to rev 2
88 resolving manifests
88 resolving manifests
89 overwrite: False, partial: False
89 overwrite: False, partial: False
90 ancestor: c334dc3be0da, local: c334dc3be0da+, remote: 521a1e40188f
90 ancestor: c334dc3be0da, local: c334dc3be0da+, remote: 521a1e40188f
91 a: versions differ -> m
91 a: versions differ -> m
92 preserving a for resolve of a
92 preserving a for resolve of a
93 updating: a 1/1 files (100.00%)
93 updating: a 1/1 files (100.00%)
94 (couldn't find merge tool hgmerge|tool hgmerge can't handle symlinks) (re)
94 (couldn't find merge tool hgmerge|tool hgmerge can't handle symlinks) (re)
95 picked tool 'internal:prompt' for a (binary False symlink True)
95 picked tool 'internal:prompt' for a (binary False symlink True)
96 no tool found to merge a
96 no tool found to merge a
97 keep (l)ocal or take (o)ther? l
97 keep (l)ocal or take (o)ther? l
98 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
98 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
99 $ hg diff --git
99 $ hg diff --git
100 diff --git a/a b/a
100 diff --git a/a b/a
101 old mode 120000
101 old mode 120000
102 new mode 100644
102 new mode 100644
103 --- a/a
103 --- a/a
104 +++ b/a
104 +++ b/a
105 @@ -1,1 +1,1 @@
105 @@ -1,1 +1,1 @@
106 -symlink
106 -symlink
107 \ No newline at end of file
107 \ No newline at end of file
108 +data
108 +data
109
109
110
110
@@ -1,36 +1,36
1 $ "$TESTDIR/hghave" execbit || exit 80
1 $ "$TESTDIR/hghave" execbit || exit 80
2
2
3 $ rm -rf a
3 $ rm -rf a
4 $ hg init a
4 $ hg init a
5 $ cd a
5 $ cd a
6
6
7 $ echo foo > foo
7 $ echo foo > foo
8 $ hg ci -qAm0
8 $ hg ci -qAm0
9 $ chmod +x foo
9 $ chmod +x foo
10 $ hg ci -m1
10 $ hg ci -m1
11 $ hg co -q 0
11 $ hg co -q 0
12 $ echo dirty > foo
12 $ echo dirty > foo
13 $ hg up -c
13 $ hg up -c
14 abort: uncommitted local changes
14 abort: uncommitted local changes
15 [255]
15 [255]
16 $ hg up -q
16 $ hg up -q
17 $ cat foo
17 $ cat foo
18 dirty
18 dirty
19 $ hg st -A
19 $ hg st -A
20 M foo
20 M foo
21
21
22 Validate update of standalone execute bit change:
22 Validate update of standalone execute bit change:
23
23
24 $ hg up -C 0
24 $ hg up -C 0
25 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
26 $ chmod -x foo
26 $ chmod -x foo
27 $ hg ci -m removeexec
27 $ hg ci -m removeexec
28 nothing changed
28 nothing changed
29 [1]
29 [1]
30 $ hg up -C 0
30 $ hg up -C 0
31 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
31 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
32 $ hg up
32 $ hg up
33 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 $ hg st
34 $ hg st
35
35
36 $ cd ..
36 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now