Skip to content

Commit 5c309df

Browse files
author
Vladimir Kotal
committed
support branches for Mercurial repository
fixes #865
1 parent 1218110 commit 5c309df

File tree

5 files changed

+109
-27
lines changed

5 files changed

+109
-27
lines changed

src/org/opensolaris/opengrok/history/MercurialRepository.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public class MercurialRepository extends Repository {
5858
*/
5959
public static final String CMD_FALLBACK = "hg";
6060

61+
private String branch = null;
62+
6163
/**
6264
* The boolean property and environment variable name to indicate
6365
* whether forest-extension in Mercurial adds repositories inside the
@@ -108,6 +110,24 @@ public MercurialRepository() {
108110
datePattern = "yyyy-MM-dd hh:mm ZZZZ";
109111
}
110112

113+
/** Return name of the branch or "default" */
114+
private String getBranch() {
115+
if (branch == null) {
116+
List<String> cmd = new ArrayList<String>();
117+
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);
118+
cmd.add(this.cmd);
119+
cmd.add("branch");
120+
121+
Executor e = new Executor(cmd, new File(directoryName));
122+
e.exec();
123+
124+
String output = e.getOutputString();
125+
branch = output.trim();
126+
}
127+
128+
return branch;
129+
}
130+
111131
/**
112132
* Get an executor to be used for retrieving the history log for the
113133
* named file or directory.
@@ -140,16 +160,21 @@ Executor getHistoryLogExecutor(File file, String changeset)
140160
cmd.add("-f");
141161
}
142162

163+
// If this is non-default branch we would like to get the changesets
164+
// on that branch and also any changesets from the parent branch(es).
143165
if (changeset != null) {
144166
cmd.add("-r");
145167
String[] parts = changeset.split(":");
146168
if (parts.length == 2) {
147-
cmd.add("tip:" + parts[0]);
169+
cmd.add("reverse(" + parts[0] + "::'" + getBranch() + "')");
148170
} else {
149171
throw new HistoryException(
150172
"Don't know how to parse changeset identifier: " +
151173
changeset);
152174
}
175+
} else {
176+
cmd.add("-r");
177+
cmd.add("reverse(0::'" + getBranch() + "')");
153178
}
154179

155180
cmd.add("--template");

src/org/opensolaris/opengrok/history/Repository.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ void removeAndVerifyOldestChangeset(List<HistoryEntry> entries,
147147
// and compare more fields, like author and date.
148148
if (entry == null || !revision.equals(entry.getRevision())) {
149149
throw new HistoryException("Cached revision '" + revision +
150-
"' not found in the repository");
150+
"' not found in the repository " +
151+
getDirectoryName());
151152
}
152153
}
153154

test/org/opensolaris/opengrok/history/FileHistoryCacheTest.java

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,26 +62,6 @@ public class FileHistoryCacheTest extends TestCase {
6262

6363
cache = null;
6464
}
65-
66-
/**
67-
* Import a new changeset into a Mercurial repository.
68-
*
69-
* @param reposRoot the root of the repository
70-
* @param changesetFile file that contains the changesets to import
71-
*/
72-
private void importHgChangeset(File reposRoot, String changesetFile) {
73-
String[] cmdargs = {
74-
MercurialRepository.CMD_FALLBACK, "import", changesetFile
75-
};
76-
Executor exec = new Executor(Arrays.asList(cmdargs), reposRoot);
77-
int exitCode = exec.exec();
78-
if (exitCode != 0) {
79-
fail("hg import failed." +
80-
"\nexit code: " + exitCode +
81-
"\nstdout:\n" + exec.getOutputString() +
82-
"\nstderr:\n" + exec.getErrorString());
83-
}
84-
}
8565

