Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgMergeState.java @ 341:75c452fdd76a
Merging state not detected when there's no conflicts to resolve (no merge/state file)
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 17 Nov 2011 07:04:58 +0100 |
parents | f74e36b7344b |
children | a0864b2892cd |
comparison
equal
deleted
inserted
replaced
340:a54bfe0db959 | 341:75c452fdd76a |
---|---|
91 repo = hgRepo; | 91 repo = hgRepo; |
92 } | 92 } |
93 | 93 |
94 public void refresh() throws IOException/*XXX it's unlikely caller can do anything reasonable about IOException */ { | 94 public void refresh() throws IOException/*XXX it's unlikely caller can do anything reasonable about IOException */ { |
95 entries = null; | 95 entries = null; |
96 wcp1 = wcp2 = stateParent = Nodeid.NULL; | 96 // it's possible there are two parents but no merge/state, we shall report this case as 'merging', with proper |
97 // first and second parent values | |
98 stateParent = Nodeid.NULL; | |
99 Pool<Nodeid> nodeidPool = new Pool<Nodeid>(); | |
100 Pool<Path> fnamePool = new Pool<Path>(); | |
101 Pair<Nodeid, Nodeid> wcParents = repo.getWorkingCopyParents(); | |
102 wcp1 = nodeidPool.unify(wcParents.first()); wcp2 = nodeidPool.unify(wcParents.second()); | |
97 final File f = new File(repo.getRepositoryRoot(), "merge/state"); | 103 final File f = new File(repo.getRepositoryRoot(), "merge/state"); |
98 if (!f.canRead()) { | 104 if (!f.canRead()) { |
99 // empty state | 105 // empty state |
100 return; | 106 return; |
101 } | 107 } |
102 Pool<Nodeid> nodeidPool = new Pool<Nodeid>(); | |
103 Pool<Path> fnamePool = new Pool<Path>(); | |
104 Pair<Nodeid, Nodeid> wcParents = repo.getWorkingCopyParents(); | |
105 wcp1 = nodeidPool.unify(wcParents.first()); wcp2 = nodeidPool.unify(wcParents.second()); | |
106 ArrayList<Entry> result = new ArrayList<Entry>(); | 108 ArrayList<Entry> result = new ArrayList<Entry>(); |
107 // FIXME need to settle use of Pool<Path> and PathPool | 109 // FIXME need to settle use of Pool<Path> and PathPool |
108 // latter is pool that can create objects on demand, former is just cache | 110 // latter is pool that can create objects on demand, former is just cache |
109 PathPool pathPool = new PathPool(new PathRewrite.Empty()); | 111 PathPool pathPool = new PathPool(new PathRewrite.Empty()); |
110 final ManifestRevision m1 = new ManifestRevision(nodeidPool, fnamePool); | 112 final ManifestRevision m1 = new ManifestRevision(nodeidPool, fnamePool); |
157 entries = result.toArray(new Entry[result.size()]); | 159 entries = result.toArray(new Entry[result.size()]); |
158 br.close(); | 160 br.close(); |
159 pathPool.clear(); | 161 pathPool.clear(); |
160 } | 162 } |
161 | 163 |
162 | 164 /** |
165 * Repository is in 'merging' state when changeset to be committed got two parents. | |
166 * This method doesn't tell whether there are (un)resolved conflicts in the working copy, | |
167 * use {@link #getConflicts()} (which makes sense only when {@link #isStale()} is <code>false</code>). | |
168 * @return <code>true</code> when repository is being merged | |
169 */ | |
163 public boolean isMerging() { | 170 public boolean isMerging() { |
164 return !getFirstParent().isNull() && !getSecondParent().isNull() && !isStale(); | 171 return !getFirstParent().isNull() && !getSecondParent().isNull() && !isStale(); |
165 } | 172 } |
166 | 173 |
167 /** | 174 /** |
175 * Merge state file may not match actual working copy due to rollback or undo operations. | |
176 * Value of {@link #getConflicts()} is reasonable iff this method returned <code>false</code>. | |
177 * | |
168 * @return <code>true</code> when recorded merge state doesn't seem to correspond to present working copy | 178 * @return <code>true</code> when recorded merge state doesn't seem to correspond to present working copy |
169 */ | 179 */ |
170 public boolean isStale() { | 180 public boolean isStale() { |
171 if (wcp1 == null) { | 181 if (wcp1 == null) { |
172 throw new HgBadStateException("Call #refresh() first"); | 182 throw new HgBadStateException("Call #refresh() first"); |
173 } | 183 } |
174 return !wcp1.equals(stateParent); | 184 return !stateParent.isNull() /*there's merge state*/ && !wcp1.equals(stateParent) /*and it doesn't match*/; |
175 } | 185 } |
176 | 186 |
177 /** | 187 /** |
178 * FIXME decide what to return if there's no merge state altogether (perhaps, separate method to check that) | 188 * It's possible for a repository to be in a 'merging' state (@see {@link #isMerging()} without any |
179 * @return never <code>null</code> | 189 * conflict to resolve (no merge state information file). |
190 * @return first parent of the working copy, never <code>null</code> | |
180 */ | 191 */ |
181 public Nodeid getFirstParent() { | 192 public Nodeid getFirstParent() { |
182 if (wcp1 == null) { | 193 if (wcp1 == null) { |
183 throw new HgBadStateException("Call #refresh() first"); | 194 throw new HgBadStateException("Call #refresh() first"); |
184 } | 195 } |
185 return wcp1; | 196 return wcp1; |
186 } | 197 } |
187 | 198 |
199 /** | |
200 * @return second parent of the working copy, never <code>null</code> | |
201 */ | |
188 public Nodeid getSecondParent() { | 202 public Nodeid getSecondParent() { |
189 if (wcp2 == null) { | 203 if (wcp2 == null) { |
190 throw new HgBadStateException("Call #refresh() first"); | 204 throw new HgBadStateException("Call #refresh() first"); |
191 } | 205 } |
192 return wcp2; | 206 return wcp2; |
200 throw new HgBadStateException("Call #refresh() first"); | 214 throw new HgBadStateException("Call #refresh() first"); |
201 } | 215 } |
202 return stateParent; | 216 return stateParent; |
203 } | 217 } |
204 | 218 |
219 /** | |
220 * List of conflicts as recorded in the merge state information file. | |
221 * Note, this information is valid unless {@link #isStale()} is <code>true</code>. | |
222 * | |
223 * @return non-<code>null</code> list with both resolved and unresolved conflicts. | |
224 */ | |
205 public List<Entry> getConflicts() { | 225 public List<Entry> getConflicts() { |
206 return entries == null ? Collections.<Entry>emptyList() : Arrays.asList(entries); | 226 return entries == null ? Collections.<Entry>emptyList() : Arrays.asList(entries); |
207 } | 227 } |
208 } | 228 } |