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 | raise util.Abort(str(inst)) |
|
787 | raise util.Abort(str(inst)) | |
788 |
|
788 | |||
789 | def docopy(ui, repo, pats, opts): |
|
789 | def docopy(ui, repo, pats, opts): | |
790 | if not pats: |
|
790 | cwd = repo.getcwd() | |
791 | raise util.Abort(_('no source or destination specified')) |
|
791 | errors = 0 | |
792 | elif len(pats) == 1: |
|
792 | copied = [] | |
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]) |
|
|||
798 |
|
793 | |||
799 | def okaytocopy(abs, rel, exact): |
|
794 | def okaytocopy(abs, rel, exact): | |
800 | reasons = {'?': _('is not managed'), |
|
795 | reasons = {'?': _('is not managed'), | |
@@ -805,74 +800,68 b' def docopy(ui, repo, pats, opts):' | |||||
805 | else: |
|
800 | else: | |
806 | return True |
|
801 | return True | |
807 |
|
802 | |||
808 | for src, abs, rel, exact in walk(repo, pats, opts): |
|
803 | def copy(abssrc, relsrc, target, exact): | |
809 | if okaytocopy(abs, rel, exact): |
|
804 | abstarget = util.canonpath(repo.root, cwd, target) | |
810 | sources.append((abs, rel, exact)) |
|
805 | reltarget = util.pathto(cwd, abstarget) | |
811 | if not sources: |
|
806 | if not opts['force'] and repo.dirstate.state(abstarget) not in 'a?': | |
812 | raise util.Abort(_('no files to copy')) |
|
807 | ui.warn(_('%s: not overwriting - file already managed\n') % | |
813 |
|
808 | reltarget) | ||
814 | cwd = repo.getcwd() |
|
809 | return | |
815 | absdest = util.canonpath(repo.root, cwd, dest) |
|
810 | if ui.verbose or not exact: | |
816 | reldest = util.pathto(cwd, absdest) |
|
811 | ui.status(_('copying %s to %s\n') % (relsrc, reltarget)) | |
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 '.' |
|
|||
850 | if not opts['after']: |
|
812 | if not opts['after']: | |
|
813 | targetdir = os.path.dirname(reltarget) or '.' | |||
|
814 | if not os.path.isdir(targetdir): | |||
|
815 | os.makedirs(targetdir) | |||
851 | try: |
|
816 | try: | |
852 | if dir2dir: os.makedirs(mydestdir) |
|
817 | shutil.copyfile(relsrc, reltarget) | |
853 | elif not destisfile: os.mkdir(mydestdir) |
|
818 | shutil.copymode(relsrc, reltarget) | |
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) |
|
|||
862 | except shutil.Error, inst: |
|
819 | except shutil.Error, inst: | |
863 | raise util.Abort(str(inst)) |
|
820 | raise util.Abort(str(inst)) | |
864 | except IOError, inst: |
|
821 | except IOError, inst: | |
865 | if inst.errno == errno.ENOENT: |
|
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 | else: |
|
824 | else: | |
868 |
ui.warn(_('%s: cannot copy - %s\n') % |
|
825 | ui.warn(_('%s: cannot copy - %s\n') % | |
869 | errs += 1 |
|
826 | (relsrc, inst.strerror)) | |
870 |
|
|
827 | errors += 1 | |
871 | repo.copy(abs, myabsdest) |
|
828 | return | |
872 | copied.append((abs, rel, exact)) |
|
829 | repo.copy(abssrc, abstarget) | |
873 | if errs: |
|
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 | ui.warn(_('(consider using --after)\n')) |
|
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 | def copy(ui, repo, *pats, **opts): |
|
866 | def copy(ui, repo, *pats, **opts): | |
878 | """mark files as copied for the next commit |
|
867 | """mark files as copied for the next commit |
General Comments 0
You need to be logged in to leave comments.
Login now