##// 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 if other.dev() != -1:
621 if other.dev() != -1:
622 abspath = os.path.abspath(source)
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 # we use a lock here because if we race with commit, we can
624 # we use a lock here because if we race with commit, we can
629 # end up with extra data in the cloned revlogs that's not
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 for f in files.split():
634 for f in files.split():
639 src = os.path.join(source, ".hg", f)
635 src = os.path.join(source, ".hg", f)
640 dst = os.path.join(dest, ".hg", f)
636 dst = os.path.join(dest, ".hg", f)
641 util.copyfiles(src, dst, copyfile)
637 util.copyfiles(src, dst)
642
638
643 repo = hg.repository(ui, dest)
639 repo = hg.repository(ui, dest)
644
640
@@ -12,7 +12,7 b' platform-specific details from the core.'
12
12
13 import os, errno
13 import os, errno
14 from demandload import *
14 from demandload import *
15 demandload(globals(), "re cStringIO")
15 demandload(globals(), "re cStringIO shutil")
16
16
17 def binary(s):
17 def binary(s):
18 """return true if a string is binary data using diff's heuristic"""
18 """return true if a string is binary data using diff's heuristic"""
@@ -217,17 +217,28 b' def rename(src, dst):'
217 os.unlink(dst)
217 os.unlink(dst)
218 os.rename(src, dst)
218 os.rename(src, dst)
219
219
220 def copyfiles(src, dst, copyfile):
220 def copyfiles(src, dst, hardlink=None):
221 """Copy a directory tree, files are copied using 'copyfile'."""
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 if os.path.isdir(src):
227 if os.path.isdir(src):
224 os.mkdir(dst)
228 os.mkdir(dst)
225 for name in os.listdir(src):
229 for name in os.listdir(src):
226 srcname = os.path.join(src, name)
230 srcname = os.path.join(src, name)
227 dstname = os.path.join(dst, name)
231 dstname = os.path.join(dst, name)
228 copyfiles(srcname, dstname, copyfile)
232 copyfiles(srcname, dstname, hardlink)
229 else:
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 def opener(base):
243 def opener(base):
233 """
244 """
@@ -244,13 +255,13 b' def opener(base):'
244
255
245 if mode[0] != "r":
256 if mode[0] != "r":
246 try:
257 try:
247 s = os.stat(f)
258 nlink = nlinks(f)
248 except OSError:
259 except OSError:
249 d = os.path.dirname(f)
260 d = os.path.dirname(f)
250 if not os.path.isdir(d):
261 if not os.path.isdir(d):
251 os.makedirs(d)
262 os.makedirs(d)
252 else:
263 else:
253 if s.st_nlink > 1:
264 if nlink > 1:
254 file(f + ".tmp", "wb").write(file(f, "rb").read())
265 file(f + ".tmp", "wb").write(file(f, "rb").read())
255 rename(f+".tmp", f)
266 rename(f+".tmp", f)
256
267
@@ -266,10 +277,41 b' def _makelock_file(info, pathname):'
266 def _readlock_file(pathname):
277 def _readlock_file(pathname):
267 return file(pathname).read()
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 # Platform specific variants
290 # Platform specific variants
270 if os.name == 'nt':
291 if os.name == 'nt':
271 nulldev = 'NUL:'
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 def is_exec(f, last):
315 def is_exec(f, last):
274 return last
316 return last
275
317
General Comments 0
You need to be logged in to leave comments. Login now