annotate src/org/tmatesoft/hg/internal/DirstateBuilder.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 42b88709e41d
children
rev   line source
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
2 * Copyright (c) 2012-2013 TMate Software Ltd
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
3 *
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
7 *
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
12 *
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
15 * contact TMate Software at support@hg4j.com
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
17 package org.tmatesoft.hg.internal;
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
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: 580
diff changeset
19 import static org.tmatesoft.hg.repo.HgRepositoryFiles.Dirstate;
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: 580
diff changeset
20 import static org.tmatesoft.hg.repo.HgRepositoryFiles.UndoDirstate;
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: 580
diff changeset
21
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
22 import java.io.File;
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
23 import java.io.FileOutputStream;
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
24 import java.io.IOException;
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
25 import java.nio.ByteBuffer;
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
26 import java.nio.channels.FileChannel;
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
27 import java.nio.channels.WritableByteChannel;
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
28 import java.util.Map;
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
29 import java.util.TreeMap;
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
30
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
31 import org.tmatesoft.hg.core.HgIOException;
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
32 import org.tmatesoft.hg.core.Nodeid;
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
33 import org.tmatesoft.hg.repo.HgDirstate;
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
34 import org.tmatesoft.hg.repo.HgDirstate.EntryKind;
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
35 import org.tmatesoft.hg.repo.HgDirstate.Record;
628
6526d8adbc0f Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
36 import org.tmatesoft.hg.repo.HgInvalidControlFileException;
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
37 import org.tmatesoft.hg.repo.HgInvalidStateException;
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
38 import org.tmatesoft.hg.repo.HgManifest.Flags;
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
39 import org.tmatesoft.hg.util.Path;
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
40
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
41 /**
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
42 * Facility to build a dirstate file as described in {@linkplain http://mercurial.selenic.com/wiki/DirState}
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
43 *
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
44 * @see http://mercurial.selenic.com/wiki/DirState
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
45 * @see HgDirstate
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
46 * @author Artem Tikhomirov
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
47 * @author TMate Software Ltd.
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
48 */
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
49 public class DirstateBuilder {
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
50 private Map<Path, HgDirstate.Record> normal = new TreeMap<Path, HgDirstate.Record>();
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
51 private Map<Path, HgDirstate.Record> added = new TreeMap<Path, HgDirstate.Record>();
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
52 private Map<Path, HgDirstate.Record> removed = new TreeMap<Path, HgDirstate.Record>();
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
53 private Map<Path, HgDirstate.Record> merged = new TreeMap<Path, HgDirstate.Record>();
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
54 private Nodeid parent1, parent2;
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
55 private final Internals hgRepo;
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
56 private final EncodingHelper encodingHelper;
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
57
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
58 public DirstateBuilder(Internals internalRepo) {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
59 hgRepo = internalRepo;
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
60 encodingHelper = internalRepo.buildFileNameEncodingHelper();
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
61 }
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
62
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
63 public void parents(Nodeid p1, Nodeid p2) {
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
64 parent1 = p1 == null ? Nodeid.NULL : p1;
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
65 parent2 = p2 == null ? Nodeid.NULL : p2;
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
66 }
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
67
580
bd5926e24aa3 Respect unix flags for checkout/revert
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 529
diff changeset
68 public void recordNormal(Path fname, int fmode, int mtime, int bytesWritten) {
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
69 forget(fname);
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
70 normal.put(fname, new HgDirstate.Record(fmode, bytesWritten, mtime, fname, null));
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
71 }
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
72
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
73 public void recordUncertain(Path fname) {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
74 // `hg revert` puts "n 0 -1 unset" for the reverted file, so shall we
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
75 forget(fname);
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
76 normal.put(fname, new HgDirstate.Record(0, -1, -1, fname, null));
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
77 }
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
78
529
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
79 public void recordAdded(Path fname, Flags flags, int size) {
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
80 forget(fname);
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
81 added.put(fname, new HgDirstate.Record(0, -1, -1, fname, null));
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
82 }
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
83
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
84 public void recordRemoved(Path fname) {
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
85 HgDirstate.Record r = forget(fname);
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
86 HgDirstate.Record n;
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
87 if (r == null) {
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
88 n = new HgDirstate.Record(0, -1, -1, fname, null);
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
89 } else {
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
90 n = new HgDirstate.Record(r.mode(), r.size(), r.modificationTime(), fname, r.copySource());
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
91 }
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
92 removed.put(fname, n);
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
93 }
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
94
705
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
95 public void recordMerged(Path fname, int fmode, int mtime, int bytesWritten) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
96 forget(fname);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
97 merged.put(fname, new HgDirstate.Record(fmode, bytesWritten,mtime, fname, null));
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
98 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
99
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
100 /**
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
101 * From DirState wiki:
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
102 * <p>"size is ... when the dirstate is in a merge state: -2 will *always* return dirty, it is used to mark a file that was cleanly picked from p2"
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
103 * and
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
104 * <p>"Additional meta status...'np2': merged from other parent (status == 'n', size == -2)"
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
105 */
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
106 public void recordMergedFromP2(Path fname) {
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
107 forget(fname);
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
108 normal.put(fname, new HgDirstate.Record(0, -2, -1, fname, null));
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
109 }
b4242b7e7dfe Merge command: implement conflict resolution alternatives
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 628
diff changeset
110
707
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
111 /**
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
112 * Mark file from this dirstate as merged, using all the information
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
113 */
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
114 public void recordMergedExisting(Path fname, Path knownInDirstate) {
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
115 HgDirstate.Record r = forget(knownInDirstate);
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
116 HgDirstate.Record n;
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
117 if (r == null) {
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
118 assert false;
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
119 n = new HgDirstate.Record(0, -1, -1, fname, null);
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
120 } else {
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
121 n = new HgDirstate.Record(r.mode(), r.size(), r.modificationTime(), fname, r.copySource());
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
122 }
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
123 merged.put(fname, n);
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
124 }
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
125
42b88709e41d Merge: support 'unresolved' resolution with MergeStateBuilder
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 705
diff changeset
126
529
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
127 private HgDirstate.Record forget(Path fname) {
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
128 HgDirstate.Record r;
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
129 if ((r = normal.remove(fname)) != null) {
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
130 return r;
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
131 }
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
132 if ((r = added.remove(fname)) != null) {
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
133 return r;
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
134 }
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
135 if ((r = removed.remove(fname)) != null) {
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
136 return r;
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
137 }
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
138 return merged.remove(fname);
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
139 }
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
140
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
141 public void serialize(WritableByteChannel dest) throws IOException {
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
142 assert parent1 != null : "Parent(s) of the working directory shall be set first";
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
143 ByteBuffer bb = ByteBuffer.allocate(256);
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
144 bb.put(parent1.toByteArray());
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
145 bb.put(parent2.toByteArray());
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
146 bb.flip();
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
147 // header
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
148 int written = dest.write(bb);
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
149 if (written != bb.limit()) {
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
150 throw new IOException("Incomplete write");
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
151 }
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
152 bb.clear();
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
153 // entries
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
154 @SuppressWarnings("unchecked")
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
155 Map<Path, HgDirstate.Record>[] all = new Map[] {normal, added, removed, merged};
529
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
156 ByteBuffer recordTypes = ByteBuffer.allocate(4);
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
157 recordTypes.put((byte) 'n').put((byte) 'a').put((byte) 'r').put((byte) 'm').flip();
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
158 for (Map<Path, HgDirstate.Record> m : all) {
529
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
159 final byte recordType = recordTypes.get();
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
160 for (HgDirstate.Record r : m.values()) {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
161 // regular entry is 1+4+4+4+4+fname.length bytes
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
162 // it might get extended with copy origin, prepended with 0 byte
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
163 byte[] fname = encodingHelper.toDirstate(r.name());
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
164 byte[] copyOrigin = r.copySource() == null ? null : encodingHelper.toDirstate(r.copySource());
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
165 int length = fname.length + (copyOrigin == null ? 0 : (1 + copyOrigin.length));
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
166 bb = ensureCapacity(bb, 17 + length);
529
95bdcf75e71e Command to schedule addition/removal of repository files
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 526
diff changeset
167 bb.put(recordType);
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
168 bb.putInt(r.mode());
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
169 bb.putInt(r.size());
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
170 bb.putInt(r.modificationTime());
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
171 bb.putInt(length);
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
172 bb.put(fname);
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
173 if (copyOrigin != null) {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
174 bb.put((byte) 0);
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
175 bb.put(copyOrigin);
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
176 }
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
177 bb.flip();
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
178 written = dest.write(bb);
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
179 if (written != bb.limit()) {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
180 throw new IOException("Incomplete write");
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
181 }
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
182 bb.clear();
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
183 }
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
184 }
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
185 }
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
186
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: 580
diff changeset
187 public void serialize(Transaction tr) throws HgIOException {
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: 580
diff changeset
188 File dirstateFile = tr.prepare(hgRepo.getRepositoryFile(Dirstate), hgRepo.getRepositoryFile(UndoDirstate));
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
189 try {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
190 FileChannel dirstate = new FileOutputStream(dirstateFile).getChannel();
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
191 serialize(dirstate);
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
192 dirstate.close();
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: 580
diff changeset
193 tr.done(dirstateFile);
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
194 } catch (IOException ex) {
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: 580
diff changeset
195 tr.failure(dirstateFile, ex);
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
196 throw new HgIOException("Can't write down new directory state", ex, dirstateFile);
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
197 }
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
198 }
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
199
628
6526d8adbc0f Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 617
diff changeset
200 public void fillFrom(DirstateReader dirstate) throws HgInvalidControlFileException {
526
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
201 // TODO preserve order, if reasonable and possible
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
202 dirstate.readInto(new HgDirstate.Inspector() {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
203
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
204 public boolean next(EntryKind kind, Record entry) {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
205 switch (kind) {
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
206 case Normal: normal.put(entry.name(), entry); break;
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
207 case Added : added.put(entry.name(), entry); break;
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
208 case Removed : removed.put(entry.name(), entry); break;
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
209 case Merged : merged.put(entry.name(), entry); break;
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
210 default: throw new HgInvalidStateException(String.format("Unexpected entry in the dirstate: %s", kind));
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
211 }
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
212 return true;
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
213 }
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
214 });
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
215 parents(dirstate.parents().first(), dirstate.parents().second());
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
216 }
2f9ed6bcefa2 Initial support for Revert command with accompanying minor refactoring
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 525
diff changeset
217
525
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
218
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
219 private static ByteBuffer ensureCapacity(ByteBuffer buf, int cap) {
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
220 if (buf.capacity() >= cap) {
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
221 return buf;
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
222 }
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
223 return ByteBuffer.allocate(cap);
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
224 }
0be5be8d57e9 Repository checkout support, first iteration
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
225 }