8666
/**
8767
* Assert that two HistoryEntry objects are equal.
@@ -160,7 +140,7 @@ public void testStoreAndGetIncrementalTags() throws Exception {
160140
cache.store(historyToStore, repo);
161141

162142
// Add bunch of changesets with file based changes and tags.
163-
importHgChangeset(
143+
MercurialRepositoryTest.runHgCommand("import",
164144
reposRoot, getClass().getResource("hg-export-tag.txt").getPath());
165145

166146
// Perform incremental reindex.
@@ -286,8 +266,7 @@ public void testStoreAndGet() throws Exception {
286266
dirHistory.getHistoryEntries(), true);
287267

288268
// test incremental update
289-
290-
importHgChangeset(
269+
MercurialRepositoryTest.runHgCommand("import",
291270
reposRoot, getClass().getResource("hg-export.txt").getPath());
292271

293272
repo.createCache(cache, cache.getLatestCachedRevision(repo));
@@ -347,7 +326,7 @@ public void testRenamedFile() throws Exception {
347326
cache.store(historyToStore, repo);
348327

349328
// import changesets which rename one of the files
350-
importHgChangeset(
329+
MercurialRepositoryTest.runHgCommand("import",
351330
reposRoot, getClass().getResource("hg-export-renamed.txt").getPath());
352331

353332
// reindex

test/org/opensolaris/opengrok/history/MercurialRepositoryTest.java

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@
2626
import java.io.File;
2727
import java.io.IOException;
2828
import java.io.InputStream;
29+
import java.util.ArrayList;
30+
import java.util.Arrays;
31+
import java.util.Collections;
2932
import java.util.List;
33+
import static junit.framework.Assert.fail;
3034
import org.junit.After;
3135
import org.junit.Test;
3236
import org.opensolaris.opengrok.util.TestRepository;
3337
import static org.junit.Assert.*;
38+
import org.opensolaris.opengrok.util.Executor;
3439

3540
/**
3641
* Tests for MercurialRepository.
@@ -48,6 +53,12 @@ public class MercurialRepositoryTest {
4853
"5:8706402863c6", "4:e494d67af12f", "3:2058725c1470",
4954
"2:585a1b3f2efb", "1:f24a5fd7a85d", "0:816b6279ae9c"
5055
};
56+
57+
// extra revisions for branch test
58+
private static final String[] REVISIONS_extra_branch = {
59+
"10:c4518ca0c841"
60+
};
61+
5162
// novel.txt (or its ancestors) existed only since revision 3
5263
private static final String[] REVISIONS_novel = {
5364
"9:8b340409b3a8",
@@ -118,7 +129,73 @@ public void testGetHistoryPartial() throws Exception {
118129
assertNotNull(e.getMessage());
119130
}
120131
}
121-
132+
133+
/**
134+
* Run Mercurial command.
135+
* @param command hg command to run
136+
* @param reposRoot directory of the repository root
137+
* @param arg argument to use for the command
138+
*/
139+
static void runHgCommand(String command, File reposRoot, String arg) {
140+
String[] cmdargs = {
141+
MercurialRepository.CMD_FALLBACK, command, arg
142+
};
143+
Executor exec = new Executor(Arrays.asList(cmdargs), reposRoot);
144+
int exitCode = exec.exec();
145+
if (exitCode != 0) {
146+
fail("hg " + command + " failed." +
147+
"\nexit code: " + exitCode +
148+
"\nstdout:\n" + exec.getOutputString() +
149+
"\nstderr:\n" + exec.getErrorString());
150+
}
151+
}
152+
153+
/**
154+
* Test that history of branched repository contains changesets of the
155+
* default branch as well.
156+
* @throws Exception
157+
*/
158+
@Test
159+
public void testGetHistoryBranch() throws Exception {
160+
setUpTestRepository();
161+
File root = new File(repository.getSourceRoot(), "mercurial");
162+
MercurialRepository mr =
163+
(MercurialRepository) RepositoryFactory.getRepository(root);
164+
165+
// Branch the repo and add one changeset.
166+
runHgCommand("unbundle",
167+
root, getClass().getResource("hg-branch.bundle").getPath());
168+
// Switch to the branch.
169+
runHgCommand("update", root, "mybranch");
170+
171+
// Get all revisions.
172+
History hist = mr.getHistory(root);
173+
List<HistoryEntry> entries = hist.getHistoryEntries();
174+
List<String> both = new ArrayList<String>(REVISIONS.length +
175+
REVISIONS_extra_branch.length);
176+
Collections.addAll(both, REVISIONS_extra_branch);
177+
Collections.addAll(both, REVISIONS);
178+
String revs[] = both.toArray(new String[both.size()]);
179+
assertEquals(revs.length, entries.size());
180+
// Ideally we should check that the last revision is branched but
181+
// there is currently no provision for that in HistoryEntry object.
182+
for (int i = 0; i < entries.size(); i++) {
183+
HistoryEntry e = entries.get(i);
184+
assertEquals(revs[i], e.getRevision());
185+
assertNotNull(e.getAuthor());
186+
assertNotNull(e.getDate());
187+
assertNotNull(e.getFiles());
188+
assertNotNull(e.getMessage());
189+
}
190+
191+
// Get revisions starting with given changeset before the repo was branched.
192+
hist = mr.getHistory(root, "8:6a8c423f5624");
193+
entries = hist.getHistoryEntries();
194+
assertEquals(2, entries.size());
195+
assertEquals(REVISIONS_extra_branch[0], entries.get(0).getRevision());
196+
assertEquals(REVISIONS[0], entries.get(1).getRevision());
197+
}
198+
122199
/**
123200
* Test that it is possible to get contents of last revision of a text
124201
* file.
Binary file not shown.

0 commit comments

Comments
 (0)