292 # hgsep => pathname that uses "/" to separate directories |
292 # hgsep => pathname that uses "/" to separate directories |
293 # ossep => pathname that uses os.sep to separate directories |
293 # ossep => pathname that uses os.sep to separate directories |
294 cwd = repo.getcwd() |
294 cwd = repo.getcwd() |
295 copied = [] |
295 copied = [] |
296 targets = {} |
296 targets = {} |
|
297 after = opts.get("after") |
|
298 dryrun = opts.get("dry_run") |
297 |
299 |
298 def walkpat(pat): |
300 def walkpat(pat): |
299 srcs = [] |
301 srcs = [] |
300 for tag, abs, rel, exact in walk(repo, [pat], opts, globbed=True): |
302 for tag, abs, rel, exact in walk(repo, [pat], opts, globbed=True): |
301 state = repo.dirstate[abs] |
303 state = repo.dirstate[abs] |
315 # relsrc: ossep |
317 # relsrc: ossep |
316 # otarget: ossep |
318 # otarget: ossep |
317 def copyfile(abssrc, relsrc, otarget, exact): |
319 def copyfile(abssrc, relsrc, otarget, exact): |
318 abstarget = util.canonpath(repo.root, cwd, otarget) |
320 abstarget = util.canonpath(repo.root, cwd, otarget) |
319 reltarget = repo.pathto(abstarget, cwd) |
321 reltarget = repo.pathto(abstarget, cwd) |
|
322 target = repo.wjoin(abstarget) |
|
323 src = repo.wjoin(abssrc) |
|
324 |
|
325 # check for collisions |
320 prevsrc = targets.get(abstarget) |
326 prevsrc = targets.get(abstarget) |
321 src = repo.wjoin(abssrc) |
|
322 target = repo.wjoin(abstarget) |
|
323 if prevsrc is not None: |
327 if prevsrc is not None: |
324 ui.warn(_('%s: not overwriting - %s collides with %s\n') % |
328 ui.warn(_('%s: not overwriting - %s collides with %s\n') % |
325 (reltarget, repo.pathto(abssrc, cwd), |
329 (reltarget, repo.pathto(abssrc, cwd), |
326 repo.pathto(prevsrc, cwd))) |
330 repo.pathto(prevsrc, cwd))) |
327 return |
331 return |
328 if (not opts['after'] and os.path.exists(target) or |
332 |
329 opts['after'] and repo.dirstate[abstarget] in 'mn'): |
333 # check for overwrites |
|
334 if (not after and os.path.exists(target) or |
|
335 after and repo.dirstate[abstarget] in 'mn'): |
330 if not opts['force']: |
336 if not opts['force']: |
331 ui.warn(_('%s: not overwriting - file exists\n') % |
337 ui.warn(_('%s: not overwriting - file exists\n') % |
332 reltarget) |
338 reltarget) |
333 return |
339 return |
334 if not opts['after'] and not opts.get('dry_run'): |
340 if not after and not dryrun: |
335 os.unlink(target) |
341 os.unlink(target) |
336 if opts['after']: |
342 |
|
343 if after: |
337 if not os.path.exists(target): |
344 if not os.path.exists(target): |
338 return |
345 return |
339 else: |
346 else: |
340 targetdir = os.path.dirname(target) or '.' |
347 targetdir = os.path.dirname(target) or '.' |
341 if not os.path.isdir(targetdir) and not opts.get('dry_run'): |
348 if not os.path.isdir(targetdir) and not dryrun: |
342 os.makedirs(targetdir) |
349 os.makedirs(targetdir) |
343 try: |
350 try: |
344 restore = repo.dirstate[abstarget] == 'r' |
351 restore = repo.dirstate[abstarget] == 'r' |
345 if restore and not opts.get('dry_run'): |
352 if restore and not dryrun: |
346 repo.undelete([abstarget]) |
353 repo.undelete([abstarget]) |
347 try: |
354 try: |
348 if not opts.get('dry_run'): |
355 if not dryrun: |
349 util.copyfile(src, target) |
356 util.copyfile(src, target) |
350 restore = False |
357 restore = False |
351 finally: |
358 finally: |
352 if restore: |
359 if restore: |
353 repo.remove([abstarget]) |
360 repo.remove([abstarget]) |
356 ui.warn(_('%s: deleted in working copy\n') % relsrc) |
363 ui.warn(_('%s: deleted in working copy\n') % relsrc) |
357 else: |
364 else: |
358 ui.warn(_('%s: cannot copy - %s\n') % |
365 ui.warn(_('%s: cannot copy - %s\n') % |
359 (relsrc, inst.strerror)) |
366 (relsrc, inst.strerror)) |
360 return True # report a failure |
367 return True # report a failure |
|
368 |
361 if ui.verbose or not exact: |
369 if ui.verbose or not exact: |
362 ui.status(_('copying %s to %s\n') % (relsrc, reltarget)) |
370 ui.status(_('copying %s to %s\n') % (relsrc, reltarget)) |
363 targets[abstarget] = abssrc |
371 targets[abstarget] = abssrc |
|
372 |
|
373 # fix up dirstate |
364 origsrc = repo.dirstate.copied(abssrc) or abssrc |
374 origsrc = repo.dirstate.copied(abssrc) or abssrc |
365 if abstarget == origsrc: # copying back a copy? |
375 if abstarget == origsrc: # copying back a copy? |
366 if repo.dirstate[abstarget] not in 'mn': |
376 if repo.dirstate[abstarget] not in 'mn': |
367 if not opts.get('dry_run'): |
377 if not dryrun: |
368 repo.add([abstarget]) |
378 repo.add([abstarget]) |
369 else: |
379 else: |
370 if repo.dirstate[origsrc] == 'a': |
380 if repo.dirstate[origsrc] == 'a': |
371 if not ui.quiet: |
381 if not ui.quiet: |
372 ui.warn(_("%s has not been committed yet, so no copy " |
382 ui.warn(_("%s has not been committed yet, so no copy " |
373 "data will be stored for %s.\n") |
383 "data will be stored for %s.\n") |
374 % (repo.pathto(origsrc, cwd), reltarget)) |
384 % (repo.pathto(origsrc, cwd), reltarget)) |
375 if abstarget not in repo.dirstate and not opts.get('dry_run'): |
385 if abstarget not in repo.dirstate and not dryrun: |
376 repo.add([abstarget]) |
386 repo.add([abstarget]) |
377 elif not opts.get('dry_run'): |
387 elif not dryrun: |
378 repo.copy(origsrc, abstarget) |
388 repo.copy(origsrc, abstarget) |
379 copied.append((abssrc, relsrc, exact)) |
389 copied.append((abssrc, relsrc, exact)) |
380 |
390 |
381 # pat: ossep |
391 # pat: ossep |
382 # dest ossep |
392 # dest ossep |
456 if len(pats) > 1 or util.patkind(pats[0], None)[0]: |
466 if len(pats) > 1 or util.patkind(pats[0], None)[0]: |
457 raise util.Abort(_('with multiple sources, destination must be an ' |
467 raise util.Abort(_('with multiple sources, destination must be an ' |
458 'existing directory')) |
468 'existing directory')) |
459 if dest.endswith(os.sep) or os.altsep and dest.endswith(os.altsep): |
469 if dest.endswith(os.sep) or os.altsep and dest.endswith(os.altsep): |
460 raise util.Abort(_('destination %s is not a directory') % dest) |
470 raise util.Abort(_('destination %s is not a directory') % dest) |
461 if opts['after']: |
471 |
|
472 tfn = targetpathfn |
|
473 if after: |
462 tfn = targetpathafterfn |
474 tfn = targetpathafterfn |
463 else: |
|
464 tfn = targetpathfn |
|
465 copylist = [] |
475 copylist = [] |
466 for pat in pats: |
476 for pat in pats: |
467 srcs = walkpat(pat) |
477 srcs = walkpat(pat) |
468 if not srcs: |
478 if not srcs: |
469 continue |
479 continue |