annotate mercurial/hg.py @ 276:10e325db7347

add tracking of execute permissions -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 add tracking of execute permissions Changes to executable permissions are now tracked. We only track one bit here as the others tends to be problematic. "hg manifest" now shows file permissions. manifest hash: b76b85d12a9550fdc9fbc4f9446a812f3a2bbe88 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCpzYBywK+sNU5EO8RAgkMAJ48l2ac12E20EFS24/i8ScwOtG4HwCgkbaE ue6l1RJroqzNA7vNeqwCwK4= =sEmJ -----END PGP SIGNATURE-----
author mpm@selenic.com
date Wed, 08 Jun 2005 10:16:33 -0800
parents 61d45b0ba8fb
children 79279550c8ff
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1 # hg.py - repository classes for mercurial
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
2 #
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
4 #
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
5 # This software may be used and distributed according to the terms
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
6 # of the GNU General Public License, incorporated herein by reference.
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
7
249
619e775aa7f9 import and startup cleanups
mpm@selenic.com
parents: 247
diff changeset
8 import sys, struct, os
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
9 from revlog import *
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
10 from demandload import *
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
11 demandload(globals(), "re lock urllib urllib2 transaction time socket")
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
12 demandload(globals(), "tempfile byterange difflib")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
13
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
14 def is_exec(f):
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
15 return (os.stat(f).st_mode & 0100 != 0)
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
16
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
17 def set_exec(f, mode):
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
18 s = os.stat(f).st_mode
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
19 if (s & 0100 != 0) == mode:
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
20 return
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
21 os.chmod(f, s & 0666 | (mode * 0111))
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
22
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
23 class filelog(revlog):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
24 def __init__(self, opener, path):
144
ea9188538222 Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents: 140
diff changeset
25 revlog.__init__(self, opener,
ea9188538222 Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents: 140
diff changeset
26 os.path.join("data", path + ".i"),
ea9188538222 Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents: 140
diff changeset
27 os.path.join("data", path + ".d"))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
28
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
29 def read(self, node):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
30 return self.revision(node)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
31 def add(self, text, transaction, link, p1=None, p2=None):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
32 return self.addrevision(text, transaction, link, p1, p2)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
33
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
34 def annotate(self, node):
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
35
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
36 def decorate(text, rev):
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
37 return [(rev, l) for l in text.splitlines(1)]
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
38
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
39 def strip(annotation):
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
40 return [e[1] for e in annotation]
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
41
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
42 def pair(parent, child):
109
95699294f580 Annotate was being too clever trying to work in place, and triggering
mpm@selenic.com
parents: 107
diff changeset
43 new = []
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
44 sm = difflib.SequenceMatcher(None, strip(parent), strip(child))
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
45 for o, m, n, s, t in sm.get_opcodes():
109
95699294f580 Annotate was being too clever trying to work in place, and triggering
mpm@selenic.com
parents: 107
diff changeset
46 if o == 'equal':
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
47 new += parent[m:n]
109
95699294f580 Annotate was being too clever trying to work in place, and triggering
mpm@selenic.com
parents: 107
diff changeset
48 else:
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
49 new += child[s:t]
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
50 return new
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
51
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
52 # find all ancestors
216
201115f2859b hg annotate: actually annotate the given version
mpm@selenic.com
parents: 210
diff changeset
53 needed = {node:1}
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
54 visit = [node]
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
55 while visit:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
56 n = visit.pop(0)
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
57 for p in self.parents(n):
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
58 if p not in needed:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
59 needed[p] = 1
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
60 visit.append(p)
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
61 else:
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
62 # count how many times we'll use this
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
63 needed[p] += 1
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
64
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
65 # sort by revision which is a topological order
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
66 visit = needed.keys()
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
67 visit = [ (self.rev(n), n) for n in visit ]
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
68 visit.sort()
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
69 visit = [ p[1] for p in visit ]
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
70 hist = {}
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
71
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
72 for n in visit:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
73 curr = decorate(self.read(n), self.linkrev(n))
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
74 for p in self.parents(n):
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
75 if p != nullid:
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
76 curr = pair(hist[p], curr)
200
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
77 # trim the history of unneeded revs
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
78 needed[p] -= 1
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
79 if not needed[p]:
8450c18f2a45 annotate: memory efficiency
mpm@selenic.com
parents: 199
diff changeset
80 del hist[p]
199
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
81 hist[n] = curr
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
82
2424676edd8c annotate: deal with merges
mpm@selenic.com
parents: 192
diff changeset
83 return hist[n]
79
837d473d54d5 Add basic annotation support
mpm@selenic.com
parents: 78
diff changeset
84
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
85 class manifest(revlog):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
86 def __init__(self, opener):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
87 self.mapcache = None
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
88 self.listcache = None
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
89 self.addlist = None
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
90 revlog.__init__(self, opener, "00manifest.i", "00manifest.d")
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
91
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
92 def read(self, node):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
93 if self.mapcache and self.mapcache[0] == node:
90
ab9ebff09dcd Fix manifest merge swap bug
mpm@selenic.com
parents: 85
diff changeset
94 return self.mapcache[1].copy()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
95 text = self.revision(node)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
96 map = {}
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
97 flag = {}
25
daa724b27300 Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents: 20
diff changeset
98 self.listcache = (text, text.splitlines(1))
daa724b27300 Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents: 20
diff changeset
99 for l in self.listcache[1]:
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
100 (f, n) = l.split('\0')
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
101 map[f] = bin(n[:40])
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
102 flag[f] = (n[40:-1] == "x")
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
103 self.mapcache = (node, map, flag)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
104 return map
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
105
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
106 def readflags(self, node):
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
107 if self.mapcache or self.mapcache[0] != node:
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
108 self.read(node)
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
109 return self.mapcache[2]
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
110
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
111 def diff(self, a, b):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
112 # this is sneaky, as we're not actually using a and b
140
30ef77113872 Minor safety checks to manifest diff
mpm@selenic.com
parents: 118
diff changeset
113 if self.listcache and self.addlist and self.listcache[0] == a:
98
3dde7c87e36d Add paranoia to diff code
mpm@selenic.com
parents: 96
diff changeset
114 d = mdiff.diff(self.listcache[1], self.addlist, 1)
3dde7c87e36d Add paranoia to diff code
mpm@selenic.com
parents: 96
diff changeset
115 if mdiff.patch(a, d) != b:
3dde7c87e36d Add paranoia to diff code
mpm@selenic.com
parents: 96
diff changeset
116 sys.stderr.write("*** sortdiff failed, falling back ***\n")
3dde7c87e36d Add paranoia to diff code
mpm@selenic.com
parents: 96
diff changeset
117 return mdiff.textdiff(a, b)
3dde7c87e36d Add paranoia to diff code
mpm@selenic.com
parents: 96
diff changeset
118 return d
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
119 else:
44
e825a68d7227 Fix occassional diff bug with manifests
mpm@selenic.com
parents: 40
diff changeset
120 return mdiff.textdiff(a, b)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
121
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
122 def add(self, map, flags, transaction, link, p1=None, p2=None):
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
123 files = map.keys()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
124 files.sort()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
125
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
126 self.addlist = ["%s\000%s%s\n" %
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
127 (f, hex(map[f]), flags[f] and "x" or '')
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
128 for f in files]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
129 text = "".join(self.addlist)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
130
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
131 n = self.addrevision(text, transaction, link, p1, p2)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
132 self.mapcache = (n, map)
25
daa724b27300 Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents: 20
diff changeset
133 self.listcache = (text, self.addlist)
140
30ef77113872 Minor safety checks to manifest diff
mpm@selenic.com
parents: 118
diff changeset
134 self.addlist = None
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
135
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
136 return n
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
137
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
138 class changelog(revlog):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
139 def __init__(self, opener):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
140 revlog.__init__(self, opener, "00changelog.i", "00changelog.d")
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
141
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
142 def extract(self, text):
37
a8811676c85a Move hex/bin bits to revlog
mpm@selenic.com
parents: 33
diff changeset
143 if not text:
40
5f87633e1ea2 Date is an int as a string in changelog
mpm@selenic.com
parents: 37
diff changeset
144 return (nullid, "", "0", [], "")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
145 last = text.index("\n\n")
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
146 desc = text[last + 2:]
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
147 l = text[:last].splitlines()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
148 manifest = bin(l[0])
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
149 user = l[1]
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
150 date = l[2]
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
151 files = l[3:]
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
152 return (manifest, user, date, files, desc)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
153
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
154 def read(self, node):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
155 return self.extract(self.revision(node))
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
156
203
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
157 def add(self, manifest, list, desc, transaction, p1=None, p2=None,
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
158 user=None, date=None):
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
159 user = (user or
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
160 os.environ.get("HGUSER") or
55
2add70d51441 From: Thomas Arendsen Hein <thomas@intevation.de>
mpm@selenic.com
parents: 48
diff changeset
161 os.environ.get("EMAIL") or
2add70d51441 From: Thomas Arendsen Hein <thomas@intevation.de>
mpm@selenic.com
parents: 48
diff changeset
162 os.environ.get("LOGNAME", "unknown") + '@' + socket.getfqdn())
203
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
163 date = date or "%d %d" % (time.time(), time.timezone)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
164 list.sort()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
165 l = [hex(manifest), user, date] + list + ["", desc]
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
166 text = "\n".join(l)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
167 return self.addrevision(text, transaction, self.count(), p1, p2)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
168
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
169 class dirstate:
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
170 def __init__(self, opener, ui, root):
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
171 self.opener = opener
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
172 self.root = root
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
173 self.dirty = 0
20
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
174 self.ui = ui
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
175 self.map = None
227
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
176 self.pl = None
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
177
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
178 def __del__(self):
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
179 if self.dirty:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
180 self.write()
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
181
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
182 def __getitem__(self, key):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
183 try:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
184 return self.map[key]
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
185 except TypeError:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
186 self.read()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
187 return self[key]
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
188
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
189 def __contains__(self, key):
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
190 if not self.map: self.read()
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
191 return key in self.map
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
192
227
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
193 def parents(self):
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
194 if not self.pl:
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
195 self.read()
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
196 return self.pl
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
197
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
198 def setparents(self, p1, p2 = nullid):
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
199 self.dirty = 1
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
200 self.pl = p1, p2
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
201
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
202 def state(self, key):
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
203 try:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
204 return self[key][0]
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
205 except KeyError:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
206 return "?"
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
207
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
208 def read(self):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
209 if self.map is not None: return self.map
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
210
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
211 self.map = {}
227
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
212 self.pl = [nullid, nullid]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
213 try:
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
214 st = self.opener("dirstate").read()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
215 except: return
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
216
227
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
217 self.pl = [st[:20], st[20: 40]]
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
218
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
219 pos = 40
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
220 while pos < len(st):
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
221 e = struct.unpack(">cllll", st[pos:pos+17])
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
222 l = e[4]
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
223 pos += 17
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
224 f = st[pos:pos + l]
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
225 self.map[f] = e[:4]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
226 pos += l
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
227
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
228 def update(self, files, state):
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
229 ''' current states:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
230 n normal
231
15e7c6cee929 add 'm' state to dirstates
mpm@selenic.com
parents: 230
diff changeset
231 m needs merging
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
232 r marked for removal
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
233 a marked for addition'''
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
234
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
235 if not files: return
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
236 self.read()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
237 self.dirty = 1
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
238 for f in files:
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
239 if state == "r":
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
240 self.map[f] = ('r', 0, 0, 0)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
241 else:
253
2da0a56aa1fd Remove invalid state from dirstate
mpm@selenic.com
parents: 251
diff changeset
242 s = os.stat(os.path.join(self.root, f))
2da0a56aa1fd Remove invalid state from dirstate
mpm@selenic.com
parents: 251
diff changeset
243 self.map[f] = (state, s.st_mode, s.st_size, s.st_mtime)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
244
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
245 def forget(self, files):
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
246 if not files: return
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
247 self.read()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
248 self.dirty = 1
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
249 for f in files:
20
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
250 try:
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
251 del self.map[f]
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
252 except KeyError:
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
253 self.ui.warn("not in dirstate: %s!\n" % f)
20
a664c2b624cf The actual hg remove fix from Thomas Hein
mpm@selenic.com
parents: 19
diff changeset
254 pass
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
255
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
256 def clear(self):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
257 self.map = {}
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
258 self.dirty = 1
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
259
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
260 def write(self):
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
261 st = self.opener("dirstate", "w")
227
f57519cddd3d move repo.current to dirstate.parents()
mpm@selenic.com
parents: 225
diff changeset
262 st.write("".join(self.pl))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
263 for f, e in self.map.items():
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
264 e = struct.pack(">cllll", e[0], e[1], e[2], e[3], len(f))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
265 st.write(e + f)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
266 self.dirty = 0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
267
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
268 def copy(self):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
269 self.read()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
270 return self.map.copy()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
271
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
272 # used to avoid circular references so destructors work
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
273 def opener(base):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
274 p = base
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
275 def o(path, mode="r"):
15
6daf7757e92b Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents: 10
diff changeset
276 if p[:7] == "http://":
6daf7757e92b Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents: 10
diff changeset
277 f = os.path.join(p, urllib.quote(path))
6daf7757e92b Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents: 10
diff changeset
278 return httprangereader(f)
6daf7757e92b Fix network pull of repo files with "%" in their base64 encoding.
mpm@selenic.com
parents: 10
diff changeset
279
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
280 f = os.path.join(p, path)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
281
110
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
282 if mode != "r":
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
283 try:
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
284 s = os.stat(f)
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
285 except OSError:
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
286 d = os.path.dirname(f)
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
287 if not os.path.isdir(d):
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
288 os.makedirs(d)
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
289 else:
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
290 if s.st_nlink > 1:
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
291 file(f + ".tmp", "w").write(file(f).read())
c37c7f784ee3 Move hg from storing files in data with base64 encoding to full
mpm@selenic.com
parents: 109
diff changeset
292 os.rename(f+".tmp", f)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
293
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
294 return file(f, mode)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
295
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
296 return o
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
297
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
298 class localrepository:
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
299 def __init__(self, ui, path=None, create=0):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
300 self.remote = 0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
301 if path and path[:7] == "http://":
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
302 self.remote = 1
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
303 self.path = path
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
304 else:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
305 if not path:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
306 p = os.getcwd()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
307 while not os.path.isdir(os.path.join(p, ".hg")):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
308 p = os.path.dirname(p)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
309 if p == "/": raise "No repo found"
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
310 path = p
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
311 self.path = os.path.join(path, ".hg")
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
312
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
313 self.root = path
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
314 self.ui = ui
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
315
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
316 if create:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
317 os.mkdir(self.path)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
318 os.mkdir(self.join("data"))
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
319
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
320 self.opener = opener(self.path)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
321 self.manifest = manifest(self.opener)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
322 self.changelog = changelog(self.opener)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
323 self.ignorelist = None
67
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
324 self.tags = None
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
325
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
326 if not self.remote:
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
327 self.dirstate = dirstate(self.opener, ui, self.root)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
328
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
329 def ignore(self, f):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
330 if self.ignorelist is None:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
331 self.ignorelist = []
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
332 try:
67
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
333 l = open(os.path.join(self.root, ".hgignore"))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
334 for pat in l:
9
b4d0c3786ad3 Ignore empty ignore patterns
mpm@selenic.com
parents: 4
diff changeset
335 if pat != "\n":
b4d0c3786ad3 Ignore empty ignore patterns
mpm@selenic.com
parents: 4
diff changeset
336 self.ignorelist.append(re.compile(pat[:-1]))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
337 except IOError: pass
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
338 for pat in self.ignorelist:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
339 if pat.search(f): return True
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
340 return False
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
341
67
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
342 def lookup(self, key):
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
343 if self.tags is None:
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
344 self.tags = {}
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
345 try:
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
346 # read each head of the tags file, ending with the tip
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
347 # and add each tag found to the map, with "newer" ones
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
348 # taking precedence
67
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
349 fl = self.file(".hgtags")
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
350 h = fl.heads()
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
351 h.reverse()
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
352 for r in h:
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
353 for l in fl.revision(r).splitlines():
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
354 if l:
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
355 n, k = l.split(" ")
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
356 self.tags[k] = bin(n)
67
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
357 except KeyError: pass
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
358 try:
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
359 return self.tags[key]
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
360 except KeyError:
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
361 return self.changelog.lookup(key)
a182f2561c8e Add tag support
mpm@selenic.com
parents: 65
diff changeset
362
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
363 def join(self, f):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
364 return os.path.join(self.path, f)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
365
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
366 def wjoin(self, f):
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
367 return os.path.join(self.root, f)
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
368
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
369 def file(self, f):
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
370 if f[0] == '/': f = f[1:]
144
ea9188538222 Fix transaction handling bug by reverting fileopener change
mpm@selenic.com
parents: 140
diff changeset
371 return filelog(self.opener, f)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
372
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
373 def transaction(self):
251
3fd8fc14b12f backup dirstate for undo
mpm@selenic.com
parents: 249
diff changeset
374 # save dirstate for undo
263
e8eb427c6d71 Fix empty repository transaction bug
mpm@selenic.com
parents: 262
diff changeset
375 try:
e8eb427c6d71 Fix empty repository transaction bug
mpm@selenic.com
parents: 262
diff changeset
376 ds = self.opener("dirstate").read()
e8eb427c6d71 Fix empty repository transaction bug
mpm@selenic.com
parents: 262
diff changeset
377 except IOError:
e8eb427c6d71 Fix empty repository transaction bug
mpm@selenic.com
parents: 262
diff changeset
378 ds = ""
251
3fd8fc14b12f backup dirstate for undo
mpm@selenic.com
parents: 249
diff changeset
379 self.opener("undo.dirstate", "w").write(ds)
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
380
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
381 return transaction.transaction(self.opener, self.join("journal"),
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
382 self.join("undo"))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
383
210
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
384 def recover(self):
225
1651a3e61925 fix repo locking
mpm@selenic.com
parents: 224
diff changeset
385 lock = self.lock()
210
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
386 if os.path.exists(self.join("recover")):
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
387 self.ui.status("attempting to rollback interrupted transaction\n")
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
388 return transaction.rollback(self.opener, self.join("recover"))
210
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
389 else:
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
390 self.ui.warn("no interrupted transaction available\n")
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
391
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
392 def undo(self):
225
1651a3e61925 fix repo locking
mpm@selenic.com
parents: 224
diff changeset
393 lock = self.lock()
210
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
394 if os.path.exists(self.join("undo")):
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
395 self.ui.status("attempting to rollback last transaction\n")
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents: 256
diff changeset
396 transaction.rollback(self.opener, self.join("undo"))
251
3fd8fc14b12f backup dirstate for undo
mpm@selenic.com
parents: 249
diff changeset
397 self.dirstate = None
3fd8fc14b12f backup dirstate for undo
mpm@selenic.com
parents: 249
diff changeset
398 os.rename(self.join("undo.dirstate"), self.join("dirstate"))
3fd8fc14b12f backup dirstate for undo
mpm@selenic.com
parents: 249
diff changeset
399 self.dirstate = dirstate(self.opener, self.ui, self.root)
163
f38c90953c2c Make undo and recover friendlier
mpm@selenic.com
parents: 162
diff changeset
400 else:
210
d2badbd7d1ad hg undo: fixup working dir state
mpm@selenic.com
parents: 207
diff changeset
401 self.ui.warn("no undo information available\n")
162
5dcbe4d9a30c Implement recover and undo commands
mpm@selenic.com
parents: 161
diff changeset
402
161
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents: 155
diff changeset
403 def lock(self, wait = 1):
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents: 155
diff changeset
404 try:
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents: 155
diff changeset
405 return lock.lock(self.join("lock"), 0)
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents: 155
diff changeset
406 except lock.LockHeld, inst:
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents: 155
diff changeset
407 if wait:
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents: 155
diff changeset
408 self.ui.warn("waiting for lock held by %s\n" % inst.args[0])
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents: 155
diff changeset
409 return lock.lock(self.join("lock"), wait)
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents: 155
diff changeset
410 raise inst
0b4c5cb953d9 Simply repository locking
mpm@selenic.com
parents: 155
diff changeset
411
203
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
412 def rawcommit(self, files, text, user, date, p1=None, p2=None):
228
2502aa663484 teach rawcommit about dirstate.parents()
mpm@selenic.com
parents: 227
diff changeset
413 p1 = p1 or self.dirstate.parents()[0] or nullid
2502aa663484 teach rawcommit about dirstate.parents()
mpm@selenic.com
parents: 227
diff changeset
414 p2 = p2 or self.dirstate.parents()[1] or nullid
203
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
415 pchange = self.changelog.read(p1)
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
416 pmmap = self.manifest.read(pchange[0])
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
417 tr = self.transaction()
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
418 mmap = {}
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
419 linkrev = self.changelog.count()
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
420 for f in files:
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
421 try:
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
422 t = file(f).read()
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
423 except IOError:
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
424 self.ui.warn("Read file %s error, skipped\n" % f)
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
425 continue
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
426 r = self.file(f)
228
2502aa663484 teach rawcommit about dirstate.parents()
mpm@selenic.com
parents: 227
diff changeset
427 # FIXME - need to find both parents properly
203
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
428 prev = pmmap.get(f, nullid)
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
429 mmap[f] = r.add(t, tr, linkrev, prev)
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
430
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
431 mnode = self.manifest.add(mmap, tr, linkrev, pchange[0])
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
432 n = self.changelog.add(mnode, files, text, tr, p1, p2, user ,date, )
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
433 tr.close()
228
2502aa663484 teach rawcommit about dirstate.parents()
mpm@selenic.com
parents: 227
diff changeset
434 self.dirstate.setparents(p1, p2)
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
435 self.dirstate.clear()
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
436 self.dirstate.update(mmap.keys(), "n")
203
0b486b5e0796 hg rawcommit command
mpm@selenic.com
parents: 200
diff changeset
437
229
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
438 def commit(self, files = None, text = ""):
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
439 commit = []
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
440 remove = []
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
441 if files:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
442 for f in files:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
443 s = self.dirstate.state(f)
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
444 if s in 'nmai':
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
445 commit.append(f)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
446 elif s == 'r':
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
447 remove.append(f)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
448 else:
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
449 self.ui.warn("%s not tracked!\n" % f)
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
450 else:
230
00ea3613f82c make diffdir default to dirstate.parents()
mpm@selenic.com
parents: 229
diff changeset
451 (c, a, d, u) = self.diffdir(self.root)
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
452 commit = c + a
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
453 remove = d
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
454
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
455 if not commit and not remove:
151
1f6c61a60586 Bail on attempts to do an empty commit
mpm@selenic.com
parents: 149
diff changeset
456 self.ui.status("nothing changed\n")
1f6c61a60586 Bail on attempts to do an empty commit
mpm@selenic.com
parents: 149
diff changeset
457 return
1f6c61a60586 Bail on attempts to do an empty commit
mpm@selenic.com
parents: 149
diff changeset
458
229
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
459 p1, p2 = self.dirstate.parents()
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
460 c1 = self.changelog.read(p1)
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
461 c2 = self.changelog.read(p2)
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
462 m1 = self.manifest.read(c1[0])
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
463 mf1 = self.manifest.readflags(c1[0])
229
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
464 m2 = self.manifest.read(c2[0])
225
1651a3e61925 fix repo locking
mpm@selenic.com
parents: 224
diff changeset
465 lock = self.lock()
151
1f6c61a60586 Bail on attempts to do an empty commit
mpm@selenic.com
parents: 149
diff changeset
466 tr = self.transaction()
1f6c61a60586 Bail on attempts to do an empty commit
mpm@selenic.com
parents: 149
diff changeset
467
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
468 # check in files
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
469 new = {}
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
470 linkrev = self.changelog.count()
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
471 commit.sort()
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
472 for f in commit:
83
9fd5b35cfc45 Add -q quiet option
mpm@selenic.com
parents: 79
diff changeset
473 self.ui.note(f + "\n")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
474 try:
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
475 fp = self.wjoin(f)
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
476 mf1[f] = is_exec(fp)
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
477 t = file(fp).read()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
478 except IOError:
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
479 self.warn("trouble committing %s!\n" % f)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
480 raise
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
481
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
482 r = self.file(f)
229
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
483 fp1 = m1.get(f, nullid)
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
484 fp2 = m2.get(f, nullid)
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
485 new[f] = r.add(t, tr, linkrev, fp1, fp2)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
486
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
487 # update manifest
229
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
488 m1.update(new)
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
489 for f in remove: del m1[f]
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
490 mn = self.manifest.add(m1, mf1, tr, linkrev, c1[0], c2[0])
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
491
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
492 # add changeset
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
493 new = new.keys()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
494 new.sort()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
495
229
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
496 edittext = text + "\n" + "HG: manifest hash %s\n" % hex(mn)
185
db3aa85b9379 Add manifest hash to commit messages for easy signing
mpm@selenic.com
parents: 182
diff changeset
497 edittext += "".join(["HG: changed %s\n" % f for f in new])
25
daa724b27300 Fix corruption from manifest.listcache optimization
mpm@selenic.com
parents: 20
diff changeset
498 edittext += "".join(["HG: removed %s\n" % f for f in remove])
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
499 edittext = self.ui.edit(edittext)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
500
229
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
501 n = self.changelog.add(mn, new, edittext, tr, p1, p2)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
502 tr.close()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
503
229
1b11da6ee69e teach commit about dirstate.parents()
mpm@selenic.com
parents: 228
diff changeset
504 self.dirstate.setparents(n)
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
505 self.dirstate.update(new, "n")
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
506 self.dirstate.forget(remove)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
507
230
00ea3613f82c make diffdir default to dirstate.parents()
mpm@selenic.com
parents: 229
diff changeset
508 def diffdir(self, path, changeset = None):
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
509 changed = []
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
510 added = []
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
511 unknown = []
4
ce3bd728b858 Fix exception handling for reading current working version
mpm@selenic.com
parents: 0
diff changeset
512 mf = {}
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
513
29
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
514 if changeset:
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
515 change = self.changelog.read(changeset)
4
ce3bd728b858 Fix exception handling for reading current working version
mpm@selenic.com
parents: 0
diff changeset
516 mf = self.manifest.read(change[0])
230
00ea3613f82c make diffdir default to dirstate.parents()
mpm@selenic.com
parents: 229
diff changeset
517 dc = dict.fromkeys(mf)
00ea3613f82c make diffdir default to dirstate.parents()
mpm@selenic.com
parents: 229
diff changeset
518 else:
00ea3613f82c make diffdir default to dirstate.parents()
mpm@selenic.com
parents: 229
diff changeset
519 changeset = self.dirstate.parents()[0]
00ea3613f82c make diffdir default to dirstate.parents()
mpm@selenic.com
parents: 229
diff changeset
520 change = self.changelog.read(changeset)
00ea3613f82c make diffdir default to dirstate.parents()
mpm@selenic.com
parents: 229
diff changeset
521 mf = self.manifest.read(change[0])
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
522 dc = self.dirstate.copy()
29
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
523
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
524 def fcmp(fn):
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
525 t1 = file(self.wjoin(fn)).read()
29
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
526 t2 = self.file(fn).revision(mf[fn])
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
527 return cmp(t1, t2)
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
528
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
529 for dir, subdirs, files in os.walk(self.root):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
530 d = dir[len(self.root)+1:]
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
531 if ".hg" in subdirs: subdirs.remove(".hg")
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
532
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
533 for f in files:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
534 fn = os.path.join(d, f)
64
b3e2ddff0159 Diff in subdirectories from Jake Edge
mpm@selenic.com
parents: 60
diff changeset
535 try: s = os.stat(os.path.join(self.root, fn))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
536 except: continue
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
537 if fn in dc:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
538 c = dc[fn]
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
539 del dc[fn]
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
540 if not c:
29
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
541 if fcmp(fn):
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
542 changed.append(fn)
231
15e7c6cee929 add 'm' state to dirstates
mpm@selenic.com
parents: 230
diff changeset
543 elif c[0] == 'm':
15e7c6cee929 add 'm' state to dirstates
mpm@selenic.com
parents: 230
diff changeset
544 changed.append(fn)
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
545 elif c[0] == 'a':
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
546 added.append(fn)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
547 elif c[0] == 'r':
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
548 unknown.append(fn)
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
549 elif c[2] != s.st_size or (c[1] ^ s.st_mode) & 0100:
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
550 changed.append(fn)
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
551 elif c[1] != s.st_mode or c[3] != s.st_mtime:
29
4d3a5dcb6972 Make diffdir take a revision argument
mpm@selenic.com
parents: 25
diff changeset
552 if fcmp(fn):
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
553 changed.append(fn)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
554 else:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
555 if self.ignore(fn): continue
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
556 unknown.append(fn)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
557
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
558 deleted = dc.keys()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
559 deleted.sort()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
560
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
561 return (changed, added, deleted, unknown)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
562
32
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
563 def diffrevs(self, node1, node2):
33
98633e60067c Support for 0, 1, or 2 diff revs
mpm@selenic.com
parents: 32
diff changeset
564 changed, added = [], []
32
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
565
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
566 change = self.changelog.read(node1)
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
567 mf1 = self.manifest.read(change[0])
33
98633e60067c Support for 0, 1, or 2 diff revs
mpm@selenic.com
parents: 32
diff changeset
568 change = self.changelog.read(node2)
32
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
569 mf2 = self.manifest.read(change[0])
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
570
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
571 for fn in mf2:
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
572 if mf1.has_key(fn):
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
573 if mf1[fn] != mf2[fn]:
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
574 changed.append(fn)
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
575 del mf1[fn]
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
576 else:
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
577 added.append(fn)
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
578
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
579 deleted = mf1.keys()
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
580 deleted.sort()
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
581
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
582 return (changed, added, deleted)
6a4d8718bee0 Add diffrevs function to compare two nodes
mpm@selenic.com
parents: 30
diff changeset
583
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
584 def add(self, list):
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
585 for f in list:
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
586 p = self.wjoin(f)
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
587 if not os.path.isfile(p):
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
588 self.ui.warn("%s does not exist!\n" % f)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
589 elif self.dirstate.state(f) == 'n':
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
590 self.ui.warn("%s already tracked!\n" % f)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
591 else:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
592 self.dirstate.update([f], "a")
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
593
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
594 def forget(self, list):
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
595 for f in list:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
596 if self.dirstate.state(f) not in 'ai':
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
597 self.ui.warn("%s not added!\n" % f)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
598 else:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
599 self.dirstate.forget([f])
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
600
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
601 def remove(self, list):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
602 for f in list:
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
603 p = self.wjoin(f)
220
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
604 if os.path.isfile(p):
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
605 self.ui.warn("%s still exists!\n" % f)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
606 elif f not in self.dirstate:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
607 self.ui.warn("%s not tracked!\n" % f)
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
608 else:
3113a94c1bff change dircache into dirstate
mpm@selenic.com
parents: 217
diff changeset
609 self.dirstate.update([f], "r")
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
610
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
611 def heads(self):
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
612 return self.changelog.heads()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
613
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
614 def branches(self, nodes):
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
615 if not nodes: nodes = [self.changelog.tip()]
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
616 b = []
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
617 for n in nodes:
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
618 t = n
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
619 while n:
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
620 p = self.changelog.parents(n)
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
621 if p[1] != nullid or p[0] == nullid:
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
622 b.append((t, n, p[0], p[1]))
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
623 break
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
624 n = p[0]
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
625 return b
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
626
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
627 def between(self, pairs):
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
628 r = []
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
629
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
630 for top, bottom in pairs:
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
631 n, l, i = top, [], 0
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
632 f = 1
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
633
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
634 while n != bottom:
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
635 p = self.changelog.parents(n)[0]
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
636 if i == f:
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
637 l.append(n)
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
638 f = f * 2
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
639 n = p
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
640 i += 1
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
641
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
642 r.append(l)
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
643
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
644 return r
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
645
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
646 def newer(self, nodes):
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
647 m = {}
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
648 nl = []
94
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
649 pm = {}
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
650 cl = self.changelog
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
651 t = l = cl.count()
94
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
652
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
653 # find the lowest numbered node
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
654 for n in nodes:
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
655 l = min(l, cl.rev(n))
94
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
656 m[n] = 1
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
657
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
658 for i in xrange(l, t):
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
659 n = cl.node(i)
94
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
660 if n in m: # explicitly listed
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
661 pm[n] = 1
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
662 nl.append(n)
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
663 continue
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
664 for p in cl.parents(n):
94
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
665 if p in pm: # parent listed
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
666 pm[n] = 1
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
667 nl.append(n)
94
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
668 break
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
669
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
670 return nl
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
671
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
672 def getchangegroup(self, remote):
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
673 m = self.changelog.nodemap
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
674 search = []
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
675 fetch = []
148
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
676 seen = {}
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
677 seenbranch = {}
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
678
190
3dd5ce2fddb6 merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents: 187
diff changeset
679 # if we have an empty repo, fetch everything
3dd5ce2fddb6 merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents: 187
diff changeset
680 if self.changelog.tip() == nullid:
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
681 self.ui.status("requesting all changes\n")
190
3dd5ce2fddb6 merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents: 187
diff changeset
682 return remote.changegroup([nullid])
3dd5ce2fddb6 merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents: 187
diff changeset
683
3dd5ce2fddb6 merge: short-circuit search for merge into empty repo
mpm@selenic.com
parents: 187
diff changeset
684 # otherwise, assume we're closer to the tip than the root
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
685 self.ui.status("searching for changes\n")
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
686 heads = remote.heads()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
687 unknown = []
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
688 for h in heads:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
689 if h not in m:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
690 unknown.append(h)
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
691
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
692 if not unknown:
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
693 self.ui.status("nothing to do!\n")
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
694 return None
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
695
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
696 unknown = remote.branches(unknown)
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
697 while unknown:
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
698 n = unknown.pop(0)
148
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
699 seen[n[0]] = 1
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
700
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
701 self.ui.debug("examining %s:%s\n" % (short(n[0]), short(n[1])))
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
702 if n == nullid: break
148
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
703 if n in seenbranch:
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
704 self.ui.debug("branch already found\n")
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
705 continue
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
706 if n[1] and n[1] in m: # do we know the base?
148
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
707 self.ui.debug("found incomplete branch %s:%s\n"
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
708 % (short(n[0]), short(n[1])))
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
709 search.append(n) # schedule branch range for scanning
148
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
710 seenbranch[n] = 1
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
711 else:
94
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
712 if n[2] in m and n[3] in m:
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
713 if n[1] not in fetch:
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
714 self.ui.debug("found new changeset %s\n" %
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
715 short(n[1]))
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
716 fetch.append(n[1]) # earliest unknown
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
717 continue
148
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
718
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
719 r = []
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
720 for a in n[2:4]:
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
721 if a not in seen: r.append(a)
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
722
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
723 if r:
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
724 self.ui.debug("requesting %s\n" %
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
725 " ".join(map(short, r)))
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
726 for b in remote.branches(r):
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
727 self.ui.debug("received %s:%s\n" %
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
728 (short(b[0]), short(b[1])))
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
729 if b[0] not in m and b[0] not in seen:
c32286d0a665 Improve pruning of branches in outstanding changeset algorithm
mpm@selenic.com
parents: 146
diff changeset
730 unknown.append(b)
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
731
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
732 while search:
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
733 n = search.pop(0)
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
734 l = remote.between([(n[0], n[1])])[0]
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
735 p = n[0]
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
736 f = 1
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
737 for i in l + [n[1]]:
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
738 if i in m:
85
58a1a0425c9b Fix merge bug, I hope
mpm@selenic.com
parents: 83
diff changeset
739 if f <= 2:
83
9fd5b35cfc45 Add -q quiet option
mpm@selenic.com
parents: 79
diff changeset
740 self.ui.debug("found new branch changeset %s\n" %
9fd5b35cfc45 Add -q quiet option
mpm@selenic.com
parents: 79
diff changeset
741 short(p))
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
742 fetch.append(p)
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
743 else:
83
9fd5b35cfc45 Add -q quiet option
mpm@selenic.com
parents: 79
diff changeset
744 self.ui.debug("narrowed branch search to %s:%s\n"
9fd5b35cfc45 Add -q quiet option
mpm@selenic.com
parents: 79
diff changeset
745 % (short(p), short(i)))
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
746 search.append((p, i))
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
747 break
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
748 p, f = i, f * 2
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
749
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
750 for f in fetch:
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
751 if f in m:
83
9fd5b35cfc45 Add -q quiet option
mpm@selenic.com
parents: 79
diff changeset
752 raise "already have", short(f[:4])
9fd5b35cfc45 Add -q quiet option
mpm@selenic.com
parents: 79
diff changeset
753
94
7daef883134f Refactor merge code
mpm@selenic.com
parents: 90
diff changeset
754 self.ui.note("adding new changesets starting at " +
83
9fd5b35cfc45 Add -q quiet option
mpm@selenic.com
parents: 79
diff changeset
755 " ".join([short(f) for f in fetch]) + "\n")
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
756
56
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
757 return remote.changegroup(fetch)
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
758
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
759 def changegroup(self, basenodes):
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
760 nodes = self.newer(basenodes)
ad2ea1185f04 Add getchangegroup code to efficiently calculate and request a changegroup
mpm@selenic.com
parents: 55
diff changeset
761
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
762 # construct the link map
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
763 linkmap = {}
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
764 for n in nodes:
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
765 linkmap[self.changelog.rev(n)] = n
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
766
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
767 # construct a list of all changed files
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
768 changed = {}
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
769 for n in nodes:
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
770 c = self.changelog.read(n)
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
771 for f in c[3]:
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
772 changed[f] = 1
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
773 changed = changed.keys()
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
774 changed.sort()
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
775
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
776 # the changegroup is changesets + manifests + all file revs
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
777 revs = [ self.changelog.rev(n) for n in nodes ]
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
778
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
779 for y in self.changelog.group(linkmap): yield y
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
780 for y in self.manifest.group(linkmap): yield y
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
781 for f in changed:
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
782 yield struct.pack(">l", len(f) + 4) + f
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
783 g = self.file(f).group(linkmap)
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
784 for y in g:
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
785 yield y
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
786
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
787 def addchangegroup(self, generator):
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
788
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
789 class genread:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
790 def __init__(self, generator):
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
791 self.g = generator
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
792 self.buf = ""
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
793 def read(self, l):
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
794 while l > len(self.buf):
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
795 try:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
796 self.buf += self.g.next()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
797 except StopIteration:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
798 break
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
799 d, self.buf = self.buf[:l], self.buf[l:]
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
800 return d
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
801
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
802 def getchunk():
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
803 d = source.read(4)
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
804 if not d: return ""
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
805 l = struct.unpack(">l", d)[0]
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
806 if l <= 4: return ""
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
807 return source.read(l - 4)
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
808
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
809 def getgroup():
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
810 while 1:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
811 c = getchunk()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
812 if not c: break
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
813 yield c
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
814
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
815 def csmap(x):
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
816 self.ui.debug("add changeset %s\n" % short(x))
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
817 return self.changelog.count()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
818
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
819 def revmap(x):
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
820 return self.changelog.rev(x)
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
821
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
822 if not generator: return
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
823 changesets = files = revisions = 0
225
1651a3e61925 fix repo locking
mpm@selenic.com
parents: 224
diff changeset
824
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
825 source = genread(generator)
225
1651a3e61925 fix repo locking
mpm@selenic.com
parents: 224
diff changeset
826 lock = self.lock()
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
827 tr = self.transaction()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
828
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
829 # pull off the changeset group
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
830 self.ui.status("adding changesets\n")
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
831 co = self.changelog.tip()
224
ccbcc4d76f81 fix bad assumption about uniqueness of file versions
mpm@selenic.com
parents: 223
diff changeset
832 cn = self.changelog.addgroup(getgroup(), csmap, tr, 1) # unique
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
833 changesets = self.changelog.rev(cn) - self.changelog.rev(co)
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
834
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
835 # pull off the manifest group
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
836 self.ui.status("adding manifests\n")
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
837 mm = self.manifest.tip()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
838 mo = self.manifest.addgroup(getgroup(), revmap, tr)
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
839
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
840 # process the files
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
841 self.ui.status("adding file revisions\n")
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
842 while 1:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
843 f = getchunk()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
844 if not f: break
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
845 self.ui.debug("adding %s revisions\n" % f)
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
846 fl = self.file(f)
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
847 o = fl.tip()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
848 n = fl.addgroup(getgroup(), revmap, tr)
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
849 revisions += fl.rev(n) - fl.rev(o)
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
850 files += 1
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
851
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
852 self.ui.status(("modified %d files, added %d changesets" +
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
853 " and %d new revisions\n")
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
854 % (files, changesets, revisions))
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
855
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
856 tr.close()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
857 return
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
858
275
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
859 def update(self, node, allow=False, force=False):
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
860 pl = self.dirstate.parents()
275
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
861 if not force and pl[1] != nullid:
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
862 self.ui.warn("aborting: outstanding uncommitted merges\n")
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
863 return
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
864
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
865 p1, p2 = pl[0], node
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
866 m1n = self.changelog.read(p1)[0]
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
867 m2n = self.changelog.read(p2)[0]
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
868 man = self.manifest.ancestor(m1n, m2n)
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
869 m1 = self.manifest.read(m1n)
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
870 mf1 = self.manifest.readflags(m1n)
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
871 m2 = self.manifest.read(m2n)
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
872 mf2 = self.manifest.readflags(m2n)
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
873 ma = self.manifest.read(man)
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
874 mfa = self.manifest.readflags(m2n)
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
875
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
876 (c, a, d, u) = self.diffdir(self.root)
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
877
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
878 # resolve the manifest to determine which files
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
879 # we care about merging
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
880 self.ui.note("resolving manifests\n")
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
881 self.ui.debug(" ancestor %s local %s remote %s\n" %
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
882 (short(man), short(m1n), short(m2n)))
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
883
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
884 merge = {}
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
885 get = {}
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
886 remove = []
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
887
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
888 # construct a working dir manifest
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
889 mw = m1.copy()
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
890 mfw = mf1.copy()
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
891 for f in a + c + u:
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
892 mw[f] = ""
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
893 mfw[f] = is_exec(self.wjoin(f))
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
894 for f in d:
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
895 if f in mw: del mw[f]
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
896
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
897 for f, n in mw.iteritems():
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
898 if f in m2:
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
899 if n != m2[f]:
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
900 a = ma.get(f, nullid)
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
901 if n != a and m2[f] != a:
273
4f8174389001 merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents: 263
diff changeset
902 self.ui.debug(" %s versions differ, resolve\n" % f)
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
903 merge[f] = (m1.get(f, nullid), m2[f])
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
904 # merge executable bits
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
905 # "if we changed or they changed, change in merge"
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
906 a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
907 mode = ((a^b) | (a^c)) ^ a
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
908 merge[f] = (m1.get(f, nullid), m2[f], mode)
273
4f8174389001 merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents: 263
diff changeset
909 elif m2[f] != a:
4f8174389001 merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents: 263
diff changeset
910 self.ui.debug(" remote %s is newer, get\n" % f)
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
911 get[f] = m2[f]
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
912 del m2[f]
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
913 elif f in ma:
275
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
914 if not force and n != ma[f]:
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
915 r = self.ui.prompt(
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
916 (" local changed %s which remote deleted\n" % f) +
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
917 "(k)eep or (d)elete?", "[kd]", "k")
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
918 if r == "d":
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
919 remove.append(f)
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
920 else:
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
921 self.ui.debug("other deleted %s\n" % f)
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
922 remove.append(f) # other deleted it
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
923 else:
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
924 if n == m1.get(f, nullid): # same as parent
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
925 self.ui.debug("remote deleted %s\n" % f)
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
926 remove.append(f)
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
927 else:
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
928 self.ui.debug("working dir created %s, keeping\n" % f)
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
929
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
930 for f, n in m2.iteritems():
256
649ed23e4661 minor fixes for update()
mpm@selenic.com
parents: 254
diff changeset
931 if f[0] == "/": continue
275
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
932 if not force and f in ma and n != ma[f]:
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
933 r = self.ui.prompt(
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
934 ("remote changed %s which local deleted\n" % f) +
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
935 "(k)eep or (d)elete?", "[kd]", "k")
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
936 if r == "d": remove.append(f)
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
937 else:
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
938 self.ui.debug("remote created %s\n" % f)
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
939 get[f] = n
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
940
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
941 del mw, m1, m2, ma
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
942
275
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
943 if force:
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
944 for f in merge:
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
945 get[f] = merge[f][1]
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
946 merge = {}
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
947
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
948 if not merge:
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
949 # we don't need to do any magic, just jump to the new rev
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
950 mode = 'n'
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
951 p1, p2 = p2, nullid
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
952 else:
275
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
953 if not allow:
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
954 self.ui.status("the following files conflict:\n")
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
955 for f in merge:
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
956 self.ui.status(" %s\n" % f)
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
957 self.ui.warn("aborting update due to conflicting files!\n")
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
958 self.ui.status("(use update -m to allow a merge)\n")
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
959 return 1
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
960 # we have to remember what files we needed to get/change
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
961 # because any file that's different from either one of its
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
962 # parents must be in the changeset
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
963 mode = 'm'
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
964
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
965 self.dirstate.setparents(p1, p2)
191
d7e859cf2f1b merge: add count of new manifests, files, and revisions
mpm@selenic.com
parents: 190
diff changeset
966
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
967 # get the files we don't need to change
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
968 files = get.keys()
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
969 files.sort()
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
970 for f in files:
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
971 if f[0] == "/": continue
273
4f8174389001 merge: Fix bug where we overwrote local when local was newer
mpm@selenic.com
parents: 263
diff changeset
972 self.ui.note("getting %s\n" % f)
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
973 t = self.file(f).read(get[f])
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
974 wp = self.wjoin(f)
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
975 try:
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
976 file(wp, "w").write(t)
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
977 except IOError:
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
978 os.makedirs(os.path.dirname(wp))
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
979 file(wp, "w").write(t)
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
980 set_exec(wp, mf2[f])
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
981 self.dirstate.update([f], mode)
46
93e868fa0db8 Add changegroup support
mpm@selenic.com
parents: 44
diff changeset
982
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
983 # merge the tricky bits
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
984 files = merge.keys()
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
985 files.sort()
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
986 for f in files:
256
649ed23e4661 minor fixes for update()
mpm@selenic.com
parents: 254
diff changeset
987 self.ui.status("merging %s\n" % f)
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
988 m, o, flag = merge[f]
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
989 self.merge3(f, m, o)
276
10e325db7347 add tracking of execute permissions
mpm@selenic.com
parents: 275
diff changeset
990 set_exec(wp, flag)
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
991 self.dirstate.update([f], 'm')
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
992
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
993 for f in remove:
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
994 self.ui.note("removing %s\n" % f)
254
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
995 os.unlink(f)
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
996 if mode == 'n':
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
997 self.dirstate.forget(remove)
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
998 else:
c03f58e5fd2d unify checkout and resolve into update
mpm@selenic.com
parents: 253
diff changeset
999 self.dirstate.update(remove, 'r')
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1000
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1001 def merge3(self, fn, my, other):
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1002 """perform a 3-way merge in the working directory"""
249
619e775aa7f9 import and startup cleanups
mpm@selenic.com
parents: 247
diff changeset
1003
96
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1004 def temp(prefix, node):
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1005 pre = "%s~%s." % (os.path.basename(fn), prefix)
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1006 (fd, name) = tempfile.mkstemp("", pre)
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1007 f = os.fdopen(fd, "w")
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1008 f.write(fl.revision(node))
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1009 f.close()
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1010 return name
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1011
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1012 fl = self.file(fn)
96
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1013 base = fl.ancestor(my, other)
244
43105253cf5e root relative IO and valid commit states
mpm@selenic.com
parents: 241
diff changeset
1014 a = self.wjoin(fn)
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1015 b = temp("other", other)
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1016 c = temp("base", base)
96
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1017
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1018 self.ui.note("resolving %s\n" % fn)
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1019 self.ui.debug("file %s: other %s ancestor %s\n" %
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1020 (fn, short(other), short(base)))
96
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1021
240
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents: 232
diff changeset
1022 cmd = os.environ.get("HGMERGE", "hgmerge")
737c66b68290 Replace tkmerge with hgmerge
mpm@selenic.com
parents: 232
diff changeset
1023 r = os.system("%s %s %s %s" % (cmd, a, b, c))
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1024 if r:
275
61d45b0ba8fb various merge improvements
mpm@selenic.com
parents: 273
diff changeset
1025 self.ui.warn("merging %s failed!\n" % fn)
232
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1026
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1027 os.unlink(b)
fc4a6e5b5812 hg resolve: merge a given node into the working directory
mpm@selenic.com
parents: 231
diff changeset
1028 os.unlink(c)
96
fce47326677c Add updated merge3 code
mpm@selenic.com
parents: 95
diff changeset
1029
247
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1030 def verify(self):
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1031 filelinkrevs = {}
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1032 filenodes = {}
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1033 manifestchangeset = {}
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1034 changesets = revisions = files = 0
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1035 errors = 0
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1036
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1037 self.ui.status("checking changesets\n")
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1038 for i in range(self.changelog.count()):
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1039 changesets += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1040 n = self.changelog.node(i)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1041 for p in self.changelog.parents(n):
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1042 if p not in self.changelog.nodemap:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1043 self.ui.warn("changeset %s has unknown parent %s\n" %
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1044 (short(n), short(p)))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1045 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1046 try:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1047 changes = self.changelog.read(n)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1048 except Exception, inst:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1049 self.ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1050 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1051
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1052 manifestchangeset[changes[0]] = n
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1053 for f in changes[3]:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1054 filelinkrevs.setdefault(f, []).append(i)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1055
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1056 self.ui.status("checking manifests\n")
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1057 for i in range(self.manifest.count()):
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1058 n = self.manifest.node(i)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1059 for p in self.manifest.parents(n):
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1060 if p not in self.manifest.nodemap:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1061 self.ui.warn("manifest %s has unknown parent %s\n" %
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1062 (short(n), short(p)))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1063 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1064 ca = self.changelog.node(self.manifest.linkrev(n))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1065 cc = manifestchangeset[n]
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1066 if ca != cc:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1067 self.ui.warn("manifest %s points to %s, not %s\n" %
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1068 (hex(n), hex(ca), hex(cc)))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1069 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1070
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1071 try:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1072 delta = mdiff.patchtext(self.manifest.delta(n))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1073 except KeyboardInterrupt:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1074 print "aborted"
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1075 sys.exit(0)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1076 except Exception, inst:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1077 self.ui.warn("unpacking manifest %s: %s\n"
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1078 % (short(n), inst))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1079 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1080
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1081 ff = [ l.split('\0') for l in delta.splitlines() ]
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1082 for f, fn in ff:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1083 filenodes.setdefault(f, {})[bin(fn)] = 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1084
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1085 self.ui.status("crosschecking files in changesets and manifests\n")
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1086 for f in filenodes:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1087 if f not in filelinkrevs:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1088 self.ui.warn("file %s in manifest but not in changesets\n" % f)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1089 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1090
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1091 for f in filelinkrevs:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1092 if f not in filenodes:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1093 self.ui.warn("file %s in changeset but not in manifest\n" % f)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1094 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1095
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1096 self.ui.status("checking files\n")
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1097 ff = filenodes.keys()
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1098 ff.sort()
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1099 for f in ff:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1100 if f == "/dev/null": continue
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1101 files += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1102 fl = self.file(f)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1103 nodes = { nullid: 1 }
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1104 for i in range(fl.count()):
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1105 revisions += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1106 n = fl.node(i)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1107
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1108 if n not in filenodes[f]:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1109 self.ui.warn("%s: %d:%s not in manifests\n"
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1110 % (f, i, short(n)))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1111 print len(filenodes[f].keys()), fl.count(), f
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1112 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1113 else:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1114 del filenodes[f][n]
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1115
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1116 flr = fl.linkrev(n)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1117 if flr not in filelinkrevs[f]:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1118 self.ui.warn("%s:%s points to unexpected changeset %d\n"
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1119 % (f, short(n), fl.linkrev(n)))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1120 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1121 else:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1122 filelinkrevs[f].remove(flr)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1123
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1124 # verify contents
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1125 try:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1126 t = fl.read(n)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1127 except Exception, inst:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1128 self.ui.warn("unpacking file %s %s: %s\n"
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1129 % (f, short(n), inst))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1130 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1131
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1132 # verify parents
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1133 (p1, p2) = fl.parents(n)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1134 if p1 not in nodes:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1135 self.ui.warn("file %s:%s unknown parent 1 %s" %
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1136 (f, short(n), short(p1)))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1137 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1138 if p2 not in nodes:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1139 self.ui.warn("file %s:%s unknown parent 2 %s" %
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1140 (f, short(n), short(p1)))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1141 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1142 nodes[n] = 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1143
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1144 # cross-check
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1145 for node in filenodes[f]:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1146 self.ui.warn("node %s in manifests not in %s\n"
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1147 % (hex(n), f))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1148 errors += 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1149
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1150 self.ui.status("%d files, %d changesets, %d total revisions\n" %
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1151 (files, changesets, revisions))
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1152
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1153 if errors:
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1154 self.ui.warn("%d integrity errors encountered!\n" % errors)
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1155 return 1
863b508c5b36 migrate verify
mpm@selenic.com
parents: 244
diff changeset
1156
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1157 class remoterepository:
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1158 def __init__(self, ui, path):
176
1d8e9637a0a4 Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents: 171
diff changeset
1159 self.url = path
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1160 self.ui = ui
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1161
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1162 def do_cmd(self, cmd, **args):
83
9fd5b35cfc45 Add -q quiet option
mpm@selenic.com
parents: 79
diff changeset
1163 self.ui.debug("sending %s command\n" % cmd)
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1164 q = {"cmd": cmd}
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1165 q.update(args)
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1166 qs = urllib.urlencode(q)
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1167 cu = "%s?%s" % (self.url, qs)
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1168 return urllib.urlopen(cu)
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1169
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
1170 def heads(self):
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
1171 d = self.do_cmd("heads").read()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
1172 try:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
1173 return map(bin, d[:-1].split(" "))
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
1174 except:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
1175 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
1176 raise
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
1177
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1178 def branches(self, nodes):
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1179 n = " ".join(map(hex, nodes))
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1180 d = self.do_cmd("branches", nodes=n).read()
217
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1181 try:
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1182 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1183 return br
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1184 except:
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1185 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1186 raise
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1187
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1188 def between(self, pairs):
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1189 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1190 d = self.do_cmd("between", pairs=n).read()
217
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1191 try:
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1192 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1193 return p
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1194 except:
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1195 self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n")
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
1196 raise
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1197
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1198 def changegroup(self, nodes):
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1199 n = " ".join(map(hex, nodes))
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1200 zd = zlib.decompressobj()
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1201 f = self.do_cmd("changegroup", roots=n)
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
1202 bytes = 0
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1203 while 1:
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1204 d = f.read(4096)
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
1205 bytes += len(d)
65
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1206 if not d:
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1207 yield zd.flush()
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1208 break
d40cc5aacc31 Fix up a bunch of bugs in the new merge code
mpm@selenic.com
parents: 64
diff changeset
1209 yield zd.decompress(d)
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
1210 self.ui.note("%d bytes of data transfered\n" % bytes)
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1211
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1212 def repository(ui, path=None, create=0):
176
1d8e9637a0a4 Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents: 171
diff changeset
1213 if path and path[:7] == "http://":
1d8e9637a0a4 Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents: 171
diff changeset
1214 return remoterepository(ui, path)
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1215 if path and path[:5] == "hg://":
176
1d8e9637a0a4 Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents: 171
diff changeset
1216 return remoterepository(ui, path.replace("hg://", "http://"))
1d8e9637a0a4 Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents: 171
diff changeset
1217 if path and path[:11] == "old-http://":
1d8e9637a0a4 Change hg: protocol name to http: and http: to old-http:
mpm@selenic.com
parents: 171
diff changeset
1218 return localrepository(ui, path.replace("old-http://", "http://"))
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1219 else:
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1220 return localrepository(ui, path, create)
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
1221
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1222 class httprangereader:
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1223 def __init__(self, url):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1224 self.url = url
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1225 self.pos = 0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1226 def seek(self, pos):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1227 self.pos = pos
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1228 def read(self, bytes=None):
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1229 opener = urllib2.build_opener(byterange.HTTPRangeHandler())
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1230 urllib2.install_opener(opener)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1231 req = urllib2.Request(self.url)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1232 end = ''
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1233 if bytes: end = self.pos + bytes
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1234 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1235 f = urllib2.urlopen(req)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
1236 return f.read()