comparison src/org/tmatesoft/hg/repo/HgMergeState.java @ 231:1792b37650f2

Introduced access to conflict resolution information (merge state)
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 01 Jun 2011 05:44:25 +0200
parents
children 3fbfce107f94
comparison
equal deleted inserted replaced
230:0dd9da7489dc 231:1792b37650f2
1 /*
2 * Copyright (c) 2011 TMate Software Ltd
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * For information on how to redistribute this software under
14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com
16 */
17 package org.tmatesoft.hg.repo;
18
19 import java.io.BufferedReader;
20 import java.io.File;
21 import java.io.FileReader;
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.List;
27
28 import org.tmatesoft.hg.core.HgBadStateException;
29 import org.tmatesoft.hg.core.HgFileRevision;
30 import org.tmatesoft.hg.core.HgLogCommand.FileRevision;
31 import org.tmatesoft.hg.core.Nodeid;
32 import org.tmatesoft.hg.internal.Pool;
33 import org.tmatesoft.hg.repo.HgStatusCollector.ManifestRevisionInspector;
34 import org.tmatesoft.hg.util.Path;
35 import org.tmatesoft.hg.util.PathPool;
36 import org.tmatesoft.hg.util.PathRewrite;
37
38 /**
39 *
40 * @author Artem Tikhomirov
41 * @author TMate Software Ltd.
42 */
43 public class HgMergeState {
44 private Nodeid wcp1, wcp2;
45
46 public enum Kind {
47 Resolved, Unresolved;
48 }
49
50 public static class Entry {
51 private final Kind state;
52 private final HgFileRevision parent1;
53 private final HgFileRevision parent2;
54 private final HgFileRevision ancestor;
55 private final Path wcFile;
56
57 /*package-local*/Entry(Kind s, Path actualCopy, HgFileRevision p1, HgFileRevision p2, HgFileRevision ca) {
58 if (p1 == null || p2 == null || ca == null || actualCopy == null) {
59 throw new IllegalArgumentException();
60 }
61 state = s;
62 wcFile = actualCopy;
63 parent1 = p1;
64 parent2 = p2;
65 ancestor = ca;
66 }
67
68 public Kind getState() {
69 return state;
70 }
71 public Path getActualFile() {
72 return wcFile;
73 }
74 public HgFileRevision getFirstParent() {
75 return parent1;
76 }
77 public HgFileRevision getSecondParent() {
78 return parent2;
79 }
80 public HgFileRevision getCommonAncestor() {
81 return ancestor;
82 }
83 }
84
85 private final HgRepository repo;
86 private Entry[] entries;
87
88 HgMergeState(HgRepository hgRepo) {
89 repo = hgRepo;
90 }
91
92 public void refresh() throws IOException/*XXX it's unlikely caller can do anything reasonable about IOException */ {
93 entries = null;
94 final File f = new File(repo.getRepositoryRoot(), "merge/state");
95 if (!f.canRead()) {
96 // empty state
97 return;
98 }
99 Nodeid[] wcParents = repo.loadDirstate().parents();
100 wcp1 = wcParents[0]; wcp2 = wcParents[1];
101 ArrayList<Entry> result = new ArrayList<Entry>();
102 PathPool pathPool = new PathPool(new PathRewrite.Empty());
103 Pool<Nodeid> nodeidPool = new Pool<Nodeid>();
104 Pool<String> fnamePool = new Pool<String>();
105 final ManifestRevisionInspector m1 = new ManifestRevisionInspector(nodeidPool, fnamePool);
106 final ManifestRevisionInspector m2 = new ManifestRevisionInspector(nodeidPool, fnamePool);
107 final int rp1 = repo.getChangelog().getLocalRevision(wcp1);
108 final int rp2 = repo.getChangelog().getLocalRevision(wcp2);
109 repo.getManifest().walk(rp1, rp1, m1);
110 repo.getManifest().walk(rp2, rp2, m2);
111 BufferedReader br = new BufferedReader(new FileReader(f));
112 String s = br.readLine();
113 Nodeid n = Nodeid.fromAscii(s);
114 if (!wcp1.equals(n)) {
115 throw new AssertionError("I assume merge/state records revision of the wc we merge into");
116 }
117 while ((s = br.readLine()) != null) {
118 String[] r = s.split("\\00");
119 HgFileRevision p1 = new HgFileRevision(repo, m1.nodeid(r[3]), pathPool.path(r[3]));
120 HgFileRevision ca = new HgFileRevision(repo, Nodeid.fromAscii(r[5]), pathPool.path(r[4]));
121 HgFileRevision p2 = new HgFileRevision(repo, m2.nodeid(r[6]), pathPool.path(r[6]));
122 final Kind k;
123 if ("u".equals(r[1])) {
124 k = Kind.Unresolved;
125 } else if ("r".equals(r[1])) {
126 k = Kind.Resolved;
127 } else {
128 throw new HgBadStateException(r[1]);
129 }
130 Entry e = new Entry(k, pathPool.path(r[0]), p1, p2, ca);
131 result.add(e);
132 }
133 entries = result.toArray(new Entry[result.size()]);
134 br.close();
135 pathPool.clear();
136 }
137
138 public Nodeid getFirstParent() {
139 if (wcp1 == null) {
140 throw new HgBadStateException("Call #refresh() first");
141 }
142 return wcp1;
143 }
144
145 public Nodeid getSecondParent() {
146 if (wcp2 == null) {
147 throw new HgBadStateException("Call #refresh() first");
148 }
149 return wcp2;
150 }
151
152 public List<Entry> getConflicts() {
153 return entries == null ? Collections.<Entry>emptyList() : Arrays.asList(entries);
154 }
155 }