correct remote heads test in prepush
authorMatt Mackall <mpm@selenic.com>
Sun, 19 Nov 2006 16:32:36 -0600
changeset 3684 975c2469c316
parent 3683 b0fd43effdb3
child 3685 193e9c6d1a6d
correct remote heads test in prepush
mercurial/localrepo.py
tests/test-push-warn
tests/test-push-warn.out
tests/test-ssh
tests/test-ssh.out
--- a/mercurial/localrepo.py	Sun Nov 19 16:32:36 2006 -0600
+++ b/mercurial/localrepo.py	Sun Nov 19 16:32:36 2006 -0600
@@ -1309,20 +1309,40 @@
             self.ui.status(_("no changes found\n"))
             return None, 1
         elif not force:
-            # FIXME we don't properly detect creation of new heads
-            # in the push -r case, assume the user knows what he's doing
-            if not revs and len(remote_heads) < len(heads) \
-                   and remote_heads != [nullid]:
+            # check if we're creating new remote heads
+            # to be a remote head after push, node must be either
+            # - unknown locally
+            # - a local outgoing head descended from update
+            # - a remote head that's known locally and not
+            #   ancestral to an outgoing head
+
+            warn = 0
+
+            if remote_heads == [nullid]:
+                warn = 0
+            elif not revs and len(heads) > len(remote_heads):
+                warn = 1
+            else:
+                newheads = list(heads)
+                for r in remote_heads:
+                    if r in self.changelog.nodemap:
+                        desc = self.changelog.heads(r)
+                        l = [h for h in heads if h in desc]
+                        if not l:
+                            newheads.append(r)
+                    else:
+                        newheads.append(r)
+                if len(newheads) > len(remote_heads):
+                    warn = 1
+
+            if warn:
                 self.ui.warn(_("abort: push creates new remote branches!\n"))
                 self.ui.status(_("(did you forget to merge?"
                                  " use push -f to force)\n"))
                 return None, 1
+            elif inc:
+                self.ui.warn(_("note: unsynced remote changes!\n"))
 
-        if not force and inc:
-            self.ui.warn(_("abort: unsynced remote changes!\n"))
-            self.ui.status(_("(did you forget to sync?"
-                             " use push -f to force)\n"))
-            return None, 1
 
         if revs is None:
             cg = self.changegroup(update, 'push')
--- a/tests/test-push-warn	Sun Nov 19 16:32:36 2006 -0600
+++ b/tests/test-push-warn	Sun Nov 19 16:32:36 2006 -0600
@@ -50,6 +50,7 @@
 hg push ../c
 hg push -r 2 ../c
 hg push -r 3 -r 4 ../c
+hg push -f -r 3 -r 4 ../c
 hg push -r 5 ../c
 
 exit 0
--- a/tests/test-push-warn.out	Sun Nov 19 16:32:36 2006 -0600
+++ b/tests/test-push-warn.out	Sun Nov 19 16:32:36 2006 -0600
@@ -1,8 +1,8 @@
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 pushing to ../a
 searching for changes
-abort: unsynced remote changes!
-(did you forget to sync? use push -f to force)
+abort: push creates new remote branches!
+(did you forget to merge? use push -f to force)
 pulling from ../a
 searching for changes
 adding changesets
@@ -38,6 +38,10 @@
 no changes found
 pushing to ../c
 searching for changes
+abort: push creates new remote branches!
+(did you forget to merge? use push -f to force)
+pushing to ../c
+searching for changes
 adding changesets
 adding manifests
 adding file changes
--- a/tests/test-ssh	Sun Nov 19 16:32:36 2006 -0600
+++ b/tests/test-ssh	Sun Nov 19 16:32:36 2006 -0600
@@ -92,11 +92,8 @@
 echo r > r
 hg ci -A -m z -d '1000002 0' r
 
-echo "# push should fail"
+echo "# push should succeed"
 hg push
 
-echo "# push should succeed"
-hg push -f
-
 cd ..
 cat dummylog
--- a/tests/test-ssh.out	Sun Nov 19 16:32:36 2006 -0600
+++ b/tests/test-ssh.out	Sun Nov 19 16:32:36 2006 -0600
@@ -68,14 +68,10 @@
 checking files
 1 files, 2 changesets, 2 total revisions
 bleah
-# push should fail
-pushing to ssh://user@dummy/remote
-searching for changes
-abort: unsynced remote changes!
-(did you forget to sync? use push -f to force)
 # push should succeed
 pushing to ssh://user@dummy/remote
 searching for changes
+note: unsynced remote changes!
 remote: adding changesets
 remote: adding manifests
 remote: adding file changes
@@ -89,5 +85,4 @@
 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
 changegroup in remote: u=remote:ssh:127.0.0.1
 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
-Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
 changegroup in remote: u=remote:ssh:127.0.0.1