##// END OF EJS Templates
Fix up copy command to behave more like regular "cp"....
Bryan O'Sullivan -
r1249:a5355fa5 default
parent child Browse files
Show More
@@ -164,11 +164,22 b' commit [options] [files...]::'
164
164
165 aliases: ci
165 aliases: ci
166
166
167 copy <source> <dest>::
167 copy <source ...> <dest>::
168 Mark <dest> file as a copy or rename of a <source> one
168 Mark dest as having copies of source files. If dest is a
169 directory, copies are put in that directory. If dest is a file,
170 there can only be one source.
171
172 By default, this command copies the contents of files as they
173 stand in the working directory. If invoked with --after, the
174 operation is recorded, but no copying is performed.
169
175
170 This command takes effect for the next commit.
176 This command takes effect for the next commit.
171
177
178 Options:
179 -A, --after record a copy that has already occurred
180 -f, --force forcibly copy over an existing managed file
181 -p, --parents append source path to dest
182
172 diff [-a] [-r revision] [-r revision] [files ...]::
183 diff [-a] [-r revision] [-r revision] [files ...]::
173 Show differences between revisions for the specified files.
184 Show differences between revisions for the specified files.
174
185
@@ -685,9 +685,84 b' def commit(ui, repo, *pats, **opts):'
685 except ValueError, inst:
685 except ValueError, inst:
686 raise util.Abort(str(inst))
686 raise util.Abort(str(inst))
687
687
688 def copy(ui, repo, source, dest):
688 def copy(ui, repo, *pats, **opts):
689 """mark a file as copied or renamed for the next commit"""
689 """mark files as copied for the next commit"""
690 return repo.copy(*relpath(repo, (source, dest)))
690 if not pats:
691 raise util.Abort('no source or destination specified')
692 elif len(pats) == 1:
693 raise util.Abort('no destination specified')
694 pats = list(pats)
695 dest = pats.pop()
696 sources = []
697
698 def okaytocopy(abs, rel, exact):
699 reasons = {'?': 'is not managed',
700 'a': 'has been marked for add'}
701 reason = reasons.get(repo.dirstate.state(abs))
702 if reason:
703 if exact: ui.warn('%s: not copying - file %s\n' % (rel, reason))
704 else:
705 return True
706
707 for src, abs, rel, exact in walk(repo, pats, opts):
708 if okaytocopy(abs, rel, exact):
709 sources.append((abs, rel, exact))
710 if not sources:
711 raise util.Abort('no files to copy')
712
713 cwd = repo.getcwd()
714 absdest = util.canonpath(repo.root, cwd, dest)
715 reldest = util.pathto(cwd, absdest)
716 if os.path.exists(reldest):
717 destisfile = not os.path.isdir(reldest)
718 else:
719 destisfile = len(sources) == 1 or repo.dirstate.state(absdest) != '?'
720
721 if destisfile:
722 if opts['parents']:
723 raise util.Abort('with --parents, destination must be a directory')
724 elif len(sources) > 1:
725 raise util.Abort('with multiple sources, destination must be a '
726 'directory')
727 errs = 0
728 for abs, rel, exact in sources:
729 if opts['parents']:
730 mydest = os.path.join(dest, rel)
731 elif destisfile:
732 mydest = reldest
733 else:
734 mydest = os.path.join(dest, os.path.basename(rel))
735 myabsdest = util.canonpath(repo.root, cwd, mydest)
736 myreldest = util.pathto(cwd, myabsdest)
737 if not opts['force'] and repo.dirstate.state(myabsdest) not in 'a?':
738 ui.warn('%s: not overwriting - file already managed\n' % myreldest)
739 continue
740 mydestdir = os.path.dirname(myreldest) or '.'
741 if not opts['after']:
742 try:
743 if opts['parents']: os.makedirs(mydestdir)
744 elif not destisfile: os.mkdir(mydestdir)
745 except OSError, inst:
746 if inst.errno != errno.EEXIST: raise
747 if ui.verbose or not exact:
748 ui.status('copying %s to %s\n' % (rel, myreldest))
749 if not opts['after']:
750 try:
751 shutil.copyfile(rel, myreldest)
752 n = repo.manifest.tip()
753 mf = repo.manifest.readflags(n)
754 util.set_exec(myreldest, util.is_exec(rel, mf[abs]))
755 except IOError, inst:
756 if inst.errno == errno.ENOENT:
757 ui.warn('%s: deleted in working copy\n' % rel)
758 else:
759 ui.warn('%s: cannot copy - %s\n' % (rel, inst.strerror))
760 errs += 1
761 continue
762 repo.copy(abs, myabsdest)
763 if errs:
764 ui.warn('(consider using --after to record failed copies)\n')
765 return errs
691
766
692 def debugcheckstate(ui, repo):
767 def debugcheckstate(ui, repo):
693 """validate the correctness of the current dirstate"""
768 """validate the correctness of the current dirstate"""
@@ -1677,7 +1752,13 b' table = {'
1677 ('d', 'date', "", 'date code'),
1752 ('d', 'date', "", 'date code'),
1678 ('u', 'user', "", 'user')],
1753 ('u', 'user', "", 'user')],
1679 'hg commit [OPTION]... [FILE]...'),
1754 'hg commit [OPTION]... [FILE]...'),
1680 "copy": (copy, [], 'hg copy SOURCE DEST'),
1755 "copy|cp": (copy,
1756 [('I', 'include', [], 'include path in search'),
1757 ('X', 'exclude', [], 'exclude path from search'),
1758 ('A', 'after', None, 'record a copy after it has happened'),
1759 ('f', 'force', None, 'replace destination if it exists'),
1760 ('p', 'parents', None, 'append source path to dest')],
1761 'hg copy [OPTION]... [SOURCE]... DEST'),
1681 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
1762 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
1682 "debugconfig": (debugconfig, [], 'debugconfig'),
1763 "debugconfig": (debugconfig, [], 'debugconfig'),
1683 "debugstate": (debugstate, [], 'debugstate'),
1764 "debugstate": (debugstate, [], 'debugstate'),
@@ -26,7 +26,7 b' echo "# should not be renamed"'
26 hg debugrename bar
26 hg debugrename bar
27
27
28 cp foo bar
28 cp foo bar
29 hg copy foo bar
29 hg copy -f foo bar
30 echo "# should show copy"
30 echo "# should show copy"
31 hg debugstate|grep '^copy'
31 hg debugstate|grep '^copy'
32 hg commit -m3 -d"0 0"
32 hg commit -m3 -d"0 0"
@@ -43,7 +43,7 b' list of commands (use "hg help -v" to sh'
43 cat output the latest or given revision of a file
43 cat output the latest or given revision of a file
44 clone make a copy of an existing repository
44 clone make a copy of an existing repository
45 commit commit the specified files or all outstanding changes
45 commit commit the specified files or all outstanding changes
46 copy mark a file as copied or renamed for the next commit
46 copy mark files as copied for the next commit
47 diff diff working directory (or selected files)
47 diff diff working directory (or selected files)
48 export dump the header and diffs for one or more changesets
48 export dump the header and diffs for one or more changesets
49 forget don't add the specified files on the next commit
49 forget don't add the specified files on the next commit
@@ -84,7 +84,7 b' list of commands (use "hg help -v" to sh'
84 cat output the latest or given revision of a file
84 cat output the latest or given revision of a file
85 clone make a copy of an existing repository
85 clone make a copy of an existing repository
86 commit commit the specified files or all outstanding changes
86 commit commit the specified files or all outstanding changes
87 copy mark a file as copied or renamed for the next commit
87 copy mark files as copied for the next commit
88 diff diff working directory (or selected files)
88 diff diff working directory (or selected files)
89 export dump the header and diffs for one or more changesets
89 export dump the header and diffs for one or more changesets
90 forget don't add the specified files on the next commit
90 forget don't add the specified files on the next commit
General Comments 0
You need to be logged in to leave comments. Login now