Skip to content

Commit 3120b39

Browse files
author
Vladimir Kotal
committed
Merge pull request #823 from vladak/tag_fix
reassign tags to changesets when performing merging of old and new histo...
2 parents 8191342 + e3ef0ee commit 3120b39

File tree

8 files changed

+195
-12
lines changed

8 files changed

+195
-12
lines changed

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

+20-5
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ private void doFileHistory(Map.Entry<String, List<HistoryEntry>> map_entry,
124124

125125
File file = new File(root, map_entry.getKey());
126126
if (!file.isDirectory()) {
127-
storeFile(hist, file);
127+
storeFile(hist, file, repository);
128128
}
129129
}
130130

@@ -213,9 +213,10 @@ private static History readCache(File file) throws IOException {
213213
*
214214
* @param history history object to store
215215
* @param file file to store the history object into
216+
* @param repo repository for the file
216217
* @throws HistoryException
217218
*/
218-
private void storeFile(History histNew, File file) throws HistoryException {
219+
private void storeFile(History histNew, File file, Repository repo) throws HistoryException {
219220

220221
File cache = getCachedFile(file);
221222
History history = histNew;
@@ -233,12 +234,26 @@ private void storeFile(History histNew, File file) throws HistoryException {
233234
// Merge old history with the new history.
234235
List<HistoryEntry> listOld = histOld.getHistoryEntries();
235236
if (!listOld.isEmpty()) {
237+
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
236238
List<HistoryEntry> listNew = histNew.getHistoryEntries();
237239
ListIterator li = listNew.listIterator(listNew.size());
238240
while (li.hasPrevious()) {
239241
listOld.add(0, (HistoryEntry) li.previous());
240242
}
241243
history = new History(listOld);
244+
245+
// Retag the last changesets in case there have been some new
246+
// tags added to the repository. Technically we should just
247+
// retag the last revision from the listOld however this
248+
// does not solve the problem when listNew contains new tags
249+
// retroactively tagging changesets from listOld so we resort
250+
// to this somewhat crude solution.
251+
if (env.isTagsEnabled() && repo.hasFileBasedTags()) {
252+
for (HistoryEntry ent : history.getHistoryEntries()) {
253+
ent.setTags(null);
254+
}
255+
repo.assignTagsInHistory(history);
256+
}
242257
}
243258
} catch (IOException ex) {
244259
// Ideally we would want to catch the case when incremental update
@@ -491,7 +506,7 @@ public History get(File file, Repository repository, boolean withFiles)
491506
(cache.exists() ||
492507
(time > env.getHistoryReaderTimeLimit()))) {
493508
// retrieving the history takes too long, cache it!
494-
storeFile(history, file);
509+
storeFile(history, file, repository);
495510
}
496511
}
497512
return history;
@@ -573,13 +588,13 @@ private void storeLatestCachedRevision(Repository repository, String rev) {
573588
new FileOutputStream(getRepositoryCachedRevPath(repository))));
574589
writer.write(rev);
575590
} catch (IOException ex) {
576-
logger.log(Level.WARNING, "cannot write latest cached revision to file: {0}",
591+
logger.log(Level.WARNING, "cannot write latest cached revision to file: " +
577592
ex.getCause());
578593
} finally {
579594
try {
580595
writer.close();
581596
} catch (IOException ex) {
582-
logger.log(Level.INFO, "cannot close file: {0}", ex);
597+
logger.log(Level.INFO, "cannot close file: " + ex);
583598
}
584599
}
585600
}

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

-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
4444
import org.opensolaris.opengrok.index.IgnoredNames;
4545
import org.opensolaris.opengrok.util.Statistics;
46-
import org.opensolaris.opengrok.util.StringUtils;
4746

