Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 2339:11422943cf72
document and fix findincoming
- add documentation about what the function does, notably
the fact that it updates 'base'
- transform the workflow to a more simple 'if elif elif else'
- do not call remote.branches if not necessary
- some nodes where missing in 'base' (from what I understand,
if the root of a branch is missing but one parent is present,
the parent should be in 'base')
- add a testcase for an incorrect outgoing that is fixed by
this cset
- add a testcase for an empty group bug, it needs fixing
author | Benoit Boissinot <benoit.boissinot@ens-lyon.org> |
---|---|
date | Tue, 23 May 2006 10:44:40 +0200 |
parents | f0680b2d1d64 |
children | 925610b2d90a |
comparison
equal
deleted
inserted
replaced
2337:3f24bc5dee81 | 2339:11422943cf72 |
---|---|
897 r.append(l) | 897 r.append(l) |
898 | 898 |
899 return r | 899 return r |
900 | 900 |
901 def findincoming(self, remote, base=None, heads=None, force=False): | 901 def findincoming(self, remote, base=None, heads=None, force=False): |
902 """Return list of roots of the subsets of missing nodes from remote | |
903 | |
904 If base dict is specified, assume that these nodes and their parents | |
905 exist on the remote side and that no child of a node of base exists | |
906 in both remote and self. | |
907 Furthermore base will be updated to include the nodes that exists | |
908 in self and remote but no children exists in self and remote. | |
909 If a list of heads is specified, return only nodes which are heads | |
910 or ancestors of these heads. | |
911 | |
912 All the ancestors of base are in self and in remote. | |
913 All the descendants of the list returned are missing in self. | |
914 (and so we know that the rest of the nodes are missing in remote, see | |
915 outgoing) | |
916 """ | |
902 m = self.changelog.nodemap | 917 m = self.changelog.nodemap |
903 search = [] | 918 search = [] |
904 fetch = {} | 919 fetch = {} |
905 seen = {} | 920 seen = {} |
906 seenbranch = {} | 921 seenbranch = {} |
909 | 924 |
910 if not heads: | 925 if not heads: |
911 heads = remote.heads() | 926 heads = remote.heads() |
912 | 927 |
913 if self.changelog.tip() == nullid: | 928 if self.changelog.tip() == nullid: |
929 base[nullid] = 1 | |
914 if heads != [nullid]: | 930 if heads != [nullid]: |
915 return [nullid] | 931 return [nullid] |
916 return [] | 932 return [] |
917 | 933 |
918 # assume we're closer to the tip than the root | 934 # assume we're closer to the tip than the root |
927 base[h] = 1 | 943 base[h] = 1 |
928 | 944 |
929 if not unknown: | 945 if not unknown: |
930 return [] | 946 return [] |
931 | 947 |
932 rep = {} | 948 req = dict.fromkeys(unknown) |
933 reqcnt = 0 | 949 reqcnt = 0 |
934 | 950 |
935 # search through remote branches | 951 # search through remote branches |
936 # a 'branch' here is a linear segment of history, with four parts: | 952 # a 'branch' here is a linear segment of history, with four parts: |
937 # head, root, first parent, second parent | 953 # head, root, first parent, second parent |
944 if n[0] in seen: | 960 if n[0] in seen: |
945 continue | 961 continue |
946 | 962 |
947 self.ui.debug(_("examining %s:%s\n") | 963 self.ui.debug(_("examining %s:%s\n") |
948 % (short(n[0]), short(n[1]))) | 964 % (short(n[0]), short(n[1]))) |
949 if n[0] == nullid: | 965 if n[0] == nullid: # found the end of the branch |
950 break | 966 pass |
951 if n in seenbranch: | 967 elif n in seenbranch: |
952 self.ui.debug(_("branch already found\n")) | 968 self.ui.debug(_("branch already found\n")) |
953 continue | 969 continue |
954 if n[1] and n[1] in m: # do we know the base? | 970 elif n[1] and n[1] in m: # do we know the base? |
955 self.ui.debug(_("found incomplete branch %s:%s\n") | 971 self.ui.debug(_("found incomplete branch %s:%s\n") |
956 % (short(n[0]), short(n[1]))) | 972 % (short(n[0]), short(n[1]))) |
957 search.append(n) # schedule branch range for scanning | 973 search.append(n) # schedule branch range for scanning |
958 seenbranch[n] = 1 | 974 seenbranch[n] = 1 |
959 else: | 975 else: |
960 if n[1] not in seen and n[1] not in fetch: | 976 if n[1] not in seen and n[1] not in fetch: |
961 if n[2] in m and n[3] in m: | 977 if n[2] in m and n[3] in m: |
962 self.ui.debug(_("found new changeset %s\n") % | 978 self.ui.debug(_("found new changeset %s\n") % |
963 short(n[1])) | 979 short(n[1])) |
964 fetch[n[1]] = 1 # earliest unknown | 980 fetch[n[1]] = 1 # earliest unknown |
965 base[n[2]] = 1 # latest known | 981 for p in n[2:4]: |
966 continue | 982 if p in m: |
967 | 983 base[p] = 1 # latest known |
968 for a in n[2:4]: | 984 |
969 if a not in rep: | 985 for p in n[2:4]: |
970 r.append(a) | 986 if p not in req and p not in m: |
971 rep[a] = 1 | 987 r.append(p) |
972 | 988 req[p] = 1 |
973 seen[n[0]] = 1 | 989 seen[n[0]] = 1 |
974 | 990 |
975 if r: | 991 if r: |
976 reqcnt += 1 | 992 reqcnt += 1 |
977 self.ui.debug(_("request %d: %s\n") % | 993 self.ui.debug(_("request %d: %s\n") % |
978 (reqcnt, " ".join(map(short, r)))) | 994 (reqcnt, " ".join(map(short, r)))) |
979 for p in range(0, len(r), 10): | 995 for p in range(0, len(r), 10): |
980 for b in remote.branches(r[p:p+10]): | 996 for b in remote.branches(r[p:p+10]): |
981 self.ui.debug(_("received %s:%s\n") % | 997 self.ui.debug(_("received %s:%s\n") % |
982 (short(b[0]), short(b[1]))) | 998 (short(b[0]), short(b[1]))) |
983 if b[0] in m: | 999 unknown.append(b) |
984 self.ui.debug(_("found base node %s\n") | |
985 % short(b[0])) | |
986 base[b[0]] = 1 | |
987 elif b[0] not in seen: | |
988 unknown.append(b) | |
989 | 1000 |
990 # do binary search on the branches we found | 1001 # do binary search on the branches we found |
991 while search: | 1002 while search: |
992 n = search.pop(0) | 1003 n = search.pop(0) |
993 reqcnt += 1 | 1004 reqcnt += 1 |