# HG changeset patch # User Artem Tikhomirov # Date 1294103305 -3600 # Node ID 11cfabe692b38b88bca1abdf736acad08ff31b19 # Parent 40532cdc92fc6c244553cc930ae84b7d9ead1e09 Status operation for two repository revisions (no local dir involved) diff -r 40532cdc92fc -r 11cfabe692b3 design.txt --- a/design.txt Tue Jan 04 01:01:39 2011 +0100 +++ b/design.txt Tue Jan 04 02:08:25 2011 +0100 @@ -32,7 +32,10 @@ delta merge Changeset to get index (local revision number) RevisionWalker (on manifest) and WorkingCopyWalker (io.File) talking to ? and/or dirstate -Revlog.Inspector to get nodeid array of meaningful data exact size (nor heading 00 bytes, nor 12 extra bytes from the spec) + +Revlog.Inspector to get nodeid array of meaningful data exact size (nor heading 00 bytes, nor 12 extra bytes from the spec) +Nodeid to keep 20 bytes always + Status operation from GUI - guess, usually on a file/subfolder, hence API should allow for starting path (unlike cmdline, seems useless to implement include/exclide patterns - GUI users hardly enter them, ever) diff -r 40532cdc92fc -r 11cfabe692b3 src/com/tmate/hgkit/console/Status.java --- a/src/com/tmate/hgkit/console/Status.java Tue Jan 04 01:01:39 2011 +0100 +++ b/src/com/tmate/hgkit/console/Status.java Tue Jan 04 02:08:25 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Artem Tikhomirov + * Copyright (c) 2010, 2011 Artem Tikhomirov */ package com.tmate.hgkit.console; @@ -25,10 +25,13 @@ } System.out.println(hgRepo.getLocation()); ((LocalHgRepo) hgRepo).loadDirstate().dump(); - //hgRepo.status(TIP, TIP, new StatusDump()); final StatusDump dump = new StatusDump(); dump.showIgnored = false; dump.showClean = false; + final int r1 = 0, r2 = 11; + System.out.printf("Status for changes between revision %d and %d:\n", r1, r2); + hgRepo.status(r1, r2, dump); + System.out.println("\nStatus against working dir:"); ((LocalHgRepo) hgRepo).statusLocal(TIP, dump); } diff -r 40532cdc92fc -r 11cfabe692b3 src/com/tmate/hgkit/ll/HgManifest.java --- a/src/com/tmate/hgkit/ll/HgManifest.java Tue Jan 04 01:01:39 2011 +0100 +++ b/src/com/tmate/hgkit/ll/HgManifest.java Tue Jan 04 02:08:25 2011 +0100 @@ -48,7 +48,6 @@ flags = new String(data, x + nodeidLen, i-x-nodeidLen); } gtg = gtg && inspector.next(nid, fname, flags); - } nid = null; fname = flags = null; diff -r 40532cdc92fc -r 11cfabe692b3 src/com/tmate/hgkit/ll/HgRepository.java --- a/src/com/tmate/hgkit/ll/HgRepository.java Tue Jan 04 01:01:39 2011 +0100 +++ b/src/com/tmate/hgkit/ll/HgRepository.java Tue Jan 04 02:08:25 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Artem Tikhomirov + * Copyright (c) 2010, 2011 Artem Tikhomirov */ package com.tmate.hgkit.ll; @@ -67,7 +67,7 @@ void copied(String fnameOrigin, String fnameAdded); // if copied files of no interest, should delegate to self.added(fnameAdded); void removed(String fname); void clean(String fname); - void missing(String fname); + void missing(String fname); // aka deleted (tracked by Hg, but not available in FS any more void unknown(String fname); // not tracked void ignored(String fname); } diff -r 40532cdc92fc -r 11cfabe692b3 src/com/tmate/hgkit/ll/LocalHgRepo.java --- a/src/com/tmate/hgkit/ll/LocalHgRepo.java Tue Jan 04 01:01:39 2011 +0100 +++ b/src/com/tmate/hgkit/ll/LocalHgRepo.java Tue Jan 04 02:08:25 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Artem Tikhomirov + * Copyright (c) 2010, 2011 Artem Tikhomirov */ package com.tmate.hgkit.ll; @@ -46,8 +46,60 @@ } @Override - public void status(int rev1, int rev2, StatusInspector inspector) { - throw HgRepository.notImplemented(); + public void status(int rev1, int rev2, final StatusInspector inspector) { + final HashMap idsMap = new HashMap(); + final HashMap flagsMap = new HashMap(); + HgManifest.Inspector collect = new HgManifest.Inspector() { + + + public boolean next(Nodeid nid, String fname, String flags) { + idsMap.put(fname, nid); + flagsMap.put(fname, flags); + return true; + } + + public boolean end(int revision) { + return false; + } + + public boolean begin(int revision, Nodeid nid) { + return true; + } + }; + getManifest().walk(rev1, rev1, collect); + + HgManifest.Inspector compare = new HgManifest.Inspector() { + + public boolean begin(int revision, Nodeid nid) { + return true; + } + + public boolean next(Nodeid nid, String fname, String flags) { + Nodeid nidR1 = idsMap.remove(fname); + String flagsR1 = flagsMap.remove(fname); + if (nidR1 == null) { + inspector.added(fname); + } else { + if (nidR1.compareTo(nid) == 0 && ((flags == null && flagsR1 == null) || flags.equals(flagsR1))) { + inspector.clean(fname); + } else { + inspector.modified(fname); + } + } + return true; + } + + public boolean end(int revision) { + for (String fname : idsMap.keySet()) { + inspector.removed(fname); + } + if (idsMap.size() != flagsMap.size()) { + throw new IllegalStateException(); + } + return false; + } + }; + getManifest().walk(rev2, rev2, compare); } public void statusLocal(int rev1, StatusInspector inspector) { diff -r 40532cdc92fc -r 11cfabe692b3 src/com/tmate/hgkit/ll/Nodeid.java --- a/src/com/tmate/hgkit/ll/Nodeid.java Tue Jan 04 01:01:39 2011 +0100 +++ b/src/com/tmate/hgkit/ll/Nodeid.java Tue Jan 04 02:08:25 2011 +0100 @@ -1,15 +1,20 @@ -/** - * Copyright (c) 2010 Artem Tikhomirov +/* + * Copyright (c) 2010, 2011 Artem Tikhomirov */ package com.tmate.hgkit.ll; +import java.util.Arrays; + /** - * @see mercurial/node.py + * Whether to store fixed size array (20 bytes) - ease of manipulation (e.g. hashcode/equals), or + * memory effective - reuse supplied array, keep significant bits only? + * Fixed size array looks most appealing to me now - I doubt one can save any significant amount of memory. + * There'd always 20 non-zero bytes, the difference is only for any extra bytes one may pass to constructor * @author artem * */ -public class Nodeid { +public final class Nodeid implements Comparable { public static int NULLREV = -1; private final byte[] binaryData; @@ -20,11 +25,30 @@ this.binaryData = binaryRepresentation; } + // instead of hashCode/equals + public int compareTo(Nodeid o) { + byte[] a1, a2; + if (this.binaryData.length != 20) { + a1 = new byte[20]; + System.arraycopy(binaryData, 0, a1, 20 - binaryData.length, binaryData.length); + } else { + a1 = this.binaryData; + } + + if (o.binaryData.length != 20) { + a2 = new byte[20]; + System.arraycopy(o.binaryData, 0, a2, 20 - o.binaryData.length, o.binaryData.length); + } else { + a2 = o.binaryData; + } + return Arrays.equals(a1, a2) ? 0 : -1; + } + @Override public String toString() { return new DigestHelper().toHexString(binaryData, 0, binaryData.length); } - + // binascii.unhexlify() public static Nodeid fromAscii(byte[] asciiRepresentation, int offset, int length) { assert length % 2 == 0; // Python's binascii.hexlify convert each byte into 2 digits @@ -36,6 +60,4 @@ } return new Nodeid(data); } - - }