Merge with MPM.
authorBryan O'Sullivan <bos@serpentine.com>
Wed, 14 Sep 2005 14:39:46 -0700
changeset 1250 0ad3f9b27260
parent 1249 a5355fa5e33a (diff)
parent 1245 d0a960b437a8 (current diff)
child 1251 84cf8834efb5
Merge with MPM.
mercurial/commands.py
--- a/contrib/mercurial.el	Wed Sep 14 15:50:31 2005 -0500
+++ b/contrib/mercurial.el	Wed Sep 14 14:39:46 2005 -0700
@@ -993,9 +993,16 @@
 		  (or repo hg-outgoing-repository))
     (hg-log-mode)))
 
-(defun hg-pull ()
-  (interactive)
-  (error "not implemented"))
+(defun hg-pull (&optional repo)
+  "Pull changes from repository REPO.
+This does not update the working directory."
+  (interactive (list (hg-read-repo-name " to pull from")))
+  (hg-view-output ((format "Mercurial: Pull to %s from %s"
+			   (hg-abbrev-file-name (hg-root))
+			   (hg-abbrev-file-name
+			    (or repo hg-incoming-repository))))
+    (call-process (hg-binary) nil t nil "pull"
+		  (or repo hg-incoming-repository))))
 
 (defun hg-push (&optional repo)
   "Push changes to repository REPO."
@@ -1079,6 +1086,10 @@
   (interactive)
   (error "not implemented"))
 
+(defun hg-update ()
+  (interactive)
+  (error "not implemented"))
+
 (defun hg-version-other-window ()
   (interactive)
   (error "not implemented"))
--- a/doc/hg.1.txt	Wed Sep 14 15:50:31 2005 -0500
+++ b/doc/hg.1.txt	Wed Sep 14 14:39:46 2005 -0700
@@ -164,11 +164,22 @@
 
     aliases: ci
 
-copy <source> <dest>::
-    Mark <dest> file as a copy or rename of a <source> one
+copy <source ...> <dest>::
+    Mark dest as having copies of source files.  If dest is a
+    directory, copies are put in that directory.  If dest is a file,
+    there can only be one source.
+
+    By default, this command copies the contents of files as they
+    stand in the working directory.  If invoked with --after, the
+    operation is recorded, but no copying is performed.
 
     This command takes effect for the next commit.
 
+    Options:
+    -A, --after        record a copy that has already occurred
+    -f, --force        forcibly copy over an existing managed file
+    -p, --parents      append source path to dest
+    
 diff [-a] [-r revision] [-r revision] [files ...]::
     Show differences between revisions for the specified files.
 
@@ -432,7 +443,8 @@
 
     This command schedules the files to be removed at the next commit.
     This only removes files from the current branch, not from the
-    entire project history.
+    entire project history.  If the files still exist in the working
+    directory, they will be deleted from it.
 
     aliases: rm
 
--- a/mercurial/commands.py	Wed Sep 14 15:50:31 2005 -0500
+++ b/mercurial/commands.py	Wed Sep 14 14:39:46 2005 -0700
@@ -696,9 +696,84 @@
     except ValueError, inst:
         raise util.Abort(str(inst))
 
