annotate src/org/tmatesoft/hg/internal/RevlogStreamWriter.java @ 709:497e697636fc

Report merged lines as changed block if possible, not as a sequence of added/deleted blocks. To facilitate access to merge parent lines AddBlock got mergeLineAt() method that reports index of the line in the second parent (if any), while insertedAt() has been changed to report index in the first parent always
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 21 Aug 2013 16:23:27 +0200
parents 4ffc17c0b534
children
rev   line source
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
2 * Copyright (c) 2013 TMate Software Ltd
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
3 *
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
7 *
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
12 *
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
15 * contact TMate Software at support@hg4j.com
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
17 package org.tmatesoft.hg.internal;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
19 import static org.tmatesoft.hg.internal.Internals.REVLOGV1_RECORD_SIZE;
663
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
20 import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION;
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
21 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION;
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
22
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
23 import java.io.IOException;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
24 import java.nio.ByteBuffer;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
25
617
65c01508f002 Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 608
diff changeset
26 import org.tmatesoft.hg.core.HgIOException;
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
27 import org.tmatesoft.hg.core.Nodeid;
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
28 import org.tmatesoft.hg.core.SessionContext;
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
29 import org.tmatesoft.hg.internal.DataSerializer.ByteArrayDataSource;
645
14dac192aa26 Push: phase2 - upload bundle with changes to remote server
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
30 import org.tmatesoft.hg.internal.DataSerializer.ByteArraySerializer;
618
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
31 import org.tmatesoft.hg.internal.DataSerializer.DataSource;
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
32 import org.tmatesoft.hg.repo.HgBundle.GroupElement;
673
545b1d4cc11d Refactor HgBundle.GroupElement (clear experimental mark), resolve few technical debt issues
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 664
diff changeset
33 import org.tmatesoft.hg.repo.HgInternals;
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
34 import org.tmatesoft.hg.repo.HgInvalidControlFileException;
664
ae2d439fbed3 Utilize transaction when writing fncache. Better HgIOException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 663
diff changeset
35 import org.tmatesoft.hg.repo.HgInvalidDataFormatException;
628
6526d8adbc0f Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 618
diff changeset
36 import org.tmatesoft.hg.repo.HgInvalidRevisionException;
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
37 import org.tmatesoft.hg.repo.HgInvalidStateException;
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
38 import org.tmatesoft.hg.repo.HgRepository;
628
6526d8adbc0f Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 618
diff changeset
39 import org.tmatesoft.hg.repo.HgRuntimeException;
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
40 import org.tmatesoft.hg.util.Pair;
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
41
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
42 /**
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
43 *
608
e1b29756f901 Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 591
diff changeset
44 * TODO [post-1.1] separate operation to check if index is too big and split into index+data
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 530
diff changeset
45 *
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
46 * @author Artem Tikhomirov
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
47 * @author TMate Software Ltd.
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
48 */
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
49 public class RevlogStreamWriter {
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
50
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
51 private final DigestHelper dh = new DigestHelper();
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
52 private final RevlogCompressor revlogDataZip;
617
65c01508f002 Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 608
diff changeset
53 private final Transaction transaction;
663
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
54 // init with illegal values
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
55 private int lastEntryBase = BAD_REVISION, lastEntryIndex = BAD_REVISION, lastEntryActualLen = -1;
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
56 // record revision and its full content
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
57 // the name might be misleading, it does not necessarily match lastEntryIndex
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
58 private Pair<Integer, byte[]> lastFullContent;
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
59 private Nodeid lastEntryRevision;
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
60 private IntMap<Nodeid> revisionCache = new IntMap<Nodeid>(32);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
61 private RevlogStream revlogStream;
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
62
617
65c01508f002 Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 608
diff changeset
63 public RevlogStreamWriter(SessionContext.Source ctxSource, RevlogStream stream, Transaction tr) {
591
e447384f3771 CommitFacility as internal class; refactored infrastructure around internals (access to RevlogStream)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
64 assert ctxSource != null;
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
65 assert stream != null;
617
65c01508f002 Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 608
diff changeset
66 assert tr != null;
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
67
591
e447384f3771 CommitFacility as internal class; refactored infrastructure around internals (access to RevlogStream)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
68 revlogDataZip = new RevlogCompressor(ctxSource.getSessionContext());
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
69 revlogStream = stream;
617
65c01508f002 Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 608
diff changeset
70 transaction = tr;
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
71 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
72
663
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
73 public RevlogStream getRevlogStream() {
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
74 return revlogStream;
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
75 }
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
76
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
77 public Pair<Integer,Nodeid> addPatchRevision(GroupElement ge, RevisionToIndexMap clogRevs, RevisionToIndexMap revlogRevs) throws HgIOException, HgRuntimeException {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
78 populateLastEntryIndex();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
79 //
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
80 final Nodeid nodeRev = ge.node();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
81 final Nodeid csetRev = ge.cset();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
82 int linkRev;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
83 if (nodeRev.equals(csetRev)) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
84 linkRev = lastEntryIndex+1;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
85 } else {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
86 linkRev = clogRevs.revisionIndex(csetRev);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
87 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
88 assert linkRev >= 0;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
89 final Nodeid p1Rev = ge.firstParent();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
90 int p1 = p1Rev.isNull() ? NO_REVISION : revlogRevs.revisionIndex(p1Rev);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
91 final Nodeid p2Rev = ge.secondParent();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
92 int p2 = p2Rev.isNull() ? NO_REVISION : revlogRevs.revisionIndex(p2Rev);
673
545b1d4cc11d Refactor HgBundle.GroupElement (clear experimental mark), resolve few technical debt issues
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 664
diff changeset
93 Patch p = null;
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
94 try {
673
545b1d4cc11d Refactor HgBundle.GroupElement (clear experimental mark), resolve few technical debt issues
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 664
diff changeset
95 p = HgInternals.patchFromData(ge);
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
96 } catch (IOException ex) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
97 throw new HgIOException("Failed to read patch information", ex, null);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
98 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
99 //
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
100 final Nodeid patchBase = ge.patchBase();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
101 int patchBaseRev = patchBase.isNull() ? NO_REVISION : revlogRevs.revisionIndex(patchBase);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
102 int baseRev = lastEntryIndex == NO_REVISION ? 0 : revlogStream.baseRevision(patchBaseRev);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
103 int revLen;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
104 DataSource ds;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
105 byte[] complete = null;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
106 if (patchBaseRev == lastEntryIndex && lastEntryIndex != NO_REVISION) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
107 // we may write patch from GroupElement as is
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
108 int patchBaseLen = dataLength(patchBaseRev);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
109 revLen = patchBaseLen + p.patchSizeDelta();
673
545b1d4cc11d Refactor HgBundle.GroupElement (clear experimental mark), resolve few technical debt issues
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 664
diff changeset
110 ds = p.new PatchDataSource();
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
111 } else {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
112 // read baseRev, unless it's the pull to empty repository
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
113 try {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
114 if (lastEntryIndex == NO_REVISION) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
115 complete = p.apply(new ByteArrayDataAccess(new byte[0]), -1);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
116 baseRev = 0; // it's done above, but doesn't hurt
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
117 } else {
663
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
118 assert patchBaseRev != NO_REVISION;
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
119 ReadContentInspector insp = new ReadContentInspector().read(revlogStream, patchBaseRev);
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
120 complete = p.apply(new ByteArrayDataAccess(insp.content), -1);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
121 baseRev = lastEntryIndex + 1;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
122 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
123 ds = new ByteArrayDataSource(complete);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
124 revLen = complete.length;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
125 } catch (IOException ex) {
663
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
126 // unlikely to happen, as ByteArrayDataSource throws IOException only in case of programming errors
664
ae2d439fbed3 Utilize transaction when writing fncache. Better HgIOException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 663
diff changeset
127 // hence, throwing rt exception here makes more sense here than HgIOException (even that latter is in throws)
ae2d439fbed3 Utilize transaction when writing fncache. Better HgIOException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 663
diff changeset
128 throw new HgInvalidDataFormatException("Failed to reconstruct revision", ex);
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
129 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
130 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
131 doAdd(nodeRev, p1, p2, linkRev, baseRev, revLen, ds);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
132 if (complete != null) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
133 lastFullContent = new Pair<Integer, byte[]>(lastEntryIndex, complete);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
134 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
135 return new Pair<Integer, Nodeid>(lastEntryIndex, lastEntryRevision);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
136 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
137
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
138 /**
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
139 * @return nodeid of added revision
628
6526d8adbc0f Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 618
diff changeset
140 * @throws HgRuntimeException
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
141 */
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
142 public Pair<Integer,Nodeid> addRevision(DataSource content, int linkRevision, int p1, int p2) throws HgIOException, HgRuntimeException {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
143 populateLastEntryIndex();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
144 populateLastEntryContent();
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
145 //
618
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
146 byte[] contentByteArray = toByteArray(content);
708
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 673
diff changeset
147 Nodeid p1Rev = revision(p1);
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 673
diff changeset
148 Nodeid p2Rev = revision(p2);
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 673
diff changeset
149 Nodeid newRev = Nodeid.fromBinary(dh.sha1(p1Rev, p2Rev, contentByteArray).asBinary(), 0);
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 673
diff changeset
150 if (newRev.equals(p1Rev)) { // shall never happen, same content but different parents give new SHA. Doesn't hurt to check, though
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 673
diff changeset
151 assert p2Rev.isNull();
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 673
diff changeset
152 return new Pair<Integer, Nodeid>(p1, p1Rev);
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 673
diff changeset
153 }
4ffc17c0b534 Merge: tests for resolver and complex scenario. Enable commit for merged revisions. Reuse file revisions if nothing changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 673
diff changeset
154 //
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
155 Patch patch = GeneratePatchInspector.delta(lastFullContent.second(), contentByteArray);
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
156 int patchSerializedLength = patch.serializedLength();
618
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
157 final boolean writeComplete = preferCompleteOverPatch(patchSerializedLength, contentByteArray.length);
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
158 DataSerializer.DataSource dataSource = writeComplete ? new ByteArrayDataSource(contentByteArray) : patch.new PatchDataSource();
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
159 //
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
160 doAdd(newRev, p1, p2, linkRevision, writeComplete ? lastEntryIndex+1 : lastEntryBase, contentByteArray.length, dataSource);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
161 lastFullContent = new Pair<Integer, byte[]>(lastEntryIndex, contentByteArray);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
162 return new Pair<Integer, Nodeid>(lastEntryIndex, lastEntryRevision);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
163 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
164
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
165 private Nodeid doAdd(Nodeid rev, int p1, int p2, int linkRevision, int baseRevision, int revLen, DataSerializer.DataSource dataSource) throws HgIOException, HgRuntimeException {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
166 assert linkRevision >= 0;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
167 assert baseRevision >= 0;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
168 assert p1 == NO_REVISION || p1 >= 0;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
169 assert p2 == NO_REVISION || p2 >= 0;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
170 assert !rev.isNull();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
171 assert revLen >= 0;
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
172 revlogDataZip.reset(dataSource);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
173 final int compressedLen;
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
174 final boolean useCompressedData = preferCompressedOverComplete(revlogDataZip.getCompressedLength(), dataSource.serializeLength());
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
175 if (useCompressedData) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
176 compressedLen= revlogDataZip.getCompressedLength();
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
177 } else {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
178 // compression wasn't too effective,
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
179 compressedLen = dataSource.serializeLength() + 1 /*1 byte for 'u' - uncompressed prefix byte*/;
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
180 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
181 //
618
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
182 DataSerializer indexFile, dataFile;
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
183 indexFile = dataFile = null;
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
184 try {
673
545b1d4cc11d Refactor HgBundle.GroupElement (clear experimental mark), resolve few technical debt issues
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 664
diff changeset
185 // FIXME perhaps, not a good idea to open stream for each revision added (e.g, when we pull a lot of them)
618
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
186 indexFile = revlogStream.getIndexStreamWriter(transaction);
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
187 final boolean isInlineData = revlogStream.isInlineData();
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
188 HeaderWriter revlogHeader = new HeaderWriter(isInlineData);
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
189 revlogHeader.length(revLen, compressedLen);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
190 revlogHeader.nodeid(rev.toByteArray());
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
191 revlogHeader.linkRevision(linkRevision);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
192 revlogHeader.parents(p1, p2);
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
193 revlogHeader.baseRevision(baseRevision);
539
9edfd5a223b8 Commit: handle empty repository case
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 538
diff changeset
194 long lastEntryOffset = revlogStream.newEntryOffset();
9edfd5a223b8 Commit: handle empty repository case
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 538
diff changeset
195 revlogHeader.offset(lastEntryOffset);
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
196 //
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
197 revlogHeader.serialize(indexFile);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
198
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
199 if (isInlineData) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
200 dataFile = indexFile;
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
201 } else {
617
65c01508f002 Rollback support for commands that modify repository. Strategy to keep complete copy of a file being changed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 608
diff changeset
202 dataFile = revlogStream.getDataStreamWriter(transaction);
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
203 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
204 if (useCompressedData) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
205 int actualCompressedLenWritten = revlogDataZip.writeCompressedData(dataFile);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
206 if (actualCompressedLenWritten != compressedLen) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
207 throw new HgInvalidStateException(String.format("Expected %d bytes of compressed data, but actually wrote %d in %s", compressedLen, actualCompressedLenWritten, revlogStream.getDataFileName()));
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
208 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
209 } else {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
210 dataFile.writeByte((byte) 'u');
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
211 dataSource.serialize(dataFile);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
212 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
213
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
214 lastEntryBase = revlogHeader.baseRevision();
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
215 lastEntryIndex++;
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
216 lastEntryActualLen = revLen;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
217 lastEntryRevision = rev;
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
218 revisionCache.put(lastEntryIndex, lastEntryRevision);
539
9edfd5a223b8 Commit: handle empty repository case
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 538
diff changeset
219
9edfd5a223b8 Commit: handle empty repository case
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 538
diff changeset
220 revlogStream.revisionAdded(lastEntryIndex, lastEntryRevision, lastEntryBase, lastEntryOffset);
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
221 } finally {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
222 indexFile.done();
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
223 if (dataFile != null && dataFile != indexFile) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
224 dataFile.done();
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
225 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
226 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
227 return lastEntryRevision;
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
228 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
229
628
6526d8adbc0f Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 618
diff changeset
230 private byte[] toByteArray(DataSource content) throws HgIOException, HgRuntimeException {
645
14dac192aa26 Push: phase2 - upload bundle with changes to remote server
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
231 ByteArraySerializer ba = new ByteArraySerializer();
618
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
232 content.serialize(ba);
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
233 return ba.toByteArray();
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
234 }
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
235
628
6526d8adbc0f Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 618
diff changeset
236 private Nodeid revision(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException {
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
237 if (revisionIndex == NO_REVISION) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
238 return Nodeid.NULL;
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
239 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
240 Nodeid n = revisionCache.get(revisionIndex);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
241 if (n == null) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
242 n = Nodeid.fromBinary(revlogStream.nodeid(revisionIndex), 0);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
243 revisionCache.put(revisionIndex, n);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
244 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
245 return n;
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
246 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
247
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
248 private int dataLength(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
249 assert revisionIndex >= 0;
663
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
250 if (revisionIndex == lastEntryIndex && lastEntryActualLen >= 0) {
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
251 // if the last entry is the one we've just written, we know its actual len.
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
252 // it's possible, however, that revisionIndex == lastEntryIndex just
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
253 // because revision being added comes right after last locally known one
46b56864b483 Pull: phase2 - update phases from remote, fncache with added files. Tests
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 660
diff changeset
254 // and lastEntryActualLen is not set
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
255 return lastEntryActualLen;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
256 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
257 if (lastFullContent != null && lastFullContent.first() == revisionIndex) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
258 return lastFullContent.second().length;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
259 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
260 return revlogStream.dataLength(revisionIndex);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
261 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
262
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
263 private void populateLastEntryIndex() throws HgRuntimeException {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
264 int revCount = revlogStream.revisionCount();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
265 lastEntryIndex = revCount == 0 ? NO_REVISION : revCount - 1;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
266 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
267
664
ae2d439fbed3 Utilize transaction when writing fncache. Better HgIOException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 663
diff changeset
268 private void populateLastEntryContent() throws HgIOException, HgRuntimeException {
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
269 if (lastFullContent != null && lastFullContent.first() == lastEntryIndex) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
270 // we have last entry cached
539
9edfd5a223b8 Commit: handle empty repository case
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 538
diff changeset
271 return;
9edfd5a223b8 Commit: handle empty repository case
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 538
diff changeset
272 }
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
273 lastEntryRevision = Nodeid.NULL;
539
9edfd5a223b8 Commit: handle empty repository case
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 538
diff changeset
274 if (lastEntryIndex != NO_REVISION) {
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
275 ReadContentInspector insp = new ReadContentInspector().read(revlogStream, lastEntryIndex);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
276 lastEntryBase = insp.baseRev;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
277 lastEntryRevision = insp.rev;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
278 lastFullContent = new Pair<Integer, byte[]>(lastEntryIndex, insp.content);
539
9edfd5a223b8 Commit: handle empty repository case
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 538
diff changeset
279 } else {
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
280 lastFullContent = new Pair<Integer, byte[]>(lastEntryIndex, new byte[0]);
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
281 }
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
282 assert lastFullContent.first() == lastEntryIndex;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
283 assert lastFullContent.second() != null;
538
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
284 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
285
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
286 public static boolean preferCompleteOverPatch(int patchLength, int fullContentLength) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
287 return !decideWorthEffort(patchLength, fullContentLength);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
288 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
289
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
290 public static boolean preferCompressedOverComplete(int compressedLen, int fullContentLength) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
291 if (compressedLen <= 0) { // just in case, meaningless otherwise
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
292 return false;
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
293 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
294 return decideWorthEffort(compressedLen, fullContentLength);
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
295 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
296
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
297 // true if length obtained with effort is worth it
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
298 private static boolean decideWorthEffort(int lengthWithExtraEffort, int lengthWithoutEffort) {
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
299 return lengthWithExtraEffort < (/* 3/4 of original */lengthWithoutEffort - (lengthWithoutEffort >>> 2));
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
300 }
dd4f6311af52 Commit: first working version
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 534
diff changeset
301
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
302 /*XXX public because HgCloneCommand uses it*/
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
303 public static class HeaderWriter implements DataSerializer.DataSource {
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
304 private final ByteBuffer header;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
305 private final boolean isInline;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
306 private long offset;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
307 private int length, compressedLength;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
308 private int baseRev, linkRev, p1, p2;
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
309 private byte[] nodeid;
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
310
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
311 public HeaderWriter(boolean inline) {
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
312 isInline = inline;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
313 header = ByteBuffer.allocate(REVLOGV1_RECORD_SIZE);
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
314 }
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
315
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
316 public HeaderWriter offset(long offset) {
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
317 this.offset = offset;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
318 return this;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
319 }
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
320
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 530
diff changeset
321 public int baseRevision() {
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 530
diff changeset
322 return baseRev;
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 530
diff changeset
323 }
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 530
diff changeset
324
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
325 public HeaderWriter baseRevision(int baseRevision) {
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
326 this.baseRev = baseRevision;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
327 return this;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
328 }
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
329
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
330 public HeaderWriter length(int len, int compressedLen) {
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
331 this.length = len;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
332 this.compressedLength = compressedLen;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
333 return this;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
334 }
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
335
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
336 public HeaderWriter parents(int parent1, int parent2) {
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
337 p1 = parent1;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
338 p2 = parent2;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
339 return this;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
340 }
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
341
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
342 public HeaderWriter linkRevision(int linkRevision) {
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
343 linkRev = linkRevision;
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
344 return this;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
345 }
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
346
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
347 public HeaderWriter nodeid(Nodeid n) {
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
348 nodeid = n.toByteArray();
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
349 return this;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
350 }
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
351
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
352 public HeaderWriter nodeid(byte[] nodeidBytes) {
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
353 nodeid = nodeidBytes;
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
354 return this;
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
355 }
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
356
618
7c0d2ce340b8 Refactor approach how content finds it way down to a commit revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
357 public void serialize(DataSerializer out) throws HgIOException {
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
358 header.clear();
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
359 if (offset == 0) {
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
360 int version = 1 /* RevlogNG */;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
361 if (isInline) {
608
e1b29756f901 Clean, organize and resolve some TODOs and FIXMEs: minor refactorings and comments
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 591
diff changeset
362 version |= RevlogStream.INLINEDATA;
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
363 }
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
364 header.putInt(version);
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
365 header.putInt(0);
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
366 } else {
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
367 header.putLong(offset << 16);
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
368 }
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
369 header.putInt(compressedLength);
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
370 header.putInt(length);
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
371 header.putInt(baseRev);
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
372 header.putInt(linkRev);
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
373 header.putInt(p1);
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
374 header.putInt(p2);
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
375 header.put(nodeid);
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
376 // assume 12 bytes left are zeros
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
377 out.write(header.array(), 0, header.capacity());
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
378
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
379 // regardless whether it's inline or separate data,
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
380 // offset field always represent cumulative compressedLength
539
9edfd5a223b8 Commit: handle empty repository case
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 538
diff changeset
381 // (while physical offset in the index file with inline==true differs by n*sizeof(header), where n is entry's position in the file)
530
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
382 offset += compressedLength;
0f6fa88e2162 Towards commit command: refactor clone, extract pieces to reuse. Describe a defect discovered when bundle has few patches with 0,0 parents
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
383 }
534
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
384
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
385 public int serializeLength() {
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
386 return header.capacity();
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
387 }
243202f1bda5 Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 533
diff changeset
388 }
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
389
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
390 // XXX part of HgRevisionMap contract, need public counterparts (along with IndexToRevisionMap)
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
391 public interface RevisionToIndexMap {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
392
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
393 /**
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
394 * @return {@link HgRepository#NO_REVISION} if unknown revision
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
395 */
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
396 int revisionIndex(Nodeid revision);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
397 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
398
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
399 private static class ReadContentInspector implements RevlogStream.Inspector {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
400 public int baseRev;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
401 public Nodeid rev;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
402 public byte[] content;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
403 private IOException failure;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
404
664
ae2d439fbed3 Utilize transaction when writing fncache. Better HgIOException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 663
diff changeset
405 public ReadContentInspector read(RevlogStream rs, int revIndex) throws HgIOException, HgRuntimeException {
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
406 assert revIndex >= 0;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
407 rs.iterate(revIndex, revIndex, true, this);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
408 if (failure != null) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
409 String m = String.format("Failed to get content of revision %d", revIndex);
664
ae2d439fbed3 Utilize transaction when writing fncache. Better HgIOException
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 663
diff changeset
410 throw rs.initWithIndexFile(new HgIOException(m, failure, null));
660
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
411 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
412 return this;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
413 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
414
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
415 public void next(int revisionIndex, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
416 try {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
417 baseRev = baseRevision;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
418 rev = Nodeid.fromBinary(nodeid, 0);
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
419 content = data.byteArray();
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
420 } catch (IOException ex) {
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
421 failure = ex;
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
422 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
423 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
424 }
4fd317a2fecf Pull: phase1 get remote changes and add local revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 645
diff changeset
425 }