comparison src/org/tmatesoft/hg/repo/HgBranches.java @ 315:8952f89be195

Allow to query specific branch heads if they are closed
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 28 Sep 2011 12:18:21 +0200
parents 962f78aac342
children a54bfe0db959
comparison
equal deleted inserted replaced
314:fb74133d2025 315:8952f89be195
20 import java.io.BufferedWriter; 20 import java.io.BufferedWriter;
21 import java.io.File; 21 import java.io.File;
22 import java.io.FileReader; 22 import java.io.FileReader;
23 import java.io.FileWriter; 23 import java.io.FileWriter;
24 import java.io.IOException; 24 import java.io.IOException;
25 import java.util.ArrayList;
25 import java.util.Arrays; 26 import java.util.Arrays;
26 import java.util.Collections; 27 import java.util.Collections;
27 import java.util.HashMap; 28 import java.util.HashMap;
28 import java.util.LinkedHashMap; 29 import java.util.LinkedHashMap;
29 import java.util.LinkedHashSet; 30 import java.util.LinkedHashSet;
323 public static class BranchInfo { 324 public static class BranchInfo {
324 private final String name; 325 private final String name;
325 private List<Nodeid> heads; 326 private List<Nodeid> heads;
326 private boolean closed; 327 private boolean closed;
327 private final Nodeid start; 328 private final Nodeid start;
329 private List<Nodeid> closedHeads; // subset of heads, those that bear 'closed' flag, or null if closed == true
328 330
329 // XXX in fact, few but not all branchHeads might be closed, and isClosed for whole branch is not 331 // XXX in fact, few but not all branchHeads might be closed, and isClosed for whole branch is not
330 // possible to determine. 332 // possible to determine.
331 BranchInfo(String branchName, Nodeid first, Nodeid[] branchHeads) { 333 BranchInfo(String branchName, Nodeid first, Nodeid[] branchHeads) {
332 name = branchName; 334 name = branchName;
347 localCset[i++] = rmap.localRevision(h); 349 localCset[i++] = rmap.localRevision(h);
348 } 350 }
349 // [0] tipmost, [1] tipmost open 351 // [0] tipmost, [1] tipmost open
350 final Nodeid[] tipmost = new Nodeid[] {null, null}; 352 final Nodeid[] tipmost = new Nodeid[] {null, null};
351 final boolean[] allClosed = new boolean[] { true }; 353 final boolean[] allClosed = new boolean[] { true };
354 final ArrayList<Nodeid> _closedHeads = new ArrayList<Nodeid>(heads.size());
352 clog.range(new HgChangelog.Inspector() { 355 clog.range(new HgChangelog.Inspector() {
353 356
354 public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) { 357 public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
355 assert heads.contains(nodeid); 358 assert heads.contains(nodeid);
356 tipmost[0] = nodeid; 359 tipmost[0] = nodeid;
357 if (!"1".equals(cset.extras().get("close"))) { 360 if (!"1".equals(cset.extras().get("close"))) {
358 tipmost[1] = nodeid; 361 tipmost[1] = nodeid;
359 allClosed[0] = false; 362 allClosed[0] = false;
363 } else {
364 _closedHeads.add(nodeid);
360 } 365 }
361 } 366 }
362 }, localCset); 367 }, localCset);
363 closed = allClosed[0]; 368 closed = allClosed[0];
364 Nodeid[] outcome = new Nodeid[localCset.length]; 369 Nodeid[] outcome = new Nodeid[localCset.length];
375 if (!h.equals(tipmost[0]) && !h.equals(tipmost[1])) { 380 if (!h.equals(tipmost[0]) && !h.equals(tipmost[1])) {
376 outcome[i++] = h; 381 outcome[i++] = h;
377 } 382 }
378 } 383 }
379 heads = Arrays.asList(outcome); 384 heads = Arrays.asList(outcome);
385 if (closed) {
386 // no need
387 closedHeads = null;
388 } else {
389 _closedHeads.trimToSize();
390 closedHeads = _closedHeads;
391 }
380 } 392 }
381 393
382 public String getName() { 394 public String getName() {
383 return name; 395 return name;
384 } 396 }
386 * @return <code>true</code> if all heads of this branch are marked as closed 398 * @return <code>true</code> if all heads of this branch are marked as closed
387 */ 399 */
388 public boolean isClosed() { 400 public boolean isClosed() {
389 return closed; 401 return closed;
390 } 402 }
403
404 /**
405 * @return all heads for the branch, both open and closed, tip-most head first
406 */
391 public List<Nodeid> getHeads() { 407 public List<Nodeid> getHeads() {
392 return heads; 408 return heads;
409 }
410
411 /**
412 *
413 * @param head one of revision from {@link #getHeads() heads} of this branch
414 * @return true if this particular head is closed
415 * @throws IllegalArgumentException if argument is not from {@link #getHeads() heads} of this branch
416 */
417 public boolean isClosed(Nodeid head) {
418 if (!heads.contains(head)) {
419 throw new IllegalArgumentException(String.format("Revision %s does not belong to heads of %s branch", head, name), null);
420 }
421 if (closed) {
422 return true;
423 }
424 return closedHeads.contains(head);
393 } 425 }
394 // public Nodeid getTip() { 426 // public Nodeid getTip() {
395 // } 427 // }
396 /*public*/ Nodeid getStart() { 428 /*public*/ Nodeid getStart() {
397 // first node where branch appears 429 // first node where branch appears