-def copy(ui, repo, source, dest):
-    """mark a file as copied or renamed for the next commit"""
-    return repo.copy(*relpath(repo, (source, dest)))
+def copy(ui, repo, *pats, **opts):
+    """mark files as copied for the next commit"""
+    if not pats:
+        raise util.Abort('no source or destination specified')
+    elif len(pats) == 1:
+        raise util.Abort('no destination specified')
+    pats = list(pats)
+    dest = pats.pop()
+    sources = []
+
+    def okaytocopy(abs, rel, exact):
+        reasons = {'?': 'is not managed',
+                   'a': 'has been marked for add'}
+        reason = reasons.get(repo.dirstate.state(abs))
+        if reason:
+            if exact: ui.warn('%s: not copying - file %s\n' % (rel, reason))
+        else:
+            return True
+
+    for src, abs, rel, exact in walk(repo, pats, opts):
+        if okaytocopy(abs, rel, exact):
+            sources.append((abs, rel, exact))
+    if not sources:
+        raise util.Abort('no files to copy')
+
+    cwd = repo.getcwd()
+    absdest = util.canonpath(repo.root, cwd, dest)
+    reldest = util.pathto(cwd, absdest)
+    if os.path.exists(reldest):
+        destisfile = not os.path.isdir(reldest)
+    else:
+        destisfile = len(sources) == 1 or repo.dirstate.state(absdest) != '?'
+
+    if destisfile:
+        if opts['parents']:
+            raise util.Abort('with --parents, destination must be a directory')
+        elif len(sources) > 1:
+            raise util.Abort('with multiple sources, destination must be a '
+                             'directory')
+    errs = 0
+    for abs, rel, exact in sources:
+        if opts['parents']:
+            mydest = os.path.join(dest, rel)
+        elif destisfile:
+            mydest = reldest
+        else:
+            mydest = os.path.join(dest, os.path.basename(rel))
+        myabsdest = util.canonpath(repo.root, cwd, mydest)
+        myreldest = util.pathto(cwd, myabsdest)
+        if not opts['force'] and repo.dirstate.state(myabsdest) not in 'a?':
+            ui.warn('%s: not overwriting - file already managed\n' % myreldest)
+            continue
+        mydestdir = os.path.dirname(myreldest) or '.'
+        if not opts['after']:
+            try:
+                if opts['parents']: os.makedirs(mydestdir)
+                elif not destisfile: os.mkdir(mydestdir)
+            except OSError, inst:
+                if inst.errno != errno.EEXIST: raise
+        if ui.verbose or not exact:
+            ui.status('copying %s to %s\n' % (rel, myreldest))
+        if not opts['after']:
+            try:
+                shutil.copyfile(rel, myreldest)
+                n = repo.manifest.tip()
+                mf = repo.manifest.readflags(n)
+                util.set_exec(myreldest, util.is_exec(rel, mf[abs]))
+            except IOError, inst:
+                if inst.errno == errno.ENOENT:
+                    ui.warn('%s: deleted in working copy\n' % rel)
+                else:
+                    ui.warn('%s: cannot copy - %s\n' % (rel, inst.strerror))
+                errs += 1
+                continue
+        repo.copy(abs, myabsdest)
+    if errs:
+        ui.warn('(consider using --after to record failed copies)\n')
+    return errs
 
 def debugcheckstate(ui, repo):
     """validate the correctness of the current dirstate"""
@@ -1324,6 +1399,11 @@
         if okaytoremove(abs, rel, exact):
             if not exact: ui.status('removing %s\n' % rel)
             names.append(abs)
+    for name in names:
+        try:
+            os.unlink(name)
+        except OSError, inst:
+            if inst.errno != errno.ENOENT: raise
     repo.remove(names)
 
 def revert(ui, repo, *names, **opts):
@@ -1683,7 +1763,13 @@
           ('d', 'date', "", 'date code'),
           ('u', 'user', "", 'user')],
          'hg commit [OPTION]... [FILE]...'),
-    "copy": (copy, [], 'hg copy SOURCE DEST'),
+    "copy|cp": (copy,
+             [('I', 'include', [], 'include path in search'),
+              ('X', 'exclude', [], 'exclude path from search'),
+              ('A', 'after', None, 'record a copy after it has happened'),
+              ('f', 'force', None, 'replace destination if it exists'),
+              ('p', 'parents', None, 'append source path to dest')],
+             'hg copy [OPTION]... [SOURCE]... DEST'),
     "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
     "debugconfig": (debugconfig, [], 'debugconfig'),
     "debugstate": (debugstate, [], 'debugstate'),
--- a/tests/test-copy2	Wed Sep 14 15:50:31 2005 -0500
+++ b/tests/test-copy2	Wed Sep 14 14:39:46 2005 -0700
@@ -26,7 +26,7 @@
 hg debugrename bar
 
 cp foo bar
-hg copy foo bar
+hg copy -f foo bar
 echo "# should show copy"
 hg debugstate|grep '^copy'
 hg commit -m3 -d"0 0"
--- a/tests/test-help.out	Wed Sep 14 15:50:31 2005 -0500
+++ b/tests/test-help.out	Wed Sep 14 14:39:46 2005 -0700
@@ -43,7 +43,7 @@
  cat         output the latest or given revision of a file
  clone       make a copy of an existing repository
  commit      commit the specified files or all outstanding changes
- copy        mark a file as copied or renamed for the next commit
+ copy        mark files as copied for the next commit
  diff        diff working directory (or selected files)
  export      dump the header and diffs for one or more changesets
  forget      don't add the specified files on the next commit
@@ -84,7 +84,7 @@
  cat         output the latest or given revision of a file
  clone       make a copy of an existing repository
  commit      commit the specified files or all outstanding changes
- copy        mark a file as copied or renamed for the next commit
+ copy        mark files as copied for the next commit
  diff        diff working directory (or selected files)
  export      dump the header and diffs for one or more changesets
  forget      don't add the specified files on the next commit