Mercurial > hg4j
comparison src/org/tmatesoft/hg/repo/HgBundle.java @ 532:688c1ab113bb
Introduce explicit reference to base patch in bundle's group element, use it when cloning to fix defect when few revisions list null,null parents
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 23 Jan 2013 19:14:15 +0100 |
parents | 2f9ed6bcefa2 |
children | 243202f1bda5 |
comparison
equal
deleted
inserted
replaced
531:95c2f43008bd | 532:688c1ab113bb |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2011-2012 TMate Software Ltd | 2 * Copyright (c) 2011-2013 TMate Software Ltd |
3 * | 3 * |
4 * This program is free software; you can redistribute it and/or modify | 4 * This program is free software; you can redistribute it and/or modify |
5 * it under the terms of the GNU General Public License as published by | 5 * it under the terms of the GNU General Public License as published by |
6 * the Free Software Foundation; version 2 of the License. | 6 * the Free Software Foundation; version 2 of the License. |
7 * | 7 * |
407 } | 407 } |
408 | 408 |
409 private static void readGroup(DataAccess da, Inspector inspector) throws IOException { | 409 private static void readGroup(DataAccess da, Inspector inspector) throws IOException { |
410 int len = da.readInt(); | 410 int len = da.readInt(); |
411 boolean good2go = true; | 411 boolean good2go = true; |
412 Nodeid prevNodeid = Nodeid.NULL; | |
412 while (len > 4 && !da.isEmpty() && good2go) { | 413 while (len > 4 && !da.isEmpty() && good2go) { |
413 byte[] nb = new byte[80]; | 414 byte[] nb = new byte[80]; |
414 da.readBytes(nb, 0, 80); | 415 da.readBytes(nb, 0, 80); |
415 int dataLength = len - 84 /* length field + 4 nodeids */; | 416 int dataLength = len - 84 /* length field + 4 nodeids */; |
416 byte[] data = new byte[dataLength]; | 417 byte[] data = new byte[dataLength]; |
417 da.readBytes(data, 0, dataLength); | 418 da.readBytes(data, 0, dataLength); |
418 DataAccess slice = new ByteArrayDataAccess(data); // XXX in fact, may pass a slicing DataAccess. | 419 DataAccess slice = new ByteArrayDataAccess(data); // XXX in fact, may pass a slicing DataAccess. |
419 // Just need to make sure that we seek to proper location afterwards (where next GroupElement starts), | 420 // Just need to make sure that we seek to proper location afterwards (where next GroupElement starts), |
420 // regardless whether that slice has read it or not. | 421 // regardless whether that slice has read it or not. |
421 GroupElement ge = new GroupElement(nb, slice); | 422 GroupElement ge = new GroupElement(nb, prevNodeid, slice); |
422 good2go = inspector.element(ge); | 423 good2go = inspector.element(ge); |
423 slice.done(); // BADA doesn't implement done(), but it could (e.g. free array) | 424 slice.done(); // BADA doesn't implement done(), but it could (e.g. free array) |
424 /// and we'd better tell it we are not going to use it any more. However, it's important to ensure Inspector | 425 /// and we'd better tell it we are not going to use it any more. However, it's important to ensure Inspector |
425 // implementations out there do not retain GroupElement.rawData() | 426 // implementations out there do not retain GroupElement.rawData() |
427 prevNodeid = ge.node(); | |
426 len = da.isEmpty() ? 0 : da.readInt(); | 428 len = da.isEmpty() ? 0 : da.readInt(); |
427 } | 429 } |
428 // need to skip up to group end if inspector told he don't want to continue with the group, | 430 // need to skip up to group end if inspector told he don't want to continue with the group, |
429 // because outer code may try to read next group immediately as we return back. | 431 // because outer code may try to read next group immediately as we return back. |
430 while (len > 4 && !da.isEmpty()) { | 432 while (len > 4 && !da.isEmpty()) { |
444 @Experimental(reason="Cumbersome API, rawData and apply with byte[] perhaps need replacement with ByteChannel/ByteBuffer, and better Exceptions. Perhaps, shall split into interface and impl") | 446 @Experimental(reason="Cumbersome API, rawData and apply with byte[] perhaps need replacement with ByteChannel/ByteBuffer, and better Exceptions. Perhaps, shall split into interface and impl") |
445 public static class GroupElement { | 447 public static class GroupElement { |
446 private final byte[] header; // byte[80] takes 120 bytes, 4 Nodeids - 192 | 448 private final byte[] header; // byte[80] takes 120 bytes, 4 Nodeids - 192 |
447 private final DataAccess dataAccess; | 449 private final DataAccess dataAccess; |
448 private Patch patches; | 450 private Patch patches; |
449 | 451 private final Nodeid deltaBase; |
450 GroupElement(byte[] fourNodeids, DataAccess rawDataAccess) { | 452 |
453 GroupElement(byte[] fourNodeids, Nodeid deltaBaseRev, DataAccess rawDataAccess) { | |
451 assert fourNodeids != null && fourNodeids.length == 80; | 454 assert fourNodeids != null && fourNodeids.length == 80; |
452 header = fourNodeids; | 455 header = fourNodeids; |
456 deltaBase = deltaBaseRev; | |
453 dataAccess = rawDataAccess; | 457 dataAccess = rawDataAccess; |
454 } | 458 } |
455 | 459 |
456 /** | 460 /** |
457 * <b>node</b> field of the group element | 461 * <b>node</b> field of the group element |
481 * <b>cs</b> <i>(changeset link)</i> field of the group element | 485 * <b>cs</b> <i>(changeset link)</i> field of the group element |
482 * @return changeset revision, never <code>null</code> | 486 * @return changeset revision, never <code>null</code> |
483 */ | 487 */ |
484 public Nodeid cset() { | 488 public Nodeid cset() { |
485 return Nodeid.fromBinary(header, 60); | 489 return Nodeid.fromBinary(header, 60); |
490 } | |
491 | |
492 /** | |
493 * Revision this element keeps patches against. For the patches of the very first revision returns {@link Nodeid#NULL}. | |
494 * @return revision of delta base, never <code>null</code> | |
495 */ | |
496 public Nodeid patchBase() { | |
497 return deltaBase; | |
486 } | 498 } |
487 | 499 |
488 public byte[] rawDataByteArray() throws IOException { // XXX IOException or HgInvalidFileException? | 500 public byte[] rawDataByteArray() throws IOException { // XXX IOException or HgInvalidFileException? |
489 return rawData().byteArray(); | 501 return rawData().byteArray(); |
490 } | 502 } |