Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgBranches.java @ 340:a54bfe0db959
IAE using stale data from branchheads file (invalid due to repository rollback)
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Thu, 17 Nov 2011 06:16:20 +0100 |
| parents | 8952f89be195 |
| children | a0864b2892cd |
comparison
equal
deleted
inserted
replaced
| 339:863356c2847e | 340:a54bfe0db959 |
|---|---|
| 52 | 52 |
| 53 HgBranches(HgRepository hgRepo) { | 53 HgBranches(HgRepository hgRepo) { |
| 54 repo = hgRepo; | 54 repo = hgRepo; |
| 55 } | 55 } |
| 56 | 56 |
| 57 private int readCache() { | 57 private int readCache() /*XXX throws parse errors, e.g. may fail with NumberFormatException */{ |
| 58 File branchheadsCache = getCacheFile(); | 58 File branchheadsCache = getCacheFile(); |
| 59 int lastInCache = -1; | 59 int lastInCache = -1; |
| 60 if (!branchheadsCache.canRead()) { | 60 if (!branchheadsCache.canRead()) { |
| 61 return lastInCache; | 61 return lastInCache; |
| 62 } | 62 } |
| 69 if (line == null || line.trim().length() == 0) { | 69 if (line == null || line.trim().length() == 0) { |
| 70 return lastInCache; | 70 return lastInCache; |
| 71 } | 71 } |
| 72 String[] cacheIdentity = spacePattern.split(line.trim()); | 72 String[] cacheIdentity = spacePattern.split(line.trim()); |
| 73 lastInCache = Integer.parseInt(cacheIdentity[1]); | 73 lastInCache = Integer.parseInt(cacheIdentity[1]); |
| 74 // XXX may want to check if nodeid of cset from repo.getChangelog() of lastInCache index match cacheIdentity[0] | 74 final int lastKnownRepoRevIndex = repo.getChangelog().getLastRevision(); |
| 75 // | 75 if (lastInCache > lastKnownRepoRevIndex || !repo.getChangelog().getRevision(lastKnownRepoRevIndex).equals(Nodeid.fromAscii(cacheIdentity[0]))) { |
| 76 // there are chances cache file got invalid entries due to e.g. rollback operation | |
| 77 return -1; | |
| 78 } | |
| 76 while ((line = br.readLine()) != null) { | 79 while ((line = br.readLine()) != null) { |
| 77 String[] elements = spacePattern.split(line.trim()); | 80 String[] elements = spacePattern.split(line.trim()); |
| 78 if (elements.length != 2) { | 81 if (elements.length != 2) { |
| 79 // bad entry | 82 // bad entry |
| 80 continue; | 83 continue; |
| 110 void collect(final ProgressSupport ps) { | 113 void collect(final ProgressSupport ps) { |
| 111 branches.clear(); | 114 branches.clear(); |
| 112 ps.start(1 + repo.getChangelog().getRevisionCount() * 2); | 115 ps.start(1 + repo.getChangelog().getRevisionCount() * 2); |
| 113 // | 116 // |
| 114 int lastCached = readCache(); | 117 int lastCached = readCache(); |
| 115 /* | |
| 116 * Next code was supposed to fill missing aspects of the BranchInfo, but is too slow | |
| 117 * | |
| 118 if (lastCached != -1 && lastCached <= repo.getChangelog().getLastRevision()) { | |
| 119 LinkedList<BranchInfo> incompleteBranches = new LinkedList<HgBranches.BranchInfo>(branches.values()); | |
| 120 for (BranchInfo bi : incompleteBranches) { | |
| 121 LinkedList<Nodeid> closedHeads = new LinkedList<Nodeid>(); | |
| 122 for (Nodeid h : bi.getHeads()) { | |
| 123 if ("1".equals(repo.getChangelog().changeset(h).extras().get("close"))) { | |
| 124 closedHeads.add(h); | |
| 125 } | |
| 126 } | |
| 127 HashSet<Nodeid> earliest = new HashSet<Nodeid>(bi.getHeads()); | |
| 128 HashSet<Nodeid> visited = new HashSet<Nodeid>(); | |
| 129 ArrayList<Nodeid> parents = new ArrayList<Nodeid>(2); | |
| 130 HashSet<Nodeid> candidate = new HashSet<Nodeid>(); | |
| 131 do { | |
| 132 candidate.clear(); | |
| 133 for (Nodeid e : earliest) { | |
| 134 parents.clear(); | |
| 135 if (pw.appendParentsOf(e, parents)) { | |
| 136 // at least one parent | |
| 137 Nodeid p1 = parents.get(0); | |
| 138 if (p1 != null && !visited.contains(p1) && bi.getName().equals(repo.getChangelog().changeset(p1).branch())) { | |
| 139 visited.add(p1); | |
| 140 candidate.add(p1); | |
| 141 } | |
| 142 Nodeid p2 = parents.size() > 1 ? parents.get(1) : null; | |
| 143 if (p2 != null && !visited.contains(p2) && bi.getName().equals(repo.getChangelog().changeset(p2).branch())) { | |
| 144 visited.add(p2); | |
| 145 candidate.add(p2); | |
| 146 } | |
| 147 } | |
| 148 } | |
| 149 if (!candidate.isEmpty()) { | |
| 150 earliest.clear(); | |
| 151 earliest.addAll(candidate); | |
| 152 } | |
| 153 } while (!candidate.isEmpty()); | |
| 154 // earliest can't be empty, we've started with non-empty heads. | |
| 155 Nodeid first = null; | |
| 156 if (earliest.size() == 1) { | |
| 157 first = earliest.iterator().next(); | |
| 158 } else { | |
| 159 int earliestRevNum = Integer.MAX_VALUE; | |
| 160 for (Nodeid e : earliest) { | |
| 161 int x = repo.getChangelog().getLocalRevision(e); | |
| 162 if (x < earliestRevNum) { | |
| 163 earliestRevNum = x; | |
| 164 first = e; | |
| 165 } | |
| 166 } | |
| 167 } | |
| 168 assert first != null; | |
| 169 System.out.println("Updated branch " + bi.getName()); | |
| 170 branches.put(bi.getName(), new BranchInfo(bi.getName(), first, bi.getHeads().toArray(new Nodeid[0]), closedHeads.size() == bi.getHeads().size())); | |
| 171 } | |
| 172 } | |
| 173 */ | |
| 174 isCacheActual = lastCached == repo.getChangelog().getLastRevision(); | 118 isCacheActual = lastCached == repo.getChangelog().getLastRevision(); |
| 175 if (!isCacheActual) { | 119 if (!isCacheActual) { |
| 176 final HgChangelog.ParentWalker pw = repo.getChangelog().new ParentWalker(); | 120 final HgChangelog.ParentWalker pw = repo.getChangelog().new ParentWalker(); |
| 177 pw.init(); | 121 pw.init(); |
| 178 ps.worked(repo.getChangelog().getRevisionCount()); | 122 ps.worked(repo.getChangelog().getRevisionCount()); |
