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