##// END OF EJS Templates
branch closing: referencing open and closed branches/heads...
branch closing: referencing open and closed branches/heads Treat fully closed branches similarly to "inactive" in the output of 'hg branches'. They will be suffixed with "(closed)" where inactive branches are marked with "(inactive)". If the -a/--active option is given both inactive and closed branches will not be shown. Partially closed branches (multiple heads, at least one not closed) will display the next (tipmost) open head. Add -a/--active option to "hg heads" which will hide closed heads iff the option is specified. In other hg commands, when multiple branch heads exist the branch name will refer to the tipmost open head, and if none exist, then the tipmost closed head.

File last commit:

r4270:29eb88bd default
r7656:6a24fb99 default
Show More
hg-relink
128 lines | 3.5 KiB | text/plain | TextLexer
Brendan Cully
Add hg-relink script to contrib
r4249 #!/usr/bin/env python
#
# Copyright (C) 2007 Brendan Cully <brendan@kublai.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
import os, sys
class ConfigError(Exception): pass
def usage():
print """relink <source> <destination>
Recreate hard links between source and destination repositories"""
class Config:
def __init__(self, args):
if len(args) != 3:
raise ConfigError("wrong number of arguments")
self.src = os.path.abspath(args[1])
self.dst = os.path.abspath(args[2])
for d in (self.src, self.dst):
if not os.path.exists(os.path.join(d, '.hg')):
raise ConfigError("%s: not a mercurial repository" % d)
def collect(src):
seplen = len(os.path.sep)
candidates = []
for dirpath, dirnames, filenames in os.walk(src):
relpath = dirpath[len(src) + seplen:]
for filename in filenames:
Brendan Cully
hg-relink: do not compare .d files
r4270 if not filename.endswith('.i'):
Brendan Cully
Add hg-relink script to contrib
r4249 continue
st = os.stat(os.path.join(dirpath, filename))
candidates.append((os.path.join(relpath, filename), st))
return candidates
def prune(candidates, dst):
Brendan Cully
hg-relink: do not compare .d files
r4270 def getdatafile(path):
if not path.endswith('.i'):
return None, None
df = path[:-1] + 'd'
try:
st = os.stat(df)
except OSError:
return None, None
return df, st
def linkfilter(dst, st):
try:
ts = os.stat(dst)
except OSError:
# Destination doesn't have this file?
return False
if st.st_ino == ts.st_ino:
return False
if st.st_dev != ts.st_dev:
# No point in continuing
raise Exception('Source and destination are on different devices')
if st.st_size != ts.st_size:
# TODO: compare revlog heads
return False
return st
Brendan Cully
Add hg-relink script to contrib
r4249 targets = []
for fn, st in candidates:
tgt = os.path.join(dst, fn)
Brendan Cully
hg-relink: do not compare .d files
r4270 ts = linkfilter(tgt, st)
if not ts:
Brendan Cully
Add hg-relink script to contrib
r4249 continue
targets.append((fn, ts.st_size))
Brendan Cully
hg-relink: do not compare .d files
r4270 df, ts = getdatafile(tgt)
if df:
targets.append((fn[:-1] + 'd', ts.st_size))
Brendan Cully
Add hg-relink script to contrib
r4249
return targets
def relink(src, dst, files):
Brendan Cully
hg-relink: do not compare .d files
r4270 def relinkfile(src, dst):
bak = dst + '.bak'
os.rename(dst, bak)
try:
os.link(src, dst)
except OSError:
os.rename(bak, dst)
raise
os.remove(bak)
Brendan Cully
Add hg-relink script to contrib
r4249 CHUNKLEN = 65536
relinked = 0
savedbytes = 0
for f, sz in files:
source = os.path.join(src, f)
tgt = os.path.join(dst, f)
sfp = file(source)
dfp = file(tgt)
sin = sfp.read(CHUNKLEN)
while sin:
din = dfp.read(CHUNKLEN)
if sin != din:
break
sin = sfp.read(CHUNKLEN)
if sin:
continue
try:
Brendan Cully
hg-relink: do not compare .d files
r4270 relinkfile(source, tgt)
Brendan Cully
Add hg-relink script to contrib
r4249 print 'Relinked %s' % f
relinked += 1
savedbytes += sz
except OSError, inst:
print '%s: %s' % (tgt, str(inst))
print 'Relinked %d files (%d bytes reclaimed)' % (relinked, savedbytes)
Brendan Cully
hg-relink: do not compare .d files
r4270 try:
cfg = Config(sys.argv)
except ConfigError, inst:
print str(inst)
usage()
sys.exit(1)
Brendan Cully
Add hg-relink script to contrib
r4249 src = os.path.join(cfg.src, '.hg')
dst = os.path.join(cfg.dst, '.hg')
candidates = collect(src)
targets = prune(candidates, dst)
relink(src, dst, targets)