Show More
@@ -0,0 +1,60 b'' | |||
|
1 | #!/bin/sh | |
|
2 | ||
|
3 | hg init | |
|
4 | mkdir d1 d1/d11 d2 | |
|
5 | echo d1/a > d1/a | |
|
6 | echo d1/ba > d1/ba | |
|
7 | echo d1/a1 > d1/d11/a1 | |
|
8 | echo d1/b > d1/b | |
|
9 | echo d2/b > d2/b | |
|
10 | hg add d1/a d1/b d1/ba d1/d11/a1 d2/b | |
|
11 | hg commit -m "1" -d "0 0" | |
|
12 | ||
|
13 | echo "# rename a single file" | |
|
14 | hg rename d1/d11/a1 d2/c | |
|
15 | hg status | |
|
16 | hg update -C | |
|
17 | ||
|
18 | echo "# move a single file to an existing directory" | |
|
19 | hg rename d1/d11/a1 d2 | |
|
20 | hg status | |
|
21 | hg update -C | |
|
22 | ||
|
23 | echo "# rename directory d1 as d3" | |
|
24 | hg rename d1 d3 | |
|
25 | hg status | |
|
26 | hg update -C | |
|
27 | ||
|
28 | echo "# move directory d1/d11 to an existing directory d2 (removes empty d1)" | |
|
29 | hg rename d1/d11 d2 | |
|
30 | hg status | |
|
31 | hg update -C | |
|
32 | ||
|
33 | echo "# move directories d1 and d2 to a new directory d3" | |
|
34 | mkdir d3 | |
|
35 | hg rename d1 d2 d3 | |
|
36 | hg status | |
|
37 | hg update -C | |
|
38 | ||
|
39 | echo "# move everything under directory d1 to existing directory d2, do not" | |
|
40 | echo "# overwrite existing files (d2/b)" | |
|
41 | hg rename d1/* d2 | |
|
42 | hg status | |
|
43 | diff d1/b d2/b | |
|
44 | hg update -C | |
|
45 | ||
|
46 | echo "# attempt to move potentially more than one file into a non-existent" | |
|
47 | echo "# directory" | |
|
48 | hg rename 'glob:d1/**' dx | |
|
49 | ||
|
50 | echo "# move every file under d1 to d2/d21 (glob)" | |
|
51 | mkdir d2/d21 | |
|
52 | hg rename 'glob:d1/**' d2/d21 | |
|
53 | hg status | |
|
54 | hg update -C | |
|
55 | ||
|
56 | echo "# move every file under d1 starting with an 'a' to d2/d21 (regexp)" | |
|
57 | mkdir d2/d21 | |
|
58 | hg rename 're:d1/([^a][^/]*/)*a.*' d2/d21 | |
|
59 | hg status | |
|
60 | hg update -C |
@@ -0,0 +1,93 b'' | |||
|
1 | # rename a single file | |
|
2 | A d2/c | |
|
3 | R d1/d11/a1 | |
|
4 | # move a single file to an existing directory | |
|
5 | A d2/a1 | |
|
6 | R d1/d11/a1 | |
|
7 | # rename directory d1 as d3 | |
|
8 | copying d1/a to d3/a | |
|
9 | copying d1/b to d3/b | |
|
10 | copying d1/ba to d3/ba | |
|
11 | copying d1/d11/a1 to d3/d11/a1 | |
|
12 | removing d1/a | |
|
13 | removing d1/b | |
|
14 | removing d1/ba | |
|
15 | removing d1/d11/a1 | |
|
16 | A d3/a | |
|
17 | A d3/b | |
|
18 | A d3/ba | |
|
19 | A d3/d11/a1 | |
|
20 | R d1/a | |
|
21 | R d1/b | |
|
22 | R d1/ba | |
|
23 | R d1/d11/a1 | |
|
24 | # move directory d1/d11 to an existing directory d2 (removes empty d1) | |
|
25 | copying d1/d11/a1 to d2/d11/a1 | |
|
26 | removing d1/d11/a1 | |
|
27 | A d2/d11/a1 | |
|
28 | R d1/d11/a1 | |
|
29 | # move directories d1 and d2 to a new directory d3 | |
|
30 | copying d1/a to d3/d1/a | |
|
31 | copying d1/b to d3/d1/b | |
|
32 | copying d1/ba to d3/d1/ba | |
|
33 | copying d1/d11/a1 to d3/d1/d11/a1 | |
|
34 | copying d2/b to d3/d2/b | |
|
35 | removing d1/a | |
|
36 | removing d1/b | |
|
37 | removing d1/ba | |
|
38 | removing d1/d11/a1 | |
|
39 | removing d2/b | |
|
40 | A d3/d1/a | |
|
41 | A d3/d1/b | |
|
42 | A d3/d1/ba | |
|
43 | A d3/d1/d11/a1 | |
|
44 | A d3/d2/b | |
|
45 | R d1/a | |
|
46 | R d1/b | |
|
47 | R d1/ba | |
|
48 | R d1/d11/a1 | |
|
49 | R d2/b | |
|
50 | # move everything under directory d1 to existing directory d2, do not | |
|
51 | # overwrite existing files (d2/b) | |
|
52 | d2/b: not overwriting - file already managed | |
|
53 | copying d1/d11/a1 to d2/d11/a1 | |
|
54 | removing d1/d11/a1 | |
|
55 | A d2/a | |
|
56 | A d2/ba | |
|
57 | A d2/d11/a1 | |
|
58 | R d1/a | |
|
59 | R d1/ba | |
|
60 | R d1/d11/a1 | |
|
61 | 1c1 | |
|
62 | < d1/b | |
|
63 | --- | |
|
64 | > d2/b | |
|
65 | # attempt to move potentially more than one file into a non-existent | |
|
66 | # directory | |
|
67 | abort: with multiple sources, destination must be an existing directory | |
|
68 | # move every file under d1 to d2/d21 (glob) | |
|
69 | copying d1/a to d2/d21/a | |
|
70 | copying d1/b to d2/d21/b | |
|
71 | copying d1/ba to d2/d21/ba | |
|
72 | copying d1/d11/a1 to d2/d21/a1 | |
|
73 | removing d1/a | |
|
74 | removing d1/b | |
|
75 | removing d1/ba | |
|
76 | removing d1/d11/a1 | |
|
77 | A d2/d21/a | |
|
78 | A d2/d21/a1 | |
|
79 | A d2/d21/b | |
|
80 | A d2/d21/ba | |
|
81 | R d1/a | |
|
82 | R d1/b | |
|
83 | R d1/ba | |
|
84 | R d1/d11/a1 | |
|
85 | # move every file under d1 starting with an 'a' to d2/d21 (regexp) | |
|
86 | copying d1/a to d2/d21/a | |
|
87 | copying d1/d11/a1 to d2/d21/a1 | |
|
88 | removing d1/a | |
|
89 | removing d1/d11/a1 | |
|
90 | A d2/d21/a | |
|
91 | A d2/d21/a1 | |
|
92 | R d1/a | |
|
93 | R d1/d11/a1 |
@@ -787,14 +787,9 b' def commit(ui, repo, *pats, **opts):' | |||
|
787 | 787 | raise util.Abort(str(inst)) |
|
788 | 788 | |
|
789 | 789 | def docopy(ui, repo, pats, opts): |
|
790 | if not pats: | |
|
791 | raise util.Abort(_('no source or destination specified')) | |
|
792 | elif len(pats) == 1: | |
|
793 | raise util.Abort(_('no destination specified')) | |
|
794 | pats = list(pats) | |
|
795 | dest = pats.pop() | |
|
796 | sources = [] | |
|
797 | dir2dir = len(pats) == 1 and os.path.isdir(pats[0]) | |
|
790 | cwd = repo.getcwd() | |
|
791 | errors = 0 | |
|
792 | copied = [] | |
|
798 | 793 | |
|
799 | 794 | def okaytocopy(abs, rel, exact): |
|
800 | 795 | reasons = {'?': _('is not managed'), |
@@ -805,74 +800,68 b' def docopy(ui, repo, pats, opts):' | |||
|
805 | 800 | else: |
|
806 | 801 | return True |
|
807 | 802 | |
|
808 | for src, abs, rel, exact in walk(repo, pats, opts): | |
|
809 | if okaytocopy(abs, rel, exact): | |
|
810 | sources.append((abs, rel, exact)) | |
|
811 | if not sources: | |
|
812 | raise util.Abort(_('no files to copy')) | |
|
813 | ||
|
814 | cwd = repo.getcwd() | |
|
815 | absdest = util.canonpath(repo.root, cwd, dest) | |
|
816 | reldest = util.pathto(cwd, absdest) | |
|
817 | if os.path.exists(reldest): | |
|
818 | destisfile = not os.path.isdir(reldest) | |
|
819 | else: | |
|
820 | destisfile = not dir2dir and (len(sources) == 1 | |
|
821 | or repo.dirstate.state(absdest) != '?') | |
|
822 | ||
|
823 | if destisfile and len(sources) > 1: | |
|
824 | raise util.Abort(_('with multiple sources, destination must be a ' | |
|
825 | 'directory')) | |
|
826 | ||
|
827 | srcpfxlen = 0 | |
|
828 | if dir2dir: | |
|
829 | srcpfx = util.pathto(cwd, util.canonpath(repo.root, cwd, pats[0])) | |
|
830 | if os.path.exists(reldest): | |
|
831 | srcpfx = os.path.split(srcpfx)[0] | |
|
832 | if srcpfx: | |
|
833 | srcpfx += os.sep | |
|
834 | srcpfxlen = len(srcpfx) | |
|
835 | ||
|
836 | errs, copied = 0, [] | |
|
837 | for abs, rel, exact in sources: | |
|
838 | if destisfile: | |
|
839 | mydest = reldest | |
|
840 | elif dir2dir: | |
|
841 | mydest = os.path.join(dest, rel[srcpfxlen:]) | |
|
842 | else: | |
|
843 | mydest = os.path.join(dest, os.path.basename(rel)) | |
|
844 | myabsdest = util.canonpath(repo.root, cwd, mydest) | |
|
845 | myreldest = util.pathto(cwd, myabsdest) | |
|
846 | if not opts['force'] and repo.dirstate.state(myabsdest) not in 'a?': | |
|
847 | ui.warn(_('%s: not overwriting - file already managed\n') % myreldest) | |
|
848 | continue | |
|
849 | mydestdir = os.path.dirname(myreldest) or '.' | |
|
803 | def copy(abssrc, relsrc, target, exact): | |
|
804 | abstarget = util.canonpath(repo.root, cwd, target) | |
|
805 | reltarget = util.pathto(cwd, abstarget) | |
|
806 | if not opts['force'] and repo.dirstate.state(abstarget) not in 'a?': | |
|
807 | ui.warn(_('%s: not overwriting - file already managed\n') % | |
|
808 | reltarget) | |
|
809 | return | |
|
810 | if ui.verbose or not exact: | |
|
811 | ui.status(_('copying %s to %s\n') % (relsrc, reltarget)) | |
|
850 | 812 | if not opts['after']: |
|
813 | targetdir = os.path.dirname(reltarget) or '.' | |
|
814 | if not os.path.isdir(targetdir): | |
|
815 | os.makedirs(targetdir) | |
|
851 | 816 | try: |
|
852 | if dir2dir: os.makedirs(mydestdir) | |
|
853 | elif not destisfile: os.mkdir(mydestdir) | |
|
854 | except OSError, inst: | |
|
855 | if inst.errno != errno.EEXIST: raise | |
|
856 | if ui.verbose or not exact: | |
|
857 | ui.status(_('copying %s to %s\n') % (rel, myreldest)) | |
|
858 | if not opts['after']: | |
|
859 | try: | |
|
860 | shutil.copyfile(rel, myreldest) | |
|
861 | shutil.copymode(rel, myreldest) | |
|
817 | shutil.copyfile(relsrc, reltarget) | |
|
818 | shutil.copymode(relsrc, reltarget) | |
|
862 | 819 | except shutil.Error, inst: |
|
863 | 820 | raise util.Abort(str(inst)) |
|
864 | 821 | except IOError, inst: |
|
865 | 822 | if inst.errno == errno.ENOENT: |
|
866 | ui.warn(_('%s: deleted in working copy\n') % rel) | |
|
823 | ui.warn(_('%s: deleted in working copy\n') % relsrc) | |
|
867 | 824 | else: |
|
868 |
ui.warn(_('%s: cannot copy - %s\n') % |
|
|
869 | errs += 1 | |
|
870 |
|
|
|
871 | repo.copy(abs, myabsdest) | |
|
872 | copied.append((abs, rel, exact)) | |
|
873 | if errs: | |
|
825 | ui.warn(_('%s: cannot copy - %s\n') % | |
|
826 | (relsrc, inst.strerror)) | |
|
827 | errors += 1 | |
|
828 | return | |
|
829 | repo.copy(abssrc, abstarget) | |
|
830 | copied.append((abssrc, relsrc, exact)) | |
|
831 | ||
|
832 | pats = list(pats) | |
|
833 | if not pats: | |
|
834 | raise util.Abort(_('no source or destination specified')) | |
|
835 | if len(pats) == 1: | |
|
836 | raise util.Abort(_('no destination specified')) | |
|
837 | dest = pats.pop() | |
|
838 | destdirexists = os.path.isdir(dest) | |
|
839 | if (len(pats) > 1 or not os.path.exists(pats[0])) and not destdirexists: | |
|
840 | raise util.Abort(_('with multiple sources, destination must be an ' | |
|
841 | 'existing directory')) | |
|
842 | ||
|
843 | for pat in pats: | |
|
844 | if os.path.isdir(pat): | |
|
845 | if destdirexists: | |
|
846 | striplen = len(os.path.split(pat)[0]) | |
|
847 | else: | |
|
848 | striplen = len(pat) | |
|
849 | if striplen: | |
|
850 | striplen += len(os.sep) | |
|
851 | targetpath = lambda p: os.path.join(dest, p[striplen:]) | |
|
852 | elif destdirexists: | |
|
853 | targetpath = lambda p: os.path.join(dest, os.path.basename(p)) | |
|
854 | else: | |
|
855 | targetpath = lambda p: dest | |
|
856 | for tag, abssrc, relsrc, exact in walk(repo, [pat], opts): | |
|
857 | if okaytocopy(abssrc, relsrc, exact): | |
|
858 | copy(abssrc, relsrc, targetpath(abssrc), exact) | |
|
859 | ||
|
860 | if errors: | |
|
874 | 861 | ui.warn(_('(consider using --after)\n')) |
|
875 | return errs, copied | |
|
862 | if len(copied) == 0: | |
|
863 | raise util.Abort(_('no files to copy')) | |
|
864 | return errors, copied | |
|
876 | 865 | |
|
877 | 866 | def copy(ui, repo, *pats, **opts): |
|
878 | 867 | """mark files as copied for the next commit |
General Comments 0
You need to be logged in to leave comments.
Login now