Mercurial > hg
changeset 2021:fc22ed56afe3
Fix hg push and hg push -r sometimes creating new heads without --force.
Fixing issue179.
The algorithm checks if there not more new heads on the remote side than heads
which become non-heads due to getting children.
Pushing this repo:
m
/\
3 3a|
|/ /
2 2a
|/
1
to a repo only having 1, 2 and 3 didn't abort requiring --force before.
Added test cases for this and some doc strings for used methods.
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Wed, 29 Mar 2006 22:35:21 +0200 |
parents | 00925397236c |
children | a59da8cc35e4 |
files | mercurial/localrepo.py tests/test-push-warn tests/test-push-warn.out |
diffstat | 3 files changed, 76 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/localrepo.py Wed Mar 29 10:31:58 2006 -0800 +++ b/mercurial/localrepo.py Wed Mar 29 22:35:21 2006 +0200 @@ -923,6 +923,14 @@ return fetch.keys() def findoutgoing(self, remote, base=None, heads=None, force=False): + """Return list of nodes that are roots of subsets not in remote + + If base dict is specified, assume that these nodes and their parents + exist on the remote side. + If a list of heads is specified, return only nodes which are heads + or ancestors of these heads, and return a second element which + contains all remote heads which get new children. + """ if base == None: base = {} self.findincoming(remote, base, heads, force=force) @@ -944,13 +952,23 @@ # find every node whose parents have been pruned subset = [] + # find every remote head that will get new children + updated_heads = {} for n in remain: p1, p2 = self.changelog.parents(n) if p1 not in remain and p2 not in remain: subset.append(n) + if heads: + if p1 in heads: + updated_heads[p1] = True + if p2 in heads: + updated_heads[p2] = True # this is the set of all roots we have to push - return subset + if heads: + return subset, updated_heads.keys() + else: + return subset def pull(self, remote, heads=None, force=False): l = self.lock() @@ -976,14 +994,15 @@ lock = remote.lock() base = {} - heads = remote.heads() - inc = self.findincoming(remote, base, heads, force=force) + remote_heads = remote.heads() + inc = self.findincoming(remote, base, remote_heads, force=force) 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")) + self.ui.status(_("(did you forget to sync?" + " use push -f to force)\n")) return 1 - update = self.findoutgoing(remote, base) + update, updated_heads = self.findoutgoing(remote, base, remote_heads) if revs is not None: msng_cl, bases, heads = self.changelog.nodesbetween(update, revs) else: @@ -993,7 +1012,14 @@ self.ui.status(_("no changes found\n")) return 1 elif not force: - if len(bases) < len(heads): + if revs is not None: + updated_heads = {} + for base in msng_cl: + for parent in self.changelog.parents(base): + if parent in remote_heads: + updated_heads[parent] = True + updated_heads = updated_heads.keys() + if len(updated_heads) < len(heads): self.ui.warn(_("abort: push creates new remote branches!\n")) self.ui.status(_("(did you forget to merge?" " use push -f to force)\n"))
--- a/tests/test-push-warn Wed Mar 29 10:31:58 2006 -0800 +++ b/tests/test-push-warn Wed Mar 29 22:35:21 2006 +0200 @@ -26,3 +26,30 @@ hg up -m hg commit -m "4" -d "1000000 0" hg push ../a +cd .. + +hg init c +cd c +for i in 0 1 2; do + echo $i >> foo + hg ci -Am $i -d "1000000 0" +done +cd .. + +hg clone c d +cd d +for i in 0 1; do + hg co -C $i + echo d-$i >> foo + hg ci -m d-$i -d "1000000 0" +done + +HGMERGE=true hg co -m 3 +hg ci -m c-d -d "1000000 0" + +hg push ../c +hg push -r 2 ../c +hg push -r 3 -r 4 ../c +hg push -r 5 ../c + +exit 0
--- a/tests/test-push-warn.out Wed Mar 29 10:31:58 2006 -0800 +++ b/tests/test-push-warn.out Wed Mar 29 22:35:21 2006 +0200 @@ -19,3 +19,20 @@ adding manifests adding file changes added 2 changesets with 1 changes to 1 files +adding foo +merging foo +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 +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 +abort: push creates new remote branches! +(did you forget to merge? use push -f to force)