4847
/**
4948
* The HistoryGuru is used to implement an transparent layer to the various

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

+4
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,10 @@ protected void buildTagList(File directory) {
589589
tag.concat(" ");
590590
tag.concat(parts[i]);
591591
}
592+
// The implicit 'tip' tag only causes confusion so ignore it.
593+
if (tag.contentEquals("tip")) {
594+
continue;
595+
}
592596
String revParts[] = parts[parts.length - 1].split(":");
593597
if (revParts.length != 2) {
594598
OpenGrokLogger.getLogger().log(Level.WARNING,

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ protected String getRevisionForAnnotate(String history_revision) {
260260
}
261261

262262
/**
263-
* Create a history log cache for all of the files in this repository.
263+
* Create a history log cache for all files in this repository.
264264
* {@code getHistory()} is used to fetch the history for the entire
265265
* repository. If {@code hasHistoryForDirectories()} returns {@code false},
266266
* this method is a no-op.
@@ -317,6 +317,12 @@ final void createCache(HistoryCache cache, String sinceRevision)
317317
cache.clear(this);
318318
}
319319

320+
// We need to refresh list of tags for incremental reindex.
321+
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
322+
if (env.isTagsEnabled() && this.hasFileBasedTags()) {
323+
this.buildTagList(new File(this.directoryName));
324+
}
325+
320326
if (history != null) {
321327
cache.store(history, this);
322328
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ public static Repository getRepository(File file) throws InstantiationException,
8888
try {
8989
res.setDirectoryName(file.getCanonicalPath());
9090
} catch (IOException e) {
91-
OpenGrokLogger.getLogger().log(Level.SEVERE, "Failed to get canonical path name for " + file.getAbsolutePath(), e);
91+
OpenGrokLogger.getLogger().log(Level.SEVERE,
92+
"Failed to get canonical path name for " + file.getAbsolutePath(), e);
9293
}
9394

9495
if (!res.isWorking()) {

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

+82-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.LinkedList;
3131
import java.util.List;
3232
import junit.framework.TestCase;
33+
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
3334
import org.opensolaris.opengrok.util.Executor;
3435
import org.opensolaris.opengrok.util.TestRepository;
3536

@@ -86,6 +87,7 @@ private void importHgChangeset(File reposRoot, String changesetFile) {
8687
* Assert that two HistoryEntry objects are equal.
8788
* @param expected the expected entry
8889
* @param actual the actual entry
90+
* @param isdir was the history generated for a directory
8991
* @throws AssertFailure if the two entries don't match
9092
*/
9193
private void assertSameEntries(
@@ -102,6 +104,7 @@ private void assertSameEntries(
102104
* Assert that two lists of HistoryEntry objects are equal.
103105
* @param expected the expected list of entries
104106
* @param actual the actual list of entries
107+
* @param isdir was the history generated for directory
105108
* @throws AssertFailure if the two lists don't match
106109
*/
107110
private void assertSameEntry(HistoryEntry expected, HistoryEntry actual, boolean isdir) {
@@ -114,8 +117,9 @@ private void assertSameEntry(HistoryEntry expected, HistoryEntry actual, boolean
114117
} else {
115118
assertEquals(0, actual.getFiles().size());
116119
}
120+
assertEquals(expected.getTags(), actual.getTags());
117121
}
118-
122+
119123
/**
120124
* Basic tests for the {@code store()} method on cache with disabled
121125
* handling of renamed files.
@@ -138,6 +142,83 @@ public void testStoreAndGetNotRenamed() throws Exception {
138142
assertEquals("9:8b340409b3a8", cache.getLatestCachedRevision(repo));
139143
}
140144

145+
/**
146+
* Test tagging by creating history cache for repository with one tag
147+
* and then importing couple of changesets which add both file changes
148+
* and tags. The last history entry before the import is important
149+
* as it needs to be retagged when old history is merged with the new one.
150+
*/
151+
public void testStoreAndGetIncrementalTags() throws Exception {
152+
// Enable tagging of history entries.
153+
RuntimeEnvironment.getInstance().setTagsEnabled(true);
154+
155+
File reposRoot = new File(repositories.getSourceRoot(), "mercurial");
156+
Repository repo = RepositoryFactory.getRepository(reposRoot);
157+
History historyToStore = repo.getHistory(reposRoot);
158+
159+
// Store the history.
160+
cache.store(historyToStore, repo);
161+
162+
// Add bunch of changesets with file based changes and tags.
163+
importHgChangeset(
164+
reposRoot, getClass().getResource("hg-export-tag.txt").getPath());
165+
166+
// Perform incremental reindex.
167+
repo.createCache(cache, cache.getLatestCachedRevision(repo));
168+
169+
// Check that the changesets were indeed applied and indexed.
170+
History updatedHistory = cache.get(reposRoot, repo, true);
171+
assertEquals("Unexpected number of history entries",
172+
15, updatedHistory.getHistoryEntries().size());
173+
174+
// Verify tags in fileHistory for main.c which is the most interesting
175+
// file from the repository from the perspective of tags.
176+
File main = new File(reposRoot, "main.c");
177+
assertTrue(main.exists());
178+
History retrievedHistoryMainC = cache.get(main, repo, true);
179+
List<HistoryEntry> entries = retrievedHistoryMainC.getHistoryEntries();
180+
assertEquals("Unexpected number of entries for main.c",
181+
3, entries.size());
182+
HistoryEntry e0 = entries.get(0);
183+
assertEquals("Unexpected revision for entry 0", "13:3d386f6bd848",
184+
e0.getRevision());
185+
assertEquals("Invalid tag list for revision 13", "tag3", e0.getTags());
186+
HistoryEntry e1 = entries.get(1);
187+
assertEquals("Unexpected revision for entry 1", "2:585a1b3f2efb",
188+
e1.getRevision());
189+
assertEquals("Invalid tag list for revision 2",
190+
"tag2, tag1, start_of_novel", e1.getTags());
191+
HistoryEntry e2 = entries.get(2);
192+
assertEquals("Unexpected revision for entry 2", "1:f24a5fd7a85d",
193+
e2.getRevision());
194+
assertEquals("Invalid tag list for revision 1", null, e2.getTags());
195+
196+
// Reindex from scratch.
197+
File dir = new File(cache.getRepositoryHistDataDirname(repo));
198+
assertTrue(dir.isDirectory());
199+
cache.clear(repo);
200+
// We cannot call cache.get() here since it would read the history anew.
201+
// Instead check that the data directory does not exist anymore.
202+
assertFalse(dir.exists());
203+
History freshHistory = repo.getHistory(reposRoot);
204+
cache.store(freshHistory, repo);
205+
History updatedHistoryFromScratch = cache.get(reposRoot, repo, true);
206+
assertEquals("Unexpected number of history entries",
207+
freshHistory.getHistoryEntries().size(),
208+
updatedHistoryFromScratch.getHistoryEntries().size());
209+
210+
// Verify that the result for the directory is the same as incremental
211+
// reindex.
212+
assertSameEntries(updatedHistory.getHistoryEntries(),
213+
updatedHistoryFromScratch.getHistoryEntries(), true);
214+
// Do the same for main.c.
215+
History retrievedUpdatedHistoryMainC = cache.get(main, repo, true);
216+
assertSameEntries(retrievedHistoryMainC.getHistoryEntries(),
217+
retrievedUpdatedHistoryMainC.getHistoryEntries(), false);
218+
219+
RuntimeEnvironment.getInstance().setTagsEnabled(false);
220+
}
221+
141222
/**
142223
* Basic tests for the {@code store()} and {@code get()} methods.
143224
*/

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ public void testTags() throws Exception {
496496
List<HistoryEntry> dirHistory =
497497
cache.get(reposRoot, repos, false).getHistoryEntries();
498498
assertEquals("Size of history", 10, dirHistory.size());
499-
assertEquals("tip", dirHistory.get(0).getTags());
499+
assertEquals(null, dirHistory.get(0).getTags());
500500
assertNull(dirHistory.get(1).getTags());
501501
assertEquals("start_of_novel", dirHistory.get(2).getTags());
502502
assertNull(dirHistory.get(3).getTags());
@@ -505,14 +505,14 @@ public void testTags() throws Exception {
505505
cache.get(new File(reposRoot, "novel.txt"),
506506
repos, false).getHistoryEntries();
507507
assertEquals("Size of history", 6, novelHistory.size());
508-
assertEquals("tip", novelHistory.get(0).getTags());
508+
assertEquals(null, novelHistory.get(0).getTags());
509509
assertEquals("start_of_novel", novelHistory.get(1).getTags());
510510

511511
List<HistoryEntry> maincHistory =
512512
cache.get(new File(reposRoot, "main.c"),
513513
repos, false).getHistoryEntries();
514514
assertEquals("Size of history", 2, maincHistory.size());
515-
assertEquals("tip, start_of_novel", maincHistory.get(0).getTags());
515+
assertEquals("start_of_novel", maincHistory.get(0).getTags());
516516
assertNull(maincHistory.get(1).getTags());
517517
}
518518
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# HG changeset patch
2+
# User Vladimir Kotal <[email protected]>
3+
# Date 1398454830 -7200
4+
# Fri Apr 25 21:40:30 2014 +0200
5+
# Node ID 9203f5519aca0213ab1fb1700082eeabeda82e60
6+
# Parent 8b340409b3a81618750aa660cb113c65440688be
7+
Added tag tag1 for changeset 8b340409b3a8
8+
9+
diff -r 8b340409b3a8 -r 9203f5519aca .hgtags
10+
--- a/.hgtags Sat Jul 13 18:27:46 2013 +0200
11+
+++ b/.hgtags Fri Apr 25 21:40:30 2014 +0200
12+
@@ -1,1 +1,2 @@
13+
db1394c05268686f89fbe4ca5524ac4ed61ec71c start_of_novel
14+
+8b340409b3a81618750aa660cb113c65440688be tag1
15+
# HG changeset patch
16+
# User Vladimir Kotal <[email protected]>
17+
# Date 1398454848 -7200
18+
# Fri Apr 25 21:40:48 2014 +0200
19+
# Node ID c102ebbaff2bf9320277a374c287987ec7f99ab9
20+
# Parent 9203f5519aca0213ab1fb1700082eeabeda82e60
21+
more
22+
23+
diff -r 9203f5519aca -r c102ebbaff2b bar.txt
24+
--- a/bar.txt Fri Apr 25 21:40:30 2014 +0200
25+
+++ b/bar.txt Fri Apr 25 21:40:48 2014 +0200
26+
@@ -1,1 +1,1 @@
27+
-stuff
28+
+stuff more
29+
# HG changeset patch
30+
# User Vladimir Kotal <[email protected]>
31+
# Date 1398454861 -7200
32+
# Fri Apr 25 21:41:01 2014 +0200
33+
# Node ID de12e7efa8d8771de0614fe151cf6e8a16530da6
34+
# Parent c102ebbaff2bf9320277a374c287987ec7f99ab9
35+
Added tag tag2 for changeset c102ebbaff2b
36+
37+
diff -r c102ebbaff2b -r de12e7efa8d8 .hgtags
38+
--- a/.hgtags Fri Apr 25 21:40:48 2014 +0200
39+
+++ b/.hgtags Fri Apr 25 21:41:01 2014 +0200
40+
@@ -1,2 +1,3 @@
41+
db1394c05268686f89fbe4ca5524ac4ed61ec71c start_of_novel
42+
8b340409b3a81618750aa660cb113c65440688be tag1
43+
+c102ebbaff2bf9320277a374c287987ec7f99ab9 tag2
44+
# HG changeset patch
45+
# User Vladimir Kotal <[email protected]>
46+
# Date 1398454896 -7200
47+
# Fri Apr 25 21:41:36 2014 +0200
48+
# Node ID 3d386f6bd84815069dbd6e4e1bc14bd1b958bdc7
49+
# Parent de12e7efa8d8771de0614fe151cf6e8a16530da6
50+
brackets
51+
52+
diff -r de12e7efa8d8 -r 3d386f6bd848 main.c
53+
--- a/main.c Fri Apr 25 21:41:01 2014 +0200
54+
+++ b/main.c Fri Apr 25 21:41:36 2014 +0200
55+
@@ -8,5 +8,5 @@
56+
}
57+
(void)printf("\n");
58+
59+
- return EXIT_SUCCESS;
60+
+ return (EXIT_SUCCESS);
61+
}
62+
# HG changeset patch
63+
# User Vladimir Kotal <[email protected]>
64+
# Date 1398454900 -7200
65+
# Fri Apr 25 21:41:40 2014 +0200
66+
# Node ID 5c85cd3019d8c8cbe54bca382c8329622be42c7c
67+
# Parent 3d386f6bd84815069dbd6e4e1bc14bd1b958bdc7
68+
Added tag tag3 for changeset 3d386f6bd848
69+
70+
diff -r 3d386f6bd848 -r 5c85cd3019d8 .hgtags
71+
--- a/.hgtags Fri Apr 25 21:41:36 2014 +0200
72+
+++ b/.hgtags Fri Apr 25 21:41:40 2014 +0200
73+
@@ -1,3 +1,4 @@
74+
db1394c05268686f89fbe4ca5524ac4ed61ec71c start_of_novel
75+
8b340409b3a81618750aa660cb113c65440688be tag1
76+
c102ebbaff2bf9320277a374c287987ec7f99ab9 tag2
77+
+3d386f6bd84815069dbd6e4e1bc14bd1b958bdc7 tag3

0 commit comments

Comments
 (0)