##// END OF EJS Templates
Add support for cloning with hardlinks on windows....
Stephen Darnell -
r1241:3b4f05ff default
parent child Browse files
Show More
@@ -620,10 +620,6 b' def clone(ui, source, dest=None, **opts)'
620 620
621 621 if other.dev() != -1:
622 622 abspath = os.path.abspath(source)
623 copyfile = (os.stat(dest).st_dev == other.dev()
624 and getattr(os, 'link', None) or shutil.copy2)
625 if copyfile is not shutil.copy2:
626 ui.note("cloning by hardlink\n")
627 623
628 624 # we use a lock here because if we race with commit, we can
629 625 # end up with extra data in the cloned revlogs that's not
@@ -638,7 +634,7 b' def clone(ui, source, dest=None, **opts)'
638 634 for f in files.split():
639 635 src = os.path.join(source, ".hg", f)
640 636 dst = os.path.join(dest, ".hg", f)
641 util.copyfiles(src, dst, copyfile)
637 util.copyfiles(src, dst)
642 638
643 639 repo = hg.repository(ui, dest)
644 640
@@ -12,7 +12,7 b' platform-specific details from the core.'
12 12
13 13 import os, errno
14 14 from demandload import *
15 demandload(globals(), "re cStringIO")
15 demandload(globals(), "re cStringIO shutil")
16 16
17 17 def binary(s):
18 18 """return true if a string is binary data using diff's heuristic"""
@@ -217,17 +217,28 b' def rename(src, dst):'
217 217 os.unlink(dst)
218 218 os.rename(src, dst)
219 219
220 def copyfiles(src, dst, copyfile):
221 """Copy a directory tree, files are copied using 'copyfile'."""
220 def copyfiles(src, dst, hardlink=None):
221 """Copy a directory tree using hardlinks if possible"""
222
223 if hardlink is None:
224 hardlink = (os.stat(src).st_dev ==
225 os.stat(os.path.dirname(dst)).st_dev)
222 226
223 227 if os.path.isdir(src):
224 228 os.mkdir(dst)
225 229 for name in os.listdir(src):
226 230 srcname = os.path.join(src, name)
227 231 dstname = os.path.join(dst, name)
228 copyfiles(srcname, dstname, copyfile)
232 copyfiles(srcname, dstname, hardlink)
229 233 else:
230 copyfile(src, dst)
234 if hardlink:
235 try:
236 os_link(src, dst)
237 except:
238 hardlink = False
239 shutil.copy2(src, dst)
240 else:
241 shutil.copy2(src, dst)
231 242
232 243 def opener(base):
233 244 """
@@ -244,13 +255,13 b' def opener(base):'
244 255
245 256 if mode[0] != "r":
246 257 try:
247 s = os.stat(f)
258 nlink = nlinks(f)
248 259 except OSError:
249 260 d = os.path.dirname(f)
250 261 if not os.path.isdir(d):
251 262 os.makedirs(d)
252 263 else:
253 if s.st_nlink > 1:
264 if nlink > 1:
254 265 file(f + ".tmp", "wb").write(file(f, "rb").read())
255 266 rename(f+".tmp", f)
256 267
@@ -266,10 +277,41 b' def _makelock_file(info, pathname):'
266 277 def _readlock_file(pathname):
267 278 return file(pathname).read()
268 279
280 def nlinks(pathname):
281 """Return number of hardlinks for the given file."""
282 return os.stat(pathname).st_nlink
283
284 if hasattr(os, 'link'):
285 os_link = os.link
286 else:
287 def os_link(src, dst):
288 raise OSError(0, "Hardlinks not supported")
289
269 290 # Platform specific variants
270 291 if os.name == 'nt':
271 292 nulldev = 'NUL:'
272 293
294 try: # ActivePython can create hard links using win32file module
295 import win32file
296
297 def os_link(src, dst): # NB will only succeed on NTFS
298 win32file.CreateHardLink(dst, src)
299
300 def nlinks(pathname):
301 """Return number of hardlinks for the given file."""
302 try:
303 fh = win32file.CreateFile(pathname,
304 win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
305 None, win32file.OPEN_EXISTING, 0, None)
306 res = win32file.GetFileInformationByHandle(fh)
307 fh.Close()
308 return res[7]
309 except:
310 return os.stat(pathname).st_nlink
311
312 except ImportError:
313 pass
314
273 315 def is_exec(f, last):
274 316 return last
275 317
General Comments 0
You need to be logged in to leave comments. Login now