comparison mercurial/localrepo.py @ 1737:2c9872a4f3fd

Merge with crew
author Matt Mackall <mpm@selenic.com>
date Fri, 17 Feb 2006 17:39:05 -0600
parents ef8cd889a78b 50de0887bbcd
children 91c56c427171
comparison
equal deleted inserted replaced
1716:ef8cd889a78b 1737:2c9872a4f3fd
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"):
372 378
373 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:
374 self.ui.status(_("nothing changed\n")) 380 self.ui.status(_("nothing changed\n"))
375 return None 381 return None
376 382
377 if not self.hook("precommit"): 383 xp1 = hex(p1)
378 return None 384 if p2 == nullid: xp2 = ''
385 else: xp2 = hex(p2)
386
387 self.hook("precommit", throw=True, parent1=xp1, parent2=xp2)
379 388
380 if not wlock: 389 if not wlock:
381 wlock = self.wlock() 390 wlock = self.wlock()
382 lock = self.lock() 391 lock = self.lock()
383 tr = self.transaction() 392 tr = self.transaction()
446 return None 455 return None
447 text = edittext 456 text = edittext
448 457
449 user = user or self.ui.username() 458 user = user or self.ui.username()
450 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)
451 tr.close() 462 tr.close()
452 463
453 self.dirstate.setparents(n) 464 self.dirstate.setparents(n)
454 self.dirstate.update(new, "n") 465 self.dirstate.update(new, "n")
455 self.dirstate.forget(remove) 466 self.dirstate.forget(remove)
456 467
457 if not self.hook("commit", node=hex(n)): 468 self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2)
458 return None
459 return n 469 return n
460 470
461 def walk(self, node=None, files=[], match=util.always): 471 def walk(self, node=None, files=[], match=util.always):
462 if node: 472 if node:
463 fdict = dict.fromkeys(files) 473 fdict = dict.fromkeys(files)
934 if not fetch: 944 if not fetch:
935 self.ui.status(_("no changes found\n")) 945 self.ui.status(_("no changes found\n"))
936 return 1 946 return 1
937 947
938 if heads is None: 948 if heads is None:
939 cg = remote.changegroup(fetch) 949 cg = remote.changegroup(fetch, 'pull')
940 else: 950 else:
941 cg = remote.changegroupsubset(fetch, heads) 951 cg = remote.changegroupsubset(fetch, heads, 'pull')
942 return self.addchangegroup(cg) 952 return self.addchangegroup(cg)
943 953
944 def push(self, remote, force=False): 954 def push(self, remote, force=False):
945 lock = remote.lock() 955 lock = remote.lock()
946 956
961 self.ui.warn(_("abort: push creates new remote branches!\n")) 971 self.ui.warn(_("abort: push creates new remote branches!\n"))
962 self.ui.status(_("(did you forget to merge?" 972 self.ui.status(_("(did you forget to merge?"
963 " use push -f to force)\n")) 973 " use push -f to force)\n"))
964 return 1 974 return 1
965 975
966 cg = self.changegroup(update) 976 cg = self.changegroup(update, 'push')
967 return remote.addchangegroup(cg) 977 return remote.addchangegroup(cg)
968 978
969 def changegroupsubset(self, bases, heads): 979 def changegroupsubset(self, bases, heads, source):
970 """This function generates a changegroup consisting of all the nodes 980 """This function generates a changegroup consisting of all the nodes
971 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
972 the heads. 982 the heads.
973 983
974 It is fairly complex as determining which filenodes and which 984 It is fairly complex as determining which filenodes and which
975 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
976 is non-trivial. 986 is non-trivial.
977 987
978 Another wrinkle is doing the reverse, figuring out which changeset in 988 Another wrinkle is doing the reverse, figuring out which changeset in
979 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)
980 992
981 # Set up some initial variables 993 # Set up some initial variables
982 # Make it easy to refer to self.changelog 994 # Make it easy to refer to self.changelog
983 cl = self.changelog 995 cl = self.changelog
984 # 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
1228 # Don't need this anymore, toss it to free memory. 1240 # Don't need this anymore, toss it to free memory.
1229 del msng_filenode_set[fname] 1241 del msng_filenode_set[fname]
1230 # Signal that no more groups are left. 1242 # Signal that no more groups are left.
1231 yield struct.pack(">l", 0) 1243 yield struct.pack(">l", 0)
1232 1244
1245 self.hook('outgoing', node=hex(msng_cl_lst[0]), source=source)
1246
1233 return util.chunkbuffer(gengroup()) 1247 return util.chunkbuffer(gengroup())
1234 1248
1235 def changegroup(self, basenodes): 1249 def changegroup(self, basenodes, source):
1236 """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
1237 doesn't. 1251 doesn't.
1238 1252
1239 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
1240 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
1241 cl = self.changelog 1258 cl = self.changelog
1242 nodes = cl.nodesbetween(basenodes, None)[0] 1259 nodes = cl.nodesbetween(basenodes, None)[0]
1243 revset = dict.fromkeys([cl.rev(n) for n in nodes]) 1260 revset = dict.fromkeys([cl.rev(n) for n in nodes])
1244 1261
1245 def identity(x): 1262 def identity(x):
1287 lookup = lookuprevlink_func(filerevlog) 1304 lookup = lookuprevlink_func(filerevlog)
1288 for chnk in filerevlog.group(nodeiter, lookup): 1305 for chnk in filerevlog.group(nodeiter, lookup):
1289 yield chnk 1306 yield chnk
1290 1307
1291 yield struct.pack(">l", 0) 1308 yield struct.pack(">l", 0)
1309 self.hook('outgoing', node=hex(nodes[0]), source=source)
1292 1310
1293 return util.chunkbuffer(gengroup()) 1311 return util.chunkbuffer(gengroup())
1294 1312
1295 def addchangegroup(self, source): 1313 def addchangegroup(self, source):
1296 1314
1322 def revmap(x): 1340 def revmap(x):
1323 return self.changelog.rev(x) 1341 return self.changelog.rev(x)
1324 1342
1325 if not source: 1343 if not source:
1326 return 1344 return
1345
1346 self.hook('prechangegroup', throw=True)
1347
1327 changesets = files = revisions = 0 1348 changesets = files = revisions = 0
1328 1349
1329 tr = self.transaction() 1350 tr = self.transaction()
1330 1351
1331 oldheads = len(self.changelog.heads()) 1352 oldheads = len(self.changelog.heads())
1364 1385
1365 self.ui.status(_("added %d changesets" 1386 self.ui.status(_("added %d changesets"
1366 " with %d changes to %d files%s\n") 1387 " with %d changes to %d files%s\n")
1367 % (changesets, revisions, files, heads)) 1388 % (changesets, revisions, files, heads))
1368 1389
1390 self.hook('pretxnchangegroup', throw=True,
1391 node=hex(self.changelog.node(cor+1)))
1392
1369 tr.close() 1393 tr.close()
1370 1394
1371 if changesets > 0: 1395 if changesets > 0:
1372 if not self.hook("changegroup", 1396 self.hook("changegroup", node=hex(self.changelog.node(cor+1)))
1373 node=hex(self.changelog.node(cor+1))):
1374 self.ui.warn(_("abort: changegroup hook returned failure!\n"))
1375 return 1
1376 1397
1377 for i in range(cor + 1, cnr + 1): 1398 for i in range(cor + 1, cnr + 1):
1378 self.hook("incoming", node=hex(self.changelog.node(i))) 1399 self.hook("incoming", node=hex(self.changelog.node(i)))
1379
1380 return
1381 1400
1382 def update(self, node, allow=False, force=False, choose=None, 1401 def update(self, node, allow=False, force=False, choose=None,
1383 moddirstate=True, forcemerge=False, wlock=None): 1402 moddirstate=True, forcemerge=False, wlock=None):
1384 pl = self.dirstate.parents() 1403 pl = self.dirstate.parents()
1385 if not force and pl[1] != nullid: 1404 if not force and pl[1] != nullid: