merge with stable
authorMatt Mackall <mpm@selenic.com>
Thu, 17 Nov 2011 16:53:17 -0600
changeset 15513 646759147717
parent 15510 5414b56cfad6 (current diff)
parent 15512 8b011ededfb2 (diff)
child 15523 f9da84a950d0
merge with stable
mercurial/commands.py
mercurial/discovery.py
mercurial/dispatch.py
mercurial/mdiff.py
mercurial/subrepo.py
mercurial/util.py
tests/test-graft.t
tests/test-url.py
--- a/mercurial/commands.py	Mon Nov 14 18:16:01 2011 +0100
+++ b/mercurial/commands.py	Thu Nov 17 16:53:17 2011 -0600
@@ -2570,15 +2570,32 @@
     if not revs:
         return -1
 
+    # analyze revs for earlier grafts
+    ids = {}
+    for ctx in repo.set("%ld", revs):
+        ids[ctx.hex()] = ctx.rev()
+        n = ctx.extra().get('source')
+        if n:
+            ids[n] = ctx.rev()
+
     # check ancestors for earlier grafts
     ui.debug('scanning for duplicate grafts\n')
     for ctx in repo.set("::. - ::%ld", revs):
         n = ctx.extra().get('source')
-        if n and n in repo:
+        if n in ids:
             r = repo[n].rev()
             if r in revs:
                 ui.warn(_('skipping already grafted revision %s\n') % r)
                 revs.remove(r)
+            elif ids[n] in revs:
+                ui.warn(_('skipping already grafted revision %s '
+                            '(same origin %d)\n') % (ids[n], r))
+                revs.remove(ids[n])
+        elif ctx.hex() in ids:
+            r = ids[ctx.hex()]
+            ui.warn(_('skipping already grafted revision %s '
+                            '(was grafted from %d)\n') % (r, ctx.rev()))
+            revs.remove(r)
     if not revs:
         return -1
 
@@ -2613,7 +2630,10 @@
             cont = False
 
         # commit
-        extra = {'source': ctx.hex()}
+        source = ctx.extra().get('source')
+        if not source:
+            source = ctx.hex()
+        extra = {'source': source}
         user = ctx.user()
         if opts.get('user'):
             user = opts['user']
@@ -3513,6 +3533,12 @@
                 try:
                     p1 = repo[p1]
                     p2 = repo[p2]
+                    # Without any options, consider p2 only if the
+                    # patch is being applied on top of the recorded
+                    # first parent.
+                    if p1 != parents[0]:
+                        p1 = parents[0]
+                        p2 = repo[nullid]
                 except error.RepoError:
                     p1, p2 = parents
             else:
@@ -3520,9 +3546,9 @@
 
             n = None
             if update:
-                if opts.get('exact') and p1 != parents[0]:
+                if p1 != parents[0]:
                     hg.clean(repo, p1.node())
-                if p1 != parents[0] and p2 != parents[1]:
+                if p2 != parents[1]:
                     repo.dirstate.setparents(p1.node(), p2.node())
 
                 if opts.get('exact') or opts.get('import_branch'):
@@ -3536,7 +3562,10 @@
                     if message:
                         msgs.append(message)
                 else:
-                    if opts.get('exact'):
+                    if opts.get('exact') or p2:
+                        # If you got here, you either use --force and know what
+                        # you are doing or used --exact or a merge patch while
+                        # being updated to its first parent.
                         m = None
                     else:
                         m = scmutil.matchfiles(repo, files or [])
--- a/mercurial/discovery.py	Mon Nov 14 18:16:01 2011 +0100
+++ b/mercurial/discovery.py	Thu Nov 17 16:53:17 2011 -0600
@@ -178,9 +178,9 @@
                         hint = _("did you forget to merge? "
                                  "use push -f to force")
                 if branch is not None:
-                    repo.ui.note("new remote heads on branch '%s'\n" % branch)
+                    repo.ui.note(_("new remote heads on branch '%s'\n") % branch)
                 for h in dhs:
-                    repo.ui.note("new remote head %s\n" % short(h))
+                    repo.ui.note(_("new remote head %s\n") % short(h))
         if error:
             raise util.Abort(error, hint=hint)
 
--- a/mercurial/dispatch.py	Mon Nov 14 18:16:01 2011 +0100
+++ b/mercurial/dispatch.py	Thu Nov 17 16:53:17 2011 -0600
@@ -124,7 +124,7 @@
             ui.warn(_("hg: %s\n") % inst.args[1])
             commands.help_(ui, 'shortlist')
     except error.OutOfBandError, inst:
-        ui.warn("abort: remote error:\n")
+        ui.warn(_("abort: remote error:\n"))
         ui.warn(''.join(inst.args))
     except error.RepoError, inst:
         ui.warn(_("abort: %s!\n") % inst)
--- a/mercurial/help/urls.txt	Mon Nov 14 18:16:01 2011 +0100
+++ b/mercurial/help/urls.txt	Thu Nov 17 16:53:17 2011 -0600
@@ -1,7 +1,7 @@
 Valid URLs are of the form::
 
   local/filesystem/path[#revision]
-  file://local/filesystem/path[#revision]
+  file://localhost/filesystem/path[#revision]
   http://[user[:pass]@]host[:port]/[path][#revision]
   https://[user[:pass]@]host[:port]/[path][#revision]
   ssh://[user@]host[:port]/[path][#revision]
--- a/mercurial/hook.py	Mon Nov 14 18:16:01 2011 +0100
+++ b/mercurial/hook.py	Thu Nov 17 16:53:17 2011 -0600
@@ -139,6 +139,7 @@
             stderrno = sys.__stderr__.fileno()
             # temporarily redirect stdout to stderr, if possible
             if stdoutno >= 0 and stderrno >= 0:
+                sys.__stdout__.flush()
                 oldstdout = os.dup(stdoutno)
                 os.dup2(stderrno, stdoutno)
         except AttributeError:
--- a/mercurial/mdiff.py	Mon Nov 14 18:16:01 2011 +0100
+++ b/mercurial/mdiff.py	Thu Nov 17 16:53:17 2011 -0600
@@ -72,7 +72,7 @@
         text = re.sub('[ \t\r]+', ' ', text)
         text = text.replace(' \n', '\n')
     if blank and opts.ignoreblanklines:
-        text = re.sub('\n+', '', text)
+        text = re.sub('\n+', '\n', text).strip('\n')
     return text
 
 def diffline(revs, a, b, opts):
--- a/mercurial/setdiscovery.py	Mon Nov 14 18:16:01 2011 +0100
+++ b/mercurial/setdiscovery.py	Thu Nov 17 16:53:17 2011 -0600
@@ -128,7 +128,7 @@
         return (srvheadhashes, False, srvheadhashes,)
 
     if sample and util.all(yesno):
-        ui.note("all local heads known remotely\n")
+        ui.note(_("all local heads known remotely\n"))
         ownheadhashes = dag.externalizeall(ownheads)
         return (ownheadhashes, True, srvheadhashes,)
 
@@ -158,7 +158,7 @@
             break
 
         if full:
-            ui.note("sampling from both directions\n")
+            ui.note(_("sampling from both directions\n"))
             sample = _takefullsample(dag, undecided, size=fullsamplesize)
         elif common:
             # use cheapish initial sample
--- a/mercurial/subrepo.py	Mon Nov 14 18:16:01 2011 +0100
+++ b/mercurial/subrepo.py	Thu Nov 17 16:53:17 2011 -0600
@@ -223,7 +223,7 @@
         source.path = posixpath.normpath(source.path)
         parent = _abssource(repo._subparent, push, abort=False)
         if parent:
-            parent = util.url(parent)
+            parent = util.url(util.pconvert(parent))
             parent.path = posixpath.join(parent.path or '', source.path)
             parent.path = posixpath.normpath(parent.path)
             return str(parent)
--- a/mercurial/util.py	Mon Nov 14 18:16:01 2011 +0100
+++ b/mercurial/util.py	Thu Nov 17 16:53:17 2011 -0600
@@ -16,7 +16,7 @@
 from i18n import _
 import error, osutil, encoding
 import errno, re, shutil, sys, tempfile, traceback
-import os, time, calendar, textwrap, signal
+import os, time, datetime, calendar, textwrap, signal
 import imp, socket, urllib
 
 if os.name == 'nt':
@@ -900,16 +900,14 @@
         yield s
 
 def makedate():
-    lt = time.localtime()
-    if lt[8] == 1 and time.daylight:
-        tz = time.altzone
-    else:
-        tz = time.timezone
-    t = time.mktime(lt)
-    if t < 0:
+    ct = time.time()
+    if ct < 0:
         hint = _("check your clock")
-        raise Abort(_("negative timestamp: %d") % t, hint=hint)
-    return t, tz
+        raise Abort(_("negative timestamp: %d") % ct, hint=hint)
+    delta = (datetime.datetime.utcfromtimestamp(ct) -
+             datetime.datetime.fromtimestamp(ct))
+    tz = delta.days * 86400 + delta.seconds
+    return ct, tz
 
 def datestr(date=None, format='%a %b %d %H:%M:%S %Y %1%2'):
     """represent a (unixtime, offset) tuple as a localized time.
@@ -1708,7 +1706,8 @@
             # letters to paths with drive letters.
             if hasdriveletter(self._hostport):
                 path = self._hostport + '/' + self.path
-            elif self.host is not None and self.path:
+            elif (self.host is not None and self.path
+                  and not hasdriveletter(path)):
                 path = '/' + path
             return path
         return self._origpath
--- a/tests/test-diff-ignore-whitespace.t	Mon Nov 14 18:16:01 2011 +0100
+++ b/tests/test-diff-ignore-whitespace.t	Thu Nov 17 16:53:17 2011 -0600
@@ -442,3 +442,16 @@
 New line not noticed when space change ignored:
 
   $ hg ndiff --ignore-blank-lines --ignore-all-space
+
+Do not ignore all newlines, only blank lines
+
+  $ printf 'hello \nworld\ngoodbye world\n' > foo
+  $ hg ndiff --ignore-blank-lines
+  diff -r 540c40a65b78 foo
+  --- a/foo
+  +++ b/foo
+  @@ -1,2 +1,3 @@
+  -hello world
+  +hello 
+  +world
+   goodbye world
--- a/tests/test-graft.t	Mon Nov 14 18:16:01 2011 +0100
+++ b/tests/test-graft.t	Thu Nov 17 16:53:17 2011 -0600
@@ -200,28 +200,80 @@
 
 View graph:
 
-  $ hg --config extensions.graphlog= log -G --template '{author}@rev: {desc}\n'
-  @  test@rev: 3
+  $ hg --config extensions.graphlog= log -G --template '{author}@{rev}: {desc}\n'
+  @  test@11: 3
   |
-  o  test@rev: 4
+  o  test@10: 4
   |
-  o  test@rev: 5
+  o  test@9: 5
   |
-  o  bar@rev: 1
+  o  bar@8: 1
   |
-  o  foo@rev: 2
+  o  foo@7: 2
   |
-  | o    test@rev: 6
+  | o    test@6: 6
   | |\
-  | | o  test@rev: 5
+  | | o  test@5: 5
   | | |
-  | o |  test@rev: 4
+  | o |  test@4: 4
   | |/
-  | o  baz@rev: 3
+  | o  baz@3: 3
+  | |
+  | o  test@2: 2
   | |
-  | o  test@rev: 2
-  | |
-  | o  bar@rev: 1
+  | o  bar@1: 1
   |/
-  o  test@rev: 0
+  o  test@0: 0
   
+Graft again onto another branch should preserve the original source
+  $ hg up -q 0
+  $ echo 'g'>g
+  $ hg add g
+  $ hg ci -m 7
+  created new head
+  $ hg graft 7
+  grafting revision 7
+
+  $ hg log -r 7 --template '{rev}:{node}\n'
+  7:d2e44c99fd3f31c176ea4efb9eca9f6306c81756
+  $ hg log -r 2 --template '{rev}:{node}\n'
+  2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
+
+  $ hg log --debug -r tip
+  changeset:   13:39bb1d13572759bd1e6fc874fed1b12ece047a18
+  tag:         tip
+  parent:      12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
+  parent:      -1:0000000000000000000000000000000000000000
+  manifest:    13:0780e055d8f4cd12eadd5a2719481648f336f7a9
+  user:        foo
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  files+:      b
+  files-:      a
+  extra:       branch=default
+  extra:       source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
+  description:
+  2
+  
+  
+Disallow grafting an already grafted cset onto its original branch
+  $ hg up -q 6
+  $ hg graft 7
+  skipping already grafted revision 7 (was grafted from 2)
+  [255]
+
+Disallow grafting already grafted csets with the same origin onto each other
+  $ hg up -q 13
+  $ hg graft 2
+  skipping already grafted revision 2
+  [255]
+  $ hg graft 7
+  skipping already grafted revision 7 (same origin 2)
+  [255]
+
+  $ hg up -q 7
+  $ hg graft 2
+  skipping already grafted revision 2
+  [255]
+  $ hg graft tip
+  skipping already grafted revision 13 (same origin 2)
+  [255]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-import-merge.t	Thu Nov 17 16:53:17 2011 -0600
@@ -0,0 +1,114 @@
+  $ echo "[extensions]" >> $HGRCPATH
+  $ echo "mq=" >> $HGRCPATH
+
+  $ tipparents() {
+  > hg parents --template "{rev}:{node|short} {desc|firstline}\n" -r tip
+  > }
+
+Test import and merge diffs
+
+  $ hg init repo
+  $ cd repo
+  $ echo a > a
+  $ hg ci -Am adda
+  adding a
+  $ echo a >> a
+  $ hg ci -m changea
+  $ echo c > c
+  $ hg ci -Am addc
+  adding c
+  $ hg up 0
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ echo b > b
+  $ hg ci -Am addb
+  adding b
+  created new head
+  $ hg up 1
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg merge 3
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg ci -m merge
+  $ hg export . > ../merge.diff
+  $ cd ..
+  $ hg clone -r2 repo repo2
+  adding changesets
+  adding manifests
+  adding file changes
+  added 3 changesets with 3 changes to 2 files
+  updating to branch default
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd repo2
+  $ hg pull -r3 ../repo
+  pulling from ../repo
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+
+Test without --exact and diff.p1 == workingdir.p1
+
+  $ hg up 1
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg import ../merge.diff
+  applying ../merge.diff
+  $ tipparents
+  1:540395c44225 changea
+  3:102a90ea7b4a addb
+  $ hg strip --no-backup tip
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+Test without --exact and diff.p1 != workingdir.p1
+
+  $ hg up 2
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg import ../merge.diff
+  applying ../merge.diff
+  $ tipparents
+  2:890ecaa90481 addc
+  $ hg strip --no-backup tip
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+Test with --exact
+
+  $ hg import --exact ../merge.diff
+  applying ../merge.diff
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ tipparents
+  1:540395c44225 changea
+  3:102a90ea7b4a addb
+  $ hg strip --no-backup tip
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+Test with --bypass and diff.p1 == workingdir.p1
+
+  $ hg up 1
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg import --bypass ../merge.diff
+  applying ../merge.diff
+  $ tipparents
+  1:540395c44225 changea
+  3:102a90ea7b4a addb
+  $ hg strip --no-backup tip
+
+Test with --bypass and diff.p1 != workingdir.p1
+
+  $ hg up 2
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg import --bypass ../merge.diff
+  applying ../merge.diff
+  $ tipparents
+  2:890ecaa90481 addc
+  $ hg strip --no-backup tip
+
+Test with --bypass and --exact
+
+  $ hg import --bypass --exact ../merge.diff
+  applying ../merge.diff
+  $ tipparents
+  1:540395c44225 changea
+  3:102a90ea7b4a addb
+  $ hg strip --no-backup tip
+
--- a/tests/test-url.py	Mon Nov 14 18:16:01 2011 +0100
+++ b/tests/test-url.py	Thu Nov 17 16:53:17 2011 -0600
@@ -223,6 +223,14 @@
     >>> u.localpath()
     'f:oo/bar/baz'
 
+    >>> u = url('file://localhost/f:oo/bar/baz')
+    >>> u
+    <url scheme: 'file', host: 'localhost', path: 'f:oo/bar/baz'>
+    >>> str(u)
+    'file://localhost/f:oo/bar/baz'
+    >>> u.localpath()
+    'f:oo/bar/baz'
+
     >>> u = url('file:foo/bar/baz')
     >>> u
     <url scheme: 'file', path: 'foo/bar/baz'>