1#!/usr/bin/perl -w
2use strict;
3use SVK::Test;
4plan tests => 70;
5
6our ($output, $answer);
7my ($xd, $svk) = build_test('foo');
8$svk->mkdir ('-m', 'init', '//V');
9my $tree = create_basic_tree ($xd, '//V');
10$svk->mkdir ('-m', 'init', '//new');
11our ($copath, $corpath) = get_copath ('copy');
12is_output_like ($svk, 'copy', [], qr'SYNOPSIS', 'copy - help');
13
14$svk->checkout ('//new', $copath);
15
16is_output ($svk, 'copy', ['//V/me', '//V/D/de', $copath],
17	   [__"A   $copath/me",
18	    __"A   $copath/de"]);
19is_output ($svk, 'cp', ['//V/me', $copath],
20	   [__"Path $copath/me already exists."]);
21
22is_output ($svk, 'copy', ['//V/me', '//V/D/de', "$copath/me"],
23	   [__"$copath/me is not a directory."], 'multi to nondir');
24is_output ($svk, 'copy', ['//V/me', "$copath/me-copy"],
25	   [__"A   $copath/me-copy"]);
26is_output ($svk, 'copy', [-q => '//V/D/de', "$copath/de-copy"],
27	   []);
28is_output ($svk, 'copy', ['//V/D', "$copath/D-copy"],
29	   [__"A   $copath/D-copy",
30	    __"A   $copath/D-copy/de"]);
31$svk->copy ('//V', "$copath/V-copy");
32
33is_output ($svk, 'copy', ['//V', '/foo/bar', "$copath/V-copy"],
34	   ['Different depots.']);
35append_file ("$copath/me-copy", "foobar");
36append_file ("$copath/V-copy/D/de", "foobar");
37$svk->rm ("$copath/V-copy/B/fe");
38is_output ($svk, 'status', [$copath],
39	   [__('A + t/checkout/copy/D-copy'),
40	    __('A + t/checkout/copy/V-copy'),
41	    __('D + t/checkout/copy/V-copy/B/fe'),
42	    __('M + t/checkout/copy/V-copy/D/de'),
43	    __('A + t/checkout/copy/de'),
44	    __('A + t/checkout/copy/de-copy'),
45	    __('A + t/checkout/copy/me'),
46	    __('M + t/checkout/copy/me-copy')]);
47$svk->commit ('-m', 'commit depot -> checkout copies', $copath);
48is_copied_from ("$copath/me", '/V/me', 3);
49is_copied_from ("$copath/me-copy", '/V/me', 3);
50is_copied_from ("$copath/D-copy/de", '/V/D/de', 3);
51is_copied_from ("$copath/D-copy", '/V/D', 3);
52
53is_output ($svk, 'copy', ['-m', 'more than one', '//V/me', '//V/D', '//V/new'],
54	   ["Copying more than one source requires //V/new to be directory."]);
55
56$svk->mkdir ('-m', 'directory for multiple source cp', '//V/new');
57is_output ($svk, 'copy', ['-m', 'more than one', '//V/me', '//V/D', '//V/new'],
58	   ["Committed revision 7."]);
59is_copied_from ("//V/new/me", '/V/me', 3);
60is_copied_from ("//V/new/D", '/V/D', 3);
61
62is_output ($svk, 'rm', ['-m', 'die!', '//V/D/de'],
63	   ["Committed revision 8."]);
64$svk->update ($copath);
65
66is_output ($svk, 'copy', ["//V/D/de", "$copath/de-revive"],
67	   ['Path /V/D/de does not exist.']);
68is_output ($svk, 'copy', ['-r7', "//V/D/de", "$copath/de-revive"],
69	   [__('A   t/checkout/copy/de-revive')]);
70is_output ($svk, 'status', [$copath],
71	   [__("A + $copath/de-revive")]
72	  );
73is_output ($svk, 'commit', ['-m', 'commit file copied from entry removed later', $copath],
74	   ['Committed revision 9.']);
75is_copied_from ("//new/de-revive", '/V/D/de', 3);
76
77# proper anchoring
78$svk->copy ('//V/A/be', "$copath/be-alone");
79$svk->copy ('//V/A', "$copath/A-prop");
80$svk->ps ('newprop', 'prop after cp', "$copath/be-alone");
81$svk->ps ('newprop', 'prop after cp', "$copath/A-prop/be");
82
83is_output ($svk, 'pl', ["$copath/be-alone"],
84	   [__("Properties on $copath/be-alone:"),
85	    '  newprop', '  svn:keywords']);
86
87is_output ($svk, 'pl', ["$copath/A-prop/be"],
88	   [__("Properties on $copath/A-prop/be:"),
89	    '  newprop', '  svn:keywords']);
90
91mkdir ("$copath/newdir");
92$svk->add ("$copath/newdir");
93my $status = [status_native ($copath, 'A  ', 'newdir/A',
94			     'A  ', 'newdir/A/Q',
95			     'A  ', 'newdir/A/Q/qu',
96			     'A  ', 'newdir/A/Q/qz',
97			     'A  ', 'newdir/A/be')];
98
99is_output ($svk, 'copy', ['//V/A', "$copath/newdir"],
100	   $status);
101is_output ($svk, 'status', ["$copath/newdir/A", "$copath/A-prop"],
102	   [status_native ($copath, 'A +', 'A-prop', ' M+', 'A-prop/be',
103			   'A  ', 'newdir', 'A +', 'newdir/A')]);
104
105
106$svk->revert ('-R', $copath);
107TODO: {
108local $TODO = 'revert removes known nodes copied';
109is_output ($svk, 'status', [$copath], []);
110}
111
112# depot -> depot copying
113is_output ($svk, 'copy', ['-m' => 'depot->depot dir copy',
114                          '//V/D' => '//V/D-depot-copy'],
115           ['Committed revision 10.']);
116is_copied_from ('//V/D-depot-copy' => '/V/D', 8);
117
118is_output( $svk, 'copy', ['-m' => 'depot->depot file copy',
119                          '//V/me' => '//V/me-depot-copy'],
120           ['Committed revision 11.']);
121is_copied_from ('//V/me-depot-copy' => '/V/me', 3);
122
123# copy on mirrored paths
124my ($srepospath, $spath, $srepos) = $xd->find_repos ('/foo/', 1);
125my $uri = uri($srepospath);
126create_basic_tree ($xd, '/foo/');
127$svk->mirror ('//foo-remote', $uri);
128$svk->sync ('//foo-remote');
129$svk->update ($copath);
130
131is_output ($svk, 'cp', ['//V/new', '//foo-remote/new'],
132	   ['You are trying to copy across different mirrors.',
133	    'Create an empty directory //foo-remote/new, and run smerge --baseless //V/new //foo-remote/new.']);
134
135is_output ($svk, 'cp', ['-m', 'copy directly', '//V/me', '//V/me-dcopied'],
136	   ['Committed revision 15.']);
137is_copied_from ("//V/me-dcopied", '/V/me', 3);
138
139is_output ($svk, 'cp', ['-m', 'copy for remote', '//foo-remote/me', '//foo-remote/me-rcopied'],
140	   [
141	    "Merging back to mirror source $uri.",
142	    'Merge back committed as revision 3.',
143	    "Syncing $uri",
144	    'Retrieving log information from 3 to 3',
145	    'Committed revision 16 from revision 3.']);
146
147is_copied_from ("//foo-remote/me-rcopied", '/foo-remote/me', 14);
148is_copied_from ("/foo/me-rcopied", '/me', 2);
149
150
151rmtree ([$copath]);
152$svk->checkout ('//foo-remote', $copath);
153
154is_output ($svk, 'cp', ['//V/me', "$copath/me-rcopied"],
155	   ['You are trying to copy across different mirrors.']);
156$svk->copy ('-m', 'from co', "$copath/me", '//foo-remote/me-rcopied.again');
157is_copied_from ("//foo-remote/me-rcopied.again", '/foo-remote/me', 14);
158is_copied_from ("/foo/me-rcopied.again", '/me', 2);
159
160append_file ("$copath/me", "bzz\n");
161is_output_like ($svk, 'copy', ['-m', 'from co, modified', "$copath/me", '//foo-remote/me-rcopied.modified'],
162		qr/modified/);
163$svk->revert ('-R', $copath);
164$svk->copy ("$copath/me", "$copath/me-cocopied");
165is_output ($svk, 'status', [$copath],
166	   [__("A + $copath/me-cocopied")]
167	  );
168is_output ($svk, 'cp', ["$copath/me", "$copath/me-cocopied"], [__("Path $copath/me-cocopied already exists.")]);
169
170$svk->commit ('-m', 'commit copied file in mirrored path', $copath);
171is_copied_from ("/foo/me-cocopied", '/me', 2);
172
173is_output($svk, 'copy', ["$copath/me", "$copath/nonexist/fnord"],
174	  [__"Parent directory t/checkout/copy/nonexist doesn't exist, use -p."]);
175
176is_output($svk, 'copy', [-p => "$copath/me", "$copath/nonexist/fnord"],
177	   [__("A   $copath/nonexist"),
178	    __("A   $copath/nonexist/fnord")]
179	  );
180
181is_output ($svk, 'status', [$copath],
182	   [__("A   $copath/nonexist"),
183	    __("A + $copath/nonexist/fnord")]
184	  );
185
186$svk->revert("$copath/nonexist");
187is_output($svk, 'copy', ["$copath/me", "$copath/nonexist"],
188	  [__"t/checkout/copy/nonexist is not a versioned directory."]);
189
190is_output($svk, 'copy', ["$copath/me", "$copath/me-cocopied/fnord"],
191	  [__"t/checkout/copy/me-cocopied is not a directory."]);
192
193is_output($svk, 'copy', ["$copath/A", "$copath/B", "$copath/me"],
194	  [__"t/checkout/copy/me is not a directory."]);
195
196my $dir = __("mkdir t/checkout/copy/me-cocopied:");
197is_output($svk, 'copy', [-p => "$copath/me", "$copath/me-cocopied/fnord/orz"],
198	  [qr{\Q$dir\E File exists.*},
199	  ]);
200
201is_output($svk, 'copy', [-p => "$copath/me", "$copath/nonexist2/fnord2/me"],
202	   [__("A   $copath/nonexist2"),
203	    __("A   $copath/nonexist2/fnord2"),
204	    __("A   $copath/nonexist2/fnord2/me")]
205	  );
206
207$svk->revert('-R', $copath);
208rmtree ["$copath/nonexist"];
209rmtree ["$copath/nonexist2"];
210
211is_output ($svk, 'cp', ['-m', 'copy directly', '//V/me', '//V/A/Q/'],
212	   ['Committed revision 19.']);
213is_copied_from ("//V/A/Q/me", '/V/me', 3);
214
215is_output ($svk, 'cp', ['-m', 'copy directly', '//V/me', '//V/newdir-with-p/me-dcopied'],
216	   ["Parent directory //V/newdir-with-p doesn't exist, use -p."]);
217is_output ($svk, 'cp', ['-p', '-m', 'copy directly', '//V/me', '//V/newdir-with-p/me-dcopied'],
218	   ['Committed revision 20.']);
219
220is_copied_from ("//V/A/Q/me", '/V/me', 3);
221
222require Cwd;
223my $cwd = Cwd::cwd();
224our (undef, $corpath_some) = get_copath ('copy-some');
225mkdir($corpath_some);
226chdir($corpath_some);
227$answer = 'somepath';
228is_output ($svk, 'cp', ['-m', '', '//V/me'],
229	   ['Committed revision 21.',
230            'Syncing //somepath(/somepath) in '.__("$corpath_some/somepath to 21."),
231            'A   somepath']);
232is_copied_from ("//somepath", '/V/me', 3);
233chdir $cwd;
234
235$svk->copy ("$copath/A", "$copath/B/A-cp-in-B");
236is_output ($svk, 'status', [$copath],
237	   [__("A + $copath/B/A-cp-in-B")]
238	  );
239$svk->update ($copath);
240
241is_output ($svk, 'commit', ['-m', 'commit copied file in mirrored path', $copath],
242	   ['Commit into mirrored path: merging back directly.',
243	    "Merging back to mirror source $uri.",
244	    'Merge back committed as revision 6.',
245	    "Syncing $uri",
246	    'Retrieving log information from 6 to 6',
247	    'Committed revision 22 from revision 6.']);
248
249is_output($svk, 'rm', ["$copath/B/fe"],
250	  [__("D   $copath/B/fe")]);
251
252TODO: {
253local $TODO = 'replaced item should be reported as R';
254is_output($svk, 'mv', ["$copath/A/Q/qu", "$copath/B/fe"],
255	  [__("R   $copath/B/fe"),
256	   __("D   $copath/A/Q/qu")]);
257}
258
259is_output ($svk, 'commit', ['-m', 'commit copied file in mirrored path', $copath],
260	   ['Commit into mirrored path: merging back directly.',
261	    "Merging back to mirror source $uri.",
262	    'Merge back committed as revision 7.',
263	    "Syncing $uri",
264	    'Retrieving log information from 7 to 7',
265	    'Committed revision 23 from revision 7.']);
266
267is_output ($svk, 'cp', ['-m', 'copy for remote', -r => '2@', '//foo-remote/me', '//foo-remote/me-rcopied-wr'],
268	   [
269	    "Merging back to mirror source $uri.",
270	    'Merge back committed as revision 8.',
271	    "Syncing $uri",
272	    'Retrieving log information from 8 to 8',
273	    'Committed revision 24 from revision 8.']);
274
275is_output($svk, 'rm', ["$copath/B/fe"],
276	  [__("D   $copath/B/fe")]);
277
278TODO: {
279local $TODO = 'replaced item should be reported as R';
280is_output($svk, 'cp', ["$copath/A/be", "$copath/B/fe"],
281	  [__("R   $copath/B/fe")]);
282}
283
284mkdir "$copath/foo";
285is_output ($svk, 'cp', ['//foo-remote', "$copath/foo"],
286	   [__"$copath/foo is not a versioned directory."]);
287is_output ($svk, 'cp', ['//foo-remote/A/be', "$copath/me"],
288	   [__"Path $copath/me already exists."]);
289
290sub is_copied_from {
291    unshift @_, $svk;
292    goto \&is_ancestor;
293}
294