Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/commands.py @ 1253:a45e717c61a8
Add rename/mv command.
This is the logical equivalent of copy and remove, and is in fact
implemented as such. It doesn't use the remove command directly.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Wed, 14 Sep 2005 16:34:22 -0700 |
parents | 0ad3f9b27260 |
children | e6560042b7b8 |
comparison
equal
deleted
inserted
replaced
1252:94f38724283f | 1253:a45e717c61a8 |
---|---|
694 try: | 694 try: |
695 repo.commit(files, message, opts['user'], opts['date'], match) | 695 repo.commit(files, message, opts['user'], opts['date'], match) |
696 except ValueError, inst: | 696 except ValueError, inst: |
697 raise util.Abort(str(inst)) | 697 raise util.Abort(str(inst)) |
698 | 698 |
699 def copy(ui, repo, *pats, **opts): | 699 def docopy(ui, repo, pats, opts): |
700 """mark files as copied for the next commit""" | |
701 if not pats: | 700 if not pats: |
702 raise util.Abort('no source or destination specified') | 701 raise util.Abort('no source or destination specified') |
703 elif len(pats) == 1: | 702 elif len(pats) == 1: |
704 raise util.Abort('no destination specified') | 703 raise util.Abort('no destination specified') |
705 pats = list(pats) | 704 pats = list(pats) |
733 if opts['parents']: | 732 if opts['parents']: |
734 raise util.Abort('with --parents, destination must be a directory') | 733 raise util.Abort('with --parents, destination must be a directory') |
735 elif len(sources) > 1: | 734 elif len(sources) > 1: |
736 raise util.Abort('with multiple sources, destination must be a ' | 735 raise util.Abort('with multiple sources, destination must be a ' |
737 'directory') | 736 'directory') |
738 errs = 0 | 737 errs, copied = 0, [] |
739 for abs, rel, exact in sources: | 738 for abs, rel, exact in sources: |
740 if opts['parents']: | 739 if opts['parents']: |
741 mydest = os.path.join(dest, rel) | 740 mydest = os.path.join(dest, rel) |
742 elif destisfile: | 741 elif destisfile: |
743 mydest = reldest | 742 mydest = reldest |
761 try: | 760 try: |
762 shutil.copyfile(rel, myreldest) | 761 shutil.copyfile(rel, myreldest) |
763 n = repo.manifest.tip() | 762 n = repo.manifest.tip() |
764 mf = repo.manifest.readflags(n) | 763 mf = repo.manifest.readflags(n) |
765 util.set_exec(myreldest, util.is_exec(rel, mf[abs])) | 764 util.set_exec(myreldest, util.is_exec(rel, mf[abs])) |
765 except shutil.Error, inst: | |
766 raise util.Abort(str(inst)) | |
766 except IOError, inst: | 767 except IOError, inst: |
767 if inst.errno == errno.ENOENT: | 768 if inst.errno == errno.ENOENT: |
768 ui.warn('%s: deleted in working copy\n' % rel) | 769 ui.warn('%s: deleted in working copy\n' % rel) |
769 else: | 770 else: |
770 ui.warn('%s: cannot copy - %s\n' % (rel, inst.strerror)) | 771 ui.warn('%s: cannot copy - %s\n' % (rel, inst.strerror)) |
771 errs += 1 | 772 errs += 1 |
772 continue | 773 continue |
773 repo.copy(abs, myabsdest) | 774 repo.copy(abs, myabsdest) |
775 copied.append((abs, rel, exact)) | |
774 if errs: | 776 if errs: |
775 ui.warn('(consider using --after to record failed copies)\n') | 777 ui.warn('(consider using --after)\n') |
778 return errs, copied | |
779 | |
780 def copy(ui, repo, *pats, **opts): | |
781 """mark files as copied for the next commit""" | |
782 errs, copied = docopy(ui, repo, pats, opts) | |
776 return errs | 783 return errs |
777 | 784 |
778 def debugcheckstate(ui, repo): | 785 def debugcheckstate(ui, repo): |
779 """validate the correctness of the current dirstate""" | 786 """validate the correctness of the current dirstate""" |
780 parent1, parent2 = repo.dirstate.parents() | 787 parent1, parent2 = repo.dirstate.parents() |
1388 def okaytoremove(abs, rel, exact): | 1395 def okaytoremove(abs, rel, exact): |
1389 c, a, d, u = repo.changes(files = [abs]) | 1396 c, a, d, u = repo.changes(files = [abs]) |
1390 reason = None | 1397 reason = None |
1391 if c: reason = 'is modified' | 1398 if c: reason = 'is modified' |
1392 elif a: reason = 'has been marked for add' | 1399 elif a: reason = 'has been marked for add' |
1393 elif u: reason = 'not managed' | 1400 elif u: reason = 'is not managed' |
1394 if reason and exact: | 1401 if reason and exact: |
1395 ui.warn('not removing %s: file %s\n' % (rel, reason)) | 1402 ui.warn('not removing %s: file %s\n' % (rel, reason)) |
1396 else: | 1403 else: |
1397 return True | 1404 return True |
1398 for src, abs, rel, exact in walk(repo, (pat,) + pats, opts): | 1405 for src, abs, rel, exact in walk(repo, (pat,) + pats, opts): |
1399 if okaytoremove(abs, rel, exact): | 1406 if okaytoremove(abs, rel, exact): |
1400 if not exact: ui.status('removing %s\n' % rel) | 1407 if ui.verbose or not exact: ui.status('removing %s\n' % rel) |
1401 names.append(abs) | 1408 names.append(abs) |
1402 for name in names: | 1409 for name in names: |
1403 try: | 1410 try: |
1404 os.unlink(name) | 1411 os.unlink(name) |
1405 except OSError, inst: | 1412 except OSError, inst: |
1406 if inst.errno != errno.ENOENT: raise | 1413 if inst.errno != errno.ENOENT: raise |
1407 repo.remove(names) | 1414 repo.remove(names) |
1415 | |
1416 def rename(ui, repo, *pats, **opts): | |
1417 """rename files; equivalent of copy + remove""" | |
1418 errs, copied = docopy(ui, repo, pats, opts) | |
1419 names = [] | |
1420 for abs, rel, exact in copied: | |
1421 if ui.verbose or not exact: ui.status('removing %s\n' % rel) | |
1422 try: | |
1423 os.unlink(rel) | |
1424 except OSError, inst: | |
1425 if inst.errno != errno.ENOENT: raise | |
1426 names.append(abs) | |
1427 repo.remove(names) | |
1428 return errs | |
1408 | 1429 |
1409 def revert(ui, repo, *names, **opts): | 1430 def revert(ui, repo, *names, **opts): |
1410 """revert modified files or dirs back to their unmodified states""" | 1431 """revert modified files or dirs back to their unmodified states""" |
1411 node = opts['rev'] and repo.lookup(opts['rev']) or \ | 1432 node = opts['rev'] and repo.lookup(opts['rev']) or \ |
1412 repo.dirstate.parents()[0] | 1433 repo.dirstate.parents()[0] |
1821 (import_, | 1842 (import_, |
1822 [('p', 'strip', 1, 'path strip'), | 1843 [('p', 'strip', 1, 'path strip'), |
1823 ('f', 'force', None, 'skip check for outstanding changes'), | 1844 ('f', 'force', None, 'skip check for outstanding changes'), |
1824 ('b', 'base', "", 'base path')], | 1845 ('b', 'base', "", 'base path')], |
1825 "hg import [-f] [-p NUM] [-b BASE] PATCH..."), | 1846 "hg import [-f] [-p NUM] [-b BASE] PATCH..."), |
1826 "incoming|in": (incoming, | 1847 "incoming|in": (incoming, |
1827 [('p', 'patch', None, 'show patch')], | 1848 [('p', 'patch', None, 'show patch')], |
1828 'hg incoming [-p] [SOURCE]'), | 1849 'hg incoming [-p] [SOURCE]'), |
1829 "^init": (init, [], 'hg init [DEST]'), | 1850 "^init": (init, [], 'hg init [DEST]'), |
1830 "locate": | 1851 "locate": |
1831 (locate, | 1852 (locate, |
1842 ('b', 'branch', None, 'show branches'), | 1863 ('b', 'branch', None, 'show branches'), |
1843 ('r', 'rev', [], 'revision'), | 1864 ('r', 'rev', [], 'revision'), |
1844 ('p', 'patch', None, 'show patch')], | 1865 ('p', 'patch', None, 'show patch')], |
1845 'hg log [-I] [-X] [-r REV]... [-p] [FILE]'), | 1866 'hg log [-I] [-X] [-r REV]... [-p] [FILE]'), |
1846 "manifest": (manifest, [], 'hg manifest [REV]'), | 1867 "manifest": (manifest, [], 'hg manifest [REV]'), |
1847 "outgoing|out": (outgoing, | 1868 "outgoing|out": (outgoing, |
1848 [('p', 'patch', None, 'show patch')], | 1869 [('p', 'patch', None, 'show patch')], |
1849 'hg outgoing [-p] [DEST]'), | 1870 'hg outgoing [-p] [DEST]'), |
1850 "parents": (parents, [], 'hg parents [REV]'), | 1871 "parents": (parents, [], 'hg parents [REV]'), |
1851 "paths": (paths, [], 'hg paths [NAME]'), | 1872 "paths": (paths, [], 'hg paths [NAME]'), |
1852 "^pull": | 1873 "^pull": |
1874 "recover": (recover, [], "hg recover"), | 1895 "recover": (recover, [], "hg recover"), |
1875 "^remove|rm": (remove, | 1896 "^remove|rm": (remove, |
1876 [('I', 'include', [], 'include path in search'), | 1897 [('I', 'include', [], 'include path in search'), |
1877 ('X', 'exclude', [], 'exclude path from search')], | 1898 ('X', 'exclude', [], 'exclude path from search')], |
1878 "hg remove [OPTION]... FILE..."), | 1899 "hg remove [OPTION]... FILE..."), |
1900 "rename|mv": (rename, | |
1901 [('I', 'include', [], 'include path in search'), | |
1902 ('X', 'exclude', [], 'exclude path from search'), | |
1903 ('A', 'after', None, 'record a copy after it has happened'), | |
1904 ('f', 'force', None, 'replace destination if it exists'), | |
1905 ('p', 'parents', None, 'append source path to dest')], | |
1906 'hg rename [OPTION]... [SOURCE]... DEST'), | |
1879 "^revert": | 1907 "^revert": |
1880 (revert, | 1908 (revert, |
1881 [("n", "nonrecursive", None, "don't recurse into subdirs"), | 1909 [("n", "nonrecursive", None, "don't recurse into subdirs"), |
1882 ("r", "rev", "", "revision")], | 1910 ("r", "rev", "", "revision")], |
1883 "hg revert [-n] [-r REV] [NAME]..."), | 1911 "hg revert [-n] [-r REV] [NAME]..."), |