diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1517,8 +1517,15 @@ class localrepository(repo.repository): if len(lheads) > len(rheads): warn = 1 else: + # add local heads involved in the push + updatelheads = [self.changelog.heads(x, lheads) + for x in update] + newheads = set(sum(updatelheads, [])) & set(lheads) + + if not newheads: + return True + # add heads we don't have or that are not involved in the push - newheads = set(lheads) for r in rheads: if r in self.changelog.nodemap: desc = self.changelog.heads(r, heads) diff --git a/tests/test-push-warn b/tests/test-push-warn --- a/tests/test-push-warn +++ b/tests/test-push-warn @@ -1,5 +1,8 @@ #!/bin/sh +echo "[extensions]" >> $HGRCPATH +echo "graphlog=" >> $HGRCPATH + mkdir a cd a hg init @@ -193,5 +196,72 @@ hg -q ci -d '0 0' -mb2 hg -q merge 3 hg -q ci -d '0 0' -mma hg push ../l -b b +cd .. + +echo % check prepush with new branch head on former topo non-head +hg init n +cd n +hg branch A +echo a >a +hg ci -Ama +hg branch B +echo b >b +hg ci -Amb +# b is now branch head of B, and a topological head +# a is now branch head of A, but not a topological head +hg clone . inner +cd inner +hg up B +echo b1 >b1 +hg ci -Amb1 +# in the clone b1 is now the head of B +cd .. +hg up 0 +echo a2 >a2 +hg ci -Ama2 +# a2 is now the new branch head of A, and a new topological head +# it replaces a former inner branch head, so it should at most warn about A, not B +echo %% glog of local +hg glog --template "{rev}: {branches} {desc}\n" +echo %% glog of remote +hg glog -R inner --template "{rev}: {branches} {desc}\n" +echo %% outgoing +hg out inner --template "{rev}: {branches} {desc}\n" +hg push inner +cd .. + +echo % check prepush with new branch head on former topo head +hg init o +cd o +hg branch A +echo a >a +hg ci -Ama +hg branch B +echo b >b +hg ci -Amb +# b is now branch head of B, and a topological head +hg up 0 +echo a1 >a1 +hg ci -Ama1 +# a1 is now branch head of A, and a topological head +hg clone . inner +cd inner +hg up B +echo b1 >b1 +hg ci -Amb1 +# in the clone b1 is now the head of B +cd .. +echo a2 >a2 +hg ci -Ama2 +# a2 is now the new branch head of A, and a topological head +# it replaces a former topological and branch head, so this should not warn +echo %% glog of local +hg glog --template "{rev}: {branches} {desc}\n" +echo %% glog of remote +hg glog -R inner --template "{rev}: {branches} {desc}\n" +echo %% outgoing +hg out inner --template "{rev}: {branches} {desc}\n" +hg push inner +cd .. exit 0 diff --git a/tests/test-push-warn.out b/tests/test-push-warn.out --- a/tests/test-push-warn.out +++ b/tests/test-push-warn.out @@ -175,3 +175,82 @@ pushing to ../l searching for changes abort: push creates new remote heads on branch 'a'! (did you forget to merge? use push -f to force) +% check prepush with new branch head on former topo non-head +marked working directory as branch A +adding a +marked working directory as branch B +adding b +updating to branch B +2 files updated, 0 files merged, 0 files removed, 0 files unresolved +0 files updated, 0 files merged, 0 files removed, 0 files unresolved +adding b1 +0 files updated, 0 files merged, 1 files removed, 0 files unresolved +adding a2 +created new head +%% glog of local +@ 2: A a2 +| +| o 1: B b +|/ +o 0: A a + +%% glog of remote +@ 2: B b1 +| +o 1: B b +| +o 0: A a + +%% outgoing +comparing with inner +searching for changes +2: A a2 +pushing to inner +searching for changes +note: unsynced remote changes! +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files (+1 heads) +% check prepush with new branch head on former topo head +marked working directory as branch A +adding a +marked working directory as branch B +adding b +0 files updated, 0 files merged, 1 files removed, 0 files unresolved +adding a1 +created new head +updating to branch A +2 files updated, 0 files merged, 0 files removed, 0 files unresolved +1 files updated, 0 files merged, 1 files removed, 0 files unresolved +adding b1 +adding a2 +%% glog of local +@ 3: A a2 +| +o 2: A a1 +| +| o 1: B b +|/ +o 0: A a + +%% glog of remote +@ 3: B b1 +| +| o 2: A a1 +| | +o | 1: B b +|/ +o 0: A a + +%% outgoing +comparing with inner +searching for changes +3: A a2 +pushing to inner +searching for changes +note: unsynced remote changes! +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files