changeset 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 fb74133d2025
children ee6b467c1a5f
files src/org/tmatesoft/hg/repo/HgBranches.java test/org/tmatesoft/hg/test/TestBranches.java
diffstat 2 files changed, 69 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgBranches.java	Tue Sep 27 06:34:54 2011 +0200
+++ b/src/org/tmatesoft/hg/repo/HgBranches.java	Wed Sep 28 12:18:21 2011 +0200
@@ -22,6 +22,7 @@
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -325,6 +326,7 @@
 		private List<Nodeid> heads;
 		private boolean closed;
 		private final Nodeid start;
+		private List<Nodeid> closedHeads; // subset of heads, those that bear 'closed' flag, or null if closed == true
 
 		// XXX in fact, few but not all branchHeads might be closed, and isClosed for whole branch is not
 		// possible to determine.
@@ -349,6 +351,7 @@
 			// [0] tipmost, [1] tipmost open
 			final Nodeid[] tipmost = new Nodeid[] {null, null};
 			final boolean[] allClosed = new boolean[] { true };
+			final ArrayList<Nodeid> _closedHeads = new ArrayList<Nodeid>(heads.size());
 			clog.range(new HgChangelog.Inspector() {
 				
 				public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
@@ -357,6 +360,8 @@
 					if (!"1".equals(cset.extras().get("close"))) {
 						tipmost[1] = nodeid;
 						allClosed[0] = false;
+					} else {
+						_closedHeads.add(nodeid);
 					}
 				}
 			}, localCset);
@@ -377,6 +382,13 @@
 				}
 			}
 			heads = Arrays.asList(outcome);
+			if (closed) {
+				// no need
+				closedHeads = null;
+			} else {
+				_closedHeads.trimToSize();
+				closedHeads = _closedHeads;
+			}
 		}
 
 		public String getName() {
@@ -388,9 +400,29 @@
 		public boolean isClosed() {
 			return closed;
 		}
+
+		/**
+		 * @return all heads for the branch, both open and closed, tip-most head first
+		 */
 		public List<Nodeid> getHeads() {
 			return heads;
 		}
+
+		/**
+		 * 
+		 * @param head one of revision from {@link #getHeads() heads} of this branch 
+		 * @return true if this particular head is closed
+		 * @throws IllegalArgumentException if argument is not from {@link #getHeads() heads} of this branch
+		 */
+		public boolean isClosed(Nodeid head) {
+			if (!heads.contains(head)) {
+				throw new IllegalArgumentException(String.format("Revision %s does not belong to heads of %s branch", head, name), null);
+			}
+			if (closed) {
+				return true;
+			}
+			return closedHeads.contains(head);
+		}
 //		public Nodeid getTip() {
 //		}
 		/*public*/ Nodeid getStart() {
--- a/test/org/tmatesoft/hg/test/TestBranches.java	Tue Sep 27 06:34:54 2011 +0200
+++ b/test/org/tmatesoft/hg/test/TestBranches.java	Wed Sep 28 12:18:21 2011 +0200
@@ -18,14 +18,22 @@
 
 import static org.junit.Assert.*;
 
-import org.junit.Assert;
 import org.junit.Test;
+import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.repo.HgBranches;
 import org.tmatesoft.hg.repo.HgBranches.BranchInfo;
 import org.tmatesoft.hg.repo.HgRepository;
 
 /**
- *
+ * <pre>
+ * branches-1/create.bat:
+ * branch1 to have fork, two heads, both closed -- shall be recognized as closed
+ * branch2 to have fork, two heads, one closed  -- shall be recognized as active
+ * branch3 no active head						-- shall be recognized as inactive
+ * branch4 to fork, with 1 inactive and 1 active heads
+ * branch5 to be closed and reopened
+ * </pre>
+ * 
  * @author Artem Tikhomirov
  * @author TMate Software Ltd.
  */
@@ -69,4 +77,31 @@
 		assertEquals(1, b5.getHeads().size());
 		assertEquals("9cb6ad32b9074021356c38050e2aab6addba4393", b5.getHeads().get(0).toString());
 	}
+
+	@Test
+	public void testBranchInfoClosedHeads() throws Exception{
+		HgRepository repo = Configuration.get().find("branches-1");
+		HgBranches branches = repo.getBranches();
+		// branch1 - two closed heads
+		BranchInfo b1 = branches.getBranch("branch1");
+		assertTrue(b1.isClosed(b1.getHeads().get(0)));
+		assertTrue(b1.isClosed(b1.getHeads().get(1)));
+		try {
+			b1.isClosed(Nodeid.fromAscii("9cb6ad32b9074021356c38050e2aab6addba4393"));
+			fail("Revision that doesn't belong to heads of the branch shall not be handled");
+		} catch (IllegalArgumentException ex) {
+			// good
+		}
+		//
+		// branch2, one closed head
+		BranchInfo b2 = branches.getBranch("branch2");
+		assertFalse(b2.isClosed(b2.getHeads().get(0)));
+		assertTrue(b2.isClosed(b2.getHeads().get(1)));
+		//
+		// branch5, closed and reopened, 1 open head
+		BranchInfo b5 = branches.getBranch("branch5");
+		for (Nodeid h : b5.getHeads()) {
+			assertFalse(b5.isClosed(h));
+		}
+	}
 }