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 |
|
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, |
|
220 | def copyfiles(src, dst, hardlink=None): | |
221 |
"""Copy a directory tree |
|
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, |
|
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 |
|
|
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 |
|
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