Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/localrepo.py @ 1779:a1e6e02e9d05
Merge with mpm
author | Josef "Jeff" Sipek <jeffpc@optonline.net> |
---|---|
date | Sat, 18 Feb 2006 22:24:42 -0500 |
parents | 2c9872a4f3fd |
children | 91c56c427171 |
comparison
equal
deleted
inserted
replaced
1778:b08b87cecc37 | 1779:a1e6e02e9d05 |
---|---|
46 try: | 46 try: |
47 self.ui.readconfig(self.join("hgrc")) | 47 self.ui.readconfig(self.join("hgrc")) |
48 except IOError: | 48 except IOError: |
49 pass | 49 pass |
50 | 50 |
51 def hook(self, name, **args): | 51 def hook(self, name, throw=False, **args): |
52 def runhook(name, cmd): | 52 def runhook(name, cmd): |
53 self.ui.note(_("running hook %s: %s\n") % (name, cmd)) | 53 self.ui.note(_("running hook %s: %s\n") % (name, cmd)) |
54 old = {} | 54 old = {} |
55 for k, v in args.items(): | 55 for k, v in args.items(): |
56 k = k.upper() | 56 k = k.upper() |
57 old['HG_' + k] = os.environ.get(k, None) | |
57 old[k] = os.environ.get(k, None) | 58 old[k] = os.environ.get(k, None) |
58 os.environ[k] = v | 59 os.environ['HG_' + k] = str(v) |
59 | 60 os.environ[k] = str(v) |
60 # Hooks run in the repository root | 61 |
61 olddir = os.getcwd() | 62 try: |
62 os.chdir(self.root) | 63 # Hooks run in the repository root |
63 r = os.system(cmd) | 64 olddir = os.getcwd() |
64 os.chdir(olddir) | 65 os.chdir(self.root) |
65 | 66 r = os.system(cmd) |
66 for k, v in old.items(): | 67 finally: |
67 if v != None: | 68 for k, v in old.items(): |
68 os.environ[k] = v | 69 if v is not None: |
69 else: | 70 os.environ[k] = v |
70 del os.environ[k] | 71 else: |
72 del os.environ[k] | |
73 | |
74 os.chdir(olddir) | |
71 | 75 |
72 if r: | 76 if r: |
73 self.ui.warn(_("abort: %s hook failed with status %d!\n") % | 77 desc, r = util.explain_exit(r) |
74 (name, r)) | 78 if throw: |
79 raise util.Abort(_('%s hook %s') % (name, desc)) | |
80 self.ui.warn(_('error: %s hook %s\n') % (name, desc)) | |
75 return False | 81 return False |
76 return True | 82 return True |
77 | 83 |
78 r = True | 84 r = True |
79 for hname, cmd in self.ui.configitems("hooks"): | 85 for hname, cmd in self.ui.configitems("hooks"): |
266 self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0]) | 272 self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0]) |
267 wlock = lock.lock(self.join("wlock"), wait, self.dirstate.write) | 273 wlock = lock.lock(self.join("wlock"), wait, self.dirstate.write) |
268 self.dirstate.read() | 274 self.dirstate.read() |
269 return wlock | 275 return wlock |
270 | 276 |
277 def checkfilemerge(self, filename, text, filelog, manifest1, manifest2): | |
278 "determine whether a new filenode is needed" | |
279 fp1 = manifest1.get(filename, nullid) | |
280 fp2 = manifest2.get(filename, nullid) | |
281 | |
282 if fp2 != nullid: | |
283 # is one parent an ancestor of the other? | |
284 fpa = filelog.ancestor(fp1, fp2) | |
285 if fpa == fp1: | |
286 fp1, fp2 = fp2, nullid | |
287 elif fpa == fp2: | |
288 fp2 = nullid | |
289 | |
290 # is the file unmodified from the parent? report existing entry | |
291 if fp2 == nullid and text == filelog.read(fp1): | |
292 return (fp1, None, None) | |
293 | |
294 return (None, fp1, fp2) | |
295 | |
271 def rawcommit(self, files, text, user, date, p1=None, p2=None, wlock=None): | 296 def rawcommit(self, files, text, user, date, p1=None, p2=None, wlock=None): |
272 orig_parent = self.dirstate.parents()[0] or nullid | 297 orig_parent = self.dirstate.parents()[0] or nullid |
273 p1 = p1 or self.dirstate.parents()[0] or nullid | 298 p1 = p1 or self.dirstate.parents()[0] or nullid |
274 p2 = p2 or self.dirstate.parents()[1] or nullid | 299 p2 = p2 or self.dirstate.parents()[1] or nullid |
275 c1 = self.changelog.read(p1) | 300 c1 = self.changelog.read(p1) |
296 t = self.wread(f) | 321 t = self.wread(f) |
297 tm = util.is_exec(self.wjoin(f), mfm.get(f, False)) | 322 tm = util.is_exec(self.wjoin(f), mfm.get(f, False)) |
298 r = self.file(f) | 323 r = self.file(f) |
299 mfm[f] = tm | 324 mfm[f] = tm |
300 | 325 |
301 fp1 = m1.get(f, nullid) | 326 (entry, fp1, fp2) = self.checkfilemerge(f, t, r, m1, m2) |
302 fp2 = m2.get(f, nullid) | 327 if entry: |
303 | 328 mm[f] = entry |
304 # is the same revision on two branches of a merge? | 329 continue |
305 if fp2 == fp1: | |
306 fp2 = nullid | |
307 | |
308 if fp2 != nullid: | |
309 # is one parent an ancestor of the other? | |
310 fpa = r.ancestor(fp1, fp2) | |
311 if fpa == fp1: | |
312 fp1, fp2 = fp2, nullid | |
313 elif fpa == fp2: | |
314 fp2 = nullid | |
315 | |
316 # is the file unmodified from the parent? | |
317 if t == r.read(fp1): | |
318 # record the proper existing parent in manifest | |
319 # no need to add a revision | |
320 mm[f] = fp1 | |
321 continue | |
322 | 330 |
323 mm[f] = r.add(t, {}, tr, linkrev, fp1, fp2) | 331 mm[f] = r.add(t, {}, tr, linkrev, fp1, fp2) |
324 changed.append(f) | 332 changed.append(f) |
325 if update_dirstate: | 333 if update_dirstate: |
326 self.dirstate.update([f], "n") | 334 self.dirstate.update([f], "n") |
370 | 378 |
371 if not commit and not remove and not force and p2 == nullid: | 379 if not commit and not remove and not force and p2 == nullid: |
372 self.ui.status(_("nothing changed\n")) | 380 self.ui.status(_("nothing changed\n")) |
373 return None | 381 return None |
374 | 382 |
375 if not self.hook("precommit"): | 383 xp1 = hex(p1) |
376 return None | 384 if p2 == nullid: xp2 = '' |
385 else: xp2 = hex(p2) | |
386 | |
387 self.hook("precommit", throw=True, parent1=xp1, parent2=xp2) | |
377 | 388 |
378 if not wlock: | 389 if not wlock: |
379 wlock = self.wlock() | 390 wlock = self.wlock() |
380 lock = self.lock() | 391 lock = self.lock() |
381 tr = self.transaction() | 392 tr = self.transaction() |
401 meta["copy"] = cp | 412 meta["copy"] = cp |
402 meta["copyrev"] = hex(m1.get(cp, m2.get(cp, nullid))) | 413 meta["copyrev"] = hex(m1.get(cp, m2.get(cp, nullid))) |
403 self.ui.debug(_(" %s: copy %s:%s\n") % (f, cp, meta["copyrev"])) | 414 self.ui.debug(_(" %s: copy %s:%s\n") % (f, cp, meta["copyrev"])) |
404 fp1, fp2 = nullid, nullid | 415 fp1, fp2 = nullid, nullid |
405 else: | 416 else: |
406 fp1 = m1.get(f, nullid) | 417 entry, fp1, fp2 = self.checkfilemerge(f, t, r, m1, m2) |
407 fp2 = m2.get(f, nullid) | 418 if entry: |
408 | 419 new[f] = entry |
409 if fp2 != nullid: | |
410 # is one parent an ancestor of the other? | |
411 fpa = r.ancestor(fp1, fp2) | |
412 if fpa == fp1: | |
413 fp1, fp2 = fp2, nullid | |
414 elif fpa == fp2: | |
415 fp2 = nullid | |
416 | |
417 # is the file unmodified from the parent? | |
418 if not meta and t == r.read(fp1) and fp2 == nullid: | |
419 # record the proper existing parent in manifest | |
420 # no need to add a revision | |
421 new[f] = fp1 | |
422 continue | 420 continue |
423 | 421 |
424 new[f] = r.add(t, meta, tr, linkrev, fp1, fp2) | 422 new[f] = r.add(t, meta, tr, linkrev, fp1, fp2) |
425 # remember what we've added so that we can later calculate | 423 # remember what we've added so that we can later calculate |
426 # the files to pull from a set of changesets | 424 # the files to pull from a set of changesets |
457 return None | 455 return None |
458 text = edittext | 456 text = edittext |
459 | 457 |
460 user = user or self.ui.username() | 458 user = user or self.ui.username() |
461 n = self.changelog.add(mn, changed + remove, text, tr, p1, p2, user, date) | 459 n = self.changelog.add(mn, changed + remove, text, tr, p1, p2, user, date) |
460 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1, | |
461 parent2=xp2) | |
462 tr.close() | 462 tr.close() |
463 | 463 |
464 self.dirstate.setparents(n) | 464 self.dirstate.setparents(n) |
465 self.dirstate.update(new, "n") | 465 self.dirstate.update(new, "n") |
466 self.dirstate.forget(remove) | 466 self.dirstate.forget(remove) |
467 | 467 |
468 if not self.hook("commit", node=hex(n)): | 468 self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2) |
469 return None | |
470 return n | 469 return n |
471 | 470 |
472 def walk(self, node=None, files=[], match=util.always): | 471 def walk(self, node=None, files=[], match=util.always): |
473 if node: | 472 if node: |
474 fdict = dict.fromkeys(files) | 473 fdict = dict.fromkeys(files) |
945 if not fetch: | 944 if not fetch: |
946 self.ui.status(_("no changes found\n")) | 945 self.ui.status(_("no changes found\n")) |
947 return 1 | 946 return 1 |
948 | 947 |
949 if heads is None: | 948 if heads is None: |
950 cg = remote.changegroup(fetch) | 949 cg = remote.changegroup(fetch, 'pull') |
951 else: | 950 else: |
952 cg = remote.changegroupsubset(fetch, heads) | 951 cg = remote.changegroupsubset(fetch, heads, 'pull') |
953 return self.addchangegroup(cg) | 952 return self.addchangegroup(cg) |
954 | 953 |
955 def push(self, remote, force=False): | 954 def push(self, remote, force=False): |
956 lock = remote.lock() | 955 lock = remote.lock() |
957 | 956 |
972 self.ui.warn(_("abort: push creates new remote branches!\n")) | 971 self.ui.warn(_("abort: push creates new remote branches!\n")) |
973 self.ui.status(_("(did you forget to merge?" | 972 self.ui.status(_("(did you forget to merge?" |
974 " use push -f to force)\n")) | 973 " use push -f to force)\n")) |
975 return 1 | 974 return 1 |
976 | 975 |
977 cg = self.changegroup(update) | 976 cg = self.changegroup(update, 'push') |
978 return remote.addchangegroup(cg) | 977 return remote.addchangegroup(cg) |
979 | 978 |
980 def changegroupsubset(self, bases, heads): | 979 def changegroupsubset(self, bases, heads, source): |
981 """This function generates a changegroup consisting of all the nodes | 980 """This function generates a changegroup consisting of all the nodes |
982 that are descendents of any of the bases, and ancestors of any of | 981 that are descendents of any of the bases, and ancestors of any of |
983 the heads. | 982 the heads. |
984 | 983 |
985 It is fairly complex as determining which filenodes and which | 984 It is fairly complex as determining which filenodes and which |
986 manifest nodes need to be included for the changeset to be complete | 985 manifest nodes need to be included for the changeset to be complete |
987 is non-trivial. | 986 is non-trivial. |
988 | 987 |
989 Another wrinkle is doing the reverse, figuring out which changeset in | 988 Another wrinkle is doing the reverse, figuring out which changeset in |
990 the changegroup a particular filenode or manifestnode belongs to.""" | 989 the changegroup a particular filenode or manifestnode belongs to.""" |
990 | |
991 self.hook('preoutgoing', throw=True, source=source) | |
991 | 992 |
992 # Set up some initial variables | 993 # Set up some initial variables |
993 # Make it easy to refer to self.changelog | 994 # Make it easy to refer to self.changelog |
994 cl = self.changelog | 995 cl = self.changelog |
995 # msng is short for missing - compute the list of changesets in this | 996 # msng is short for missing - compute the list of changesets in this |
1239 # Don't need this anymore, toss it to free memory. | 1240 # Don't need this anymore, toss it to free memory. |
1240 del msng_filenode_set[fname] | 1241 del msng_filenode_set[fname] |
1241 # Signal that no more groups are left. | 1242 # Signal that no more groups are left. |
1242 yield struct.pack(">l", 0) | 1243 yield struct.pack(">l", 0) |
1243 | 1244 |
1245 self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source) | |
1246 | |
1244 return util.chunkbuffer(gengroup()) | 1247 return util.chunkbuffer(gengroup()) |
1245 | 1248 |
1246 def changegroup(self, basenodes): | 1249 def changegroup(self, basenodes, source): |
1247 """Generate a changegroup of all nodes that we have that a recipient | 1250 """Generate a changegroup of all nodes that we have that a recipient |
1248 doesn't. | 1251 doesn't. |
1249 | 1252 |
1250 This is much easier than the previous function as we can assume that | 1253 This is much easier than the previous function as we can assume that |
1251 the recipient has any changenode we aren't sending them.""" | 1254 the recipient has any changenode we aren't sending them.""" |
1255 | |
1256 self.hook('preoutgoing', throw=True, source=source) | |
1257 | |
1252 cl = self.changelog | 1258 cl = self.changelog |
1253 nodes = cl.nodesbetween(basenodes, None)[0] | 1259 nodes = cl.nodesbetween(basenodes, None)[0] |
1254 revset = dict.fromkeys([cl.rev(n) for n in nodes]) | 1260 revset = dict.fromkeys([cl.rev(n) for n in nodes]) |
1255 | 1261 |
1256 def identity(x): | 1262 def identity(x): |
1298 lookup = lookuprevlink_func(filerevlog) | 1304 lookup = lookuprevlink_func(filerevlog) |
1299 for chnk in filerevlog.group(nodeiter, lookup): | 1305 for chnk in filerevlog.group(nodeiter, lookup): |
1300 yield chnk | 1306 yield chnk |
1301 | 1307 |
1302 yield struct.pack(">l", 0) | 1308 yield struct.pack(">l", 0) |
1309 self.hook('outgoing', node=hex(nodes[0]), source=source) | |
1303 | 1310 |
1304 return util.chunkbuffer(gengroup()) | 1311 return util.chunkbuffer(gengroup()) |
1305 | 1312 |
1306 def addchangegroup(self, source): | 1313 def addchangegroup(self, source): |
1307 | 1314 |
1333 def revmap(x): | 1340 def revmap(x): |
1334 return self.changelog.rev(x) | 1341 return self.changelog.rev(x) |
1335 | 1342 |
1336 if not source: | 1343 if not source: |
1337 return | 1344 return |
1345 | |
1346 self.hook('prechangegroup', throw=True) | |
1347 | |
1338 changesets = files = revisions = 0 | 1348 changesets = files = revisions = 0 |
1339 | 1349 |
1340 tr = self.transaction() | 1350 tr = self.transaction() |
1341 | 1351 |
1342 oldheads = len(self.changelog.heads()) | 1352 oldheads = len(self.changelog.heads()) |
1375 | 1385 |
1376 self.ui.status(_("added %d changesets" | 1386 self.ui.status(_("added %d changesets" |
1377 " with %d changes to %d files%s\n") | 1387 " with %d changes to %d files%s\n") |
1378 % (changesets, revisions, files, heads)) | 1388 % (changesets, revisions, files, heads)) |
1379 | 1389 |
1390 self.hook('pretxnchangegroup', throw=True, | |
1391 node=hex(self.changelog.node(cor+1))) | |
1392 | |
1380 tr.close() | 1393 tr.close() |
1381 | 1394 |
1382 if changesets > 0: | 1395 if changesets > 0: |
1383 if not self.hook("changegroup", | 1396 self.hook("changegroup", node=hex(self.changelog.node(cor+1))) |
1384 node=hex(self.changelog.node(cor+1))): | |
1385 self.ui.warn(_("abort: changegroup hook returned failure!\n")) | |
1386 return 1 | |
1387 | 1397 |
1388 for i in range(cor + 1, cnr + 1): | 1398 for i in range(cor + 1, cnr + 1): |
1389 self.hook("incoming", node=hex(self.changelog.node(i))) | 1399 self.hook("incoming", node=hex(self.changelog.node(i))) |
1390 | |
1391 return | |
1392 | 1400 |
1393 def update(self, node, allow=False, force=False, choose=None, | 1401 def update(self, node, allow=False, force=False, choose=None, |
1394 moddirstate=True, forcemerge=False, wlock=None): | 1402 moddirstate=True, forcemerge=False, wlock=None): |
1395 pl = self.dirstate.parents() | 1403 pl = self.dirstate.parents() |
1396 if not force and pl[1] != nullid: | 1404 if not force and pl[1] != nullid: |