10 from node import * |
10 from node import * |
11 from i18n import gettext as _ |
11 from i18n import gettext as _ |
12 from demandload import * |
12 from demandload import * |
13 demandload(globals(), "appendfile changegroup") |
13 demandload(globals(), "appendfile changegroup") |
14 demandload(globals(), "re lock transaction tempfile stat mdiff errno ui") |
14 demandload(globals(), "re lock transaction tempfile stat mdiff errno ui") |
15 demandload(globals(), "revlog traceback") |
15 demandload(globals(), "revlog") |
16 |
16 |
17 class localrepository(object): |
17 class localrepository(object): |
18 def __del__(self): |
18 def __del__(self): |
19 self.transhandle = None |
19 self.transhandle = None |
20 def __init__(self, parentui, path=None, create=0): |
20 def __init__(self, parentui, path=None, create=0): |
123 else: |
123 else: |
124 self.ui.warn(_('error: %s hook raised an exception: ' |
124 self.ui.warn(_('error: %s hook raised an exception: ' |
125 '%s\n') % (hname, exc)) |
125 '%s\n') % (hname, exc)) |
126 if throw: |
126 if throw: |
127 raise |
127 raise |
128 if self.ui.traceback: |
128 self.ui.print_exc() |
129 traceback.print_exc() |
|
130 return True |
129 return True |
131 if r: |
130 if r: |
132 if throw: |
131 if throw: |
133 raise util.Abort(_('%s hook failed') % hname) |
132 raise util.Abort(_('%s hook failed') % hname) |
134 self.ui.warn(_('warning: %s hook failed\n') % hname) |
133 self.ui.warn(_('warning: %s hook failed\n') % hname) |
898 r.append(l) |
897 r.append(l) |
899 |
898 |
900 return r |
899 return r |
901 |
900 |
902 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 """ |
903 m = self.changelog.nodemap |
917 m = self.changelog.nodemap |
904 search = [] |
918 search = [] |
905 fetch = {} |
919 fetch = {} |
906 seen = {} |
920 seen = {} |
907 seenbranch = {} |
921 seenbranch = {} |
928 base[h] = 1 |
943 base[h] = 1 |
929 |
944 |
930 if not unknown: |
945 if not unknown: |
931 return [] |
946 return [] |
932 |
947 |
933 rep = {} |
948 req = dict.fromkeys(unknown) |
934 reqcnt = 0 |
949 reqcnt = 0 |
935 |
950 |
936 # search through remote branches |
951 # search through remote branches |
937 # 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: |
938 # head, root, first parent, second parent |
953 # head, root, first parent, second parent |
945 if n[0] in seen: |
960 if n[0] in seen: |
946 continue |
961 continue |
947 |
962 |
948 self.ui.debug(_("examining %s:%s\n") |
963 self.ui.debug(_("examining %s:%s\n") |
949 % (short(n[0]), short(n[1]))) |
964 % (short(n[0]), short(n[1]))) |
950 if n[0] == nullid: |
965 if n[0] == nullid: # found the end of the branch |
951 break |
966 pass |
952 if n in seenbranch: |
967 elif n in seenbranch: |
953 self.ui.debug(_("branch already found\n")) |
968 self.ui.debug(_("branch already found\n")) |
954 continue |
969 continue |
955 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? |
956 self.ui.debug(_("found incomplete branch %s:%s\n") |
971 self.ui.debug(_("found incomplete branch %s:%s\n") |
957 % (short(n[0]), short(n[1]))) |
972 % (short(n[0]), short(n[1]))) |
958 search.append(n) # schedule branch range for scanning |
973 search.append(n) # schedule branch range for scanning |
959 seenbranch[n] = 1 |
974 seenbranch[n] = 1 |
960 else: |
975 else: |
961 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: |
962 if n[2] in m and n[3] in m: |
977 if n[2] in m and n[3] in m: |
963 self.ui.debug(_("found new changeset %s\n") % |
978 self.ui.debug(_("found new changeset %s\n") % |
964 short(n[1])) |
979 short(n[1])) |
965 fetch[n[1]] = 1 # earliest unknown |
980 fetch[n[1]] = 1 # earliest unknown |
966 base[n[2]] = 1 # latest known |
981 for p in n[2:4]: |
967 continue |
982 if p in m: |
968 |
983 base[p] = 1 # latest known |
969 for a in n[2:4]: |
984 |
970 if a not in rep: |
985 for p in n[2:4]: |
971 r.append(a) |
986 if p not in req and p not in m: |
972 rep[a] = 1 |
987 r.append(p) |
973 |
988 req[p] = 1 |
974 seen[n[0]] = 1 |
989 seen[n[0]] = 1 |
975 |
990 |
976 if r: |
991 if r: |
977 reqcnt += 1 |
992 reqcnt += 1 |
978 self.ui.debug(_("request %d: %s\n") % |
993 self.ui.debug(_("request %d: %s\n") % |
979 (reqcnt, " ".join(map(short, r)))) |
994 (reqcnt, " ".join(map(short, r)))) |
980 for p in range(0, len(r), 10): |
995 for p in range(0, len(r), 10): |
981 for b in remote.branches(r[p:p+10]): |
996 for b in remote.branches(r[p:p+10]): |
982 self.ui.debug(_("received %s:%s\n") % |
997 self.ui.debug(_("received %s:%s\n") % |
983 (short(b[0]), short(b[1]))) |
998 (short(b[0]), short(b[1]))) |
984 if b[0] in m: |
999 unknown.append(b) |
985 self.ui.debug(_("found base node %s\n") |
|
986 % short(b[0])) |
|
987 base[b[0]] = 1 |
|
988 elif b[0] not in seen: |
|
989 unknown.append(b) |
|
990 |
1000 |
991 # do binary search on the branches we found |
1001 # do binary search on the branches we found |
992 while search: |
1002 while search: |
993 n = search.pop(0) |
1003 n = search.pop(0) |
994 reqcnt += 1 |
1004 reqcnt += 1 |