# HG changeset patch # User Artem Tikhomirov # Date 1321506980 -3600 # Node ID a54bfe0db959dc332270c4eea0a40e0c404e1702 # Parent 863356c2847e251a815a0e2c3b92f91d0461dfdd IAE using stale data from branchheads file (invalid due to repository rollback) diff -r 863356c2847e -r a54bfe0db959 cmdline/org/tmatesoft/hg/console/Main.java --- a/cmdline/org/tmatesoft/hg/console/Main.java Wed Nov 16 22:42:21 2011 +0100 +++ b/cmdline/org/tmatesoft/hg/console/Main.java Thu Nov 17 06:16:20 2011 +0100 @@ -99,9 +99,9 @@ // m.testParents(); // m.testEffectiveFileLog(); // m.testCatAtCsetRevision(); - m.testMergeState(); +// m.testMergeState(); // m.testFileStatus(); -// m.dumpBranches(); + m.dumpBranches(); // m.inflaterLengthException(); // m.dumpIgnored(); // m.dumpDirstate(); diff -r 863356c2847e -r a54bfe0db959 src/org/tmatesoft/hg/repo/HgBranches.java --- a/src/org/tmatesoft/hg/repo/HgBranches.java Wed Nov 16 22:42:21 2011 +0100 +++ b/src/org/tmatesoft/hg/repo/HgBranches.java Thu Nov 17 06:16:20 2011 +0100 @@ -54,7 +54,7 @@ repo = hgRepo; } - private int readCache() { + private int readCache() /*XXX throws parse errors, e.g. may fail with NumberFormatException */{ File branchheadsCache = getCacheFile(); int lastInCache = -1; if (!branchheadsCache.canRead()) { @@ -71,8 +71,11 @@ } String[] cacheIdentity = spacePattern.split(line.trim()); lastInCache = Integer.parseInt(cacheIdentity[1]); - // XXX may want to check if nodeid of cset from repo.getChangelog() of lastInCache index match cacheIdentity[0] - // + final int lastKnownRepoRevIndex = repo.getChangelog().getLastRevision(); + if (lastInCache > lastKnownRepoRevIndex || !repo.getChangelog().getRevision(lastKnownRepoRevIndex).equals(Nodeid.fromAscii(cacheIdentity[0]))) { + // there are chances cache file got invalid entries due to e.g. rollback operation + return -1; + } while ((line = br.readLine()) != null) { String[] elements = spacePattern.split(line.trim()); if (elements.length != 2) { @@ -112,65 +115,6 @@ ps.start(1 + repo.getChangelog().getRevisionCount() * 2); // int lastCached = readCache(); - /* - * Next code was supposed to fill missing aspects of the BranchInfo, but is too slow - * - if (lastCached != -1 && lastCached <= repo.getChangelog().getLastRevision()) { - LinkedList incompleteBranches = new LinkedList(branches.values()); - for (BranchInfo bi : incompleteBranches) { - LinkedList closedHeads = new LinkedList(); - for (Nodeid h : bi.getHeads()) { - if ("1".equals(repo.getChangelog().changeset(h).extras().get("close"))) { - closedHeads.add(h); - } - } - HashSet earliest = new HashSet(bi.getHeads()); - HashSet visited = new HashSet(); - ArrayList parents = new ArrayList(2); - HashSet candidate = new HashSet(); - do { - candidate.clear(); - for (Nodeid e : earliest) { - parents.clear(); - if (pw.appendParentsOf(e, parents)) { - // at least one parent - Nodeid p1 = parents.get(0); - if (p1 != null && !visited.contains(p1) && bi.getName().equals(repo.getChangelog().changeset(p1).branch())) { - visited.add(p1); - candidate.add(p1); - } - Nodeid p2 = parents.size() > 1 ? parents.get(1) : null; - if (p2 != null && !visited.contains(p2) && bi.getName().equals(repo.getChangelog().changeset(p2).branch())) { - visited.add(p2); - candidate.add(p2); - } - } - } - if (!candidate.isEmpty()) { - earliest.clear(); - earliest.addAll(candidate); - } - } while (!candidate.isEmpty()); - // earliest can't be empty, we've started with non-empty heads. - Nodeid first = null; - if (earliest.size() == 1) { - first = earliest.iterator().next(); - } else { - int earliestRevNum = Integer.MAX_VALUE; - for (Nodeid e : earliest) { - int x = repo.getChangelog().getLocalRevision(e); - if (x < earliestRevNum) { - earliestRevNum = x; - first = e; - } - } - } - assert first != null; - System.out.println("Updated branch " + bi.getName()); - branches.put(bi.getName(), new BranchInfo(bi.getName(), first, bi.getHeads().toArray(new Nodeid[0]), closedHeads.size() == bi.getHeads().size())); - } - } - */ isCacheActual = lastCached == repo.getChangelog().getLastRevision(); if (!isCacheActual) { final HgChangelog.ParentWalker pw = repo.getChangelog().new ParentWalker();