Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgRepository.java @ 610:5c68567b3645
Refresh tags, branches, bookmarks and ignore when their files (or csets in the repo) are changed
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Thu, 09 May 2013 21:06:48 +0200 |
| parents | e447384f3771 |
| children | f41dd9a3b8af |
comparison
equal
deleted
inserted
replaced
| 609:e4a71afd3c71 | 610:5c68567b3645 |
|---|---|
| 14 * the terms of a license other than GNU General Public License | 14 * the terms of a license other than GNU General Public License |
| 15 * contact TMate Software at support@hg4j.com | 15 * contact TMate Software at support@hg4j.com |
| 16 */ | 16 */ |
| 17 package org.tmatesoft.hg.repo; | 17 package org.tmatesoft.hg.repo; |
| 18 | 18 |
| 19 import static org.tmatesoft.hg.repo.HgRepositoryFiles.*; | 19 import static org.tmatesoft.hg.repo.HgRepositoryFiles.LastMessage; |
| 20 import static org.tmatesoft.hg.util.LogFacility.Severity.*; | 20 import static org.tmatesoft.hg.util.LogFacility.Severity.Warn; |
| 21 | 21 |
| 22 import java.io.File; | 22 import java.io.File; |
| 23 import java.io.FileReader; | 23 import java.io.FileReader; |
| 24 import java.io.IOException; | 24 import java.io.IOException; |
| 25 import java.io.StringReader; | |
| 26 import java.nio.CharBuffer; | 25 import java.nio.CharBuffer; |
| 27 import java.util.ArrayList; | 26 import java.util.ArrayList; |
| 28 import java.util.Collections; | 27 import java.util.Collections; |
| 29 import java.util.List; | 28 import java.util.List; |
| 30 | 29 |
| 31 import org.tmatesoft.hg.core.Nodeid; | 30 import org.tmatesoft.hg.core.Nodeid; |
| 32 import org.tmatesoft.hg.core.SessionContext; | 31 import org.tmatesoft.hg.core.SessionContext; |
| 33 import org.tmatesoft.hg.internal.ByteArrayChannel; | |
| 34 import org.tmatesoft.hg.internal.ConfigFile; | 32 import org.tmatesoft.hg.internal.ConfigFile; |
| 35 import org.tmatesoft.hg.internal.DirstateReader; | 33 import org.tmatesoft.hg.internal.DirstateReader; |
| 36 import org.tmatesoft.hg.internal.Experimental; | 34 import org.tmatesoft.hg.internal.Experimental; |
| 37 import org.tmatesoft.hg.internal.Filter; | 35 import org.tmatesoft.hg.internal.Filter; |
| 38 import org.tmatesoft.hg.internal.Internals; | 36 import org.tmatesoft.hg.internal.Internals; |
| 39 import org.tmatesoft.hg.internal.PropertyMarshal; | 37 import org.tmatesoft.hg.internal.PropertyMarshal; |
| 40 import org.tmatesoft.hg.internal.RevlogStream; | 38 import org.tmatesoft.hg.internal.RevlogStream; |
| 41 import org.tmatesoft.hg.internal.SubrepoManager; | 39 import org.tmatesoft.hg.internal.SubrepoManager; |
| 42 import org.tmatesoft.hg.repo.ext.HgExtensionsManager; | 40 import org.tmatesoft.hg.repo.ext.HgExtensionsManager; |
| 43 import org.tmatesoft.hg.util.CancelledException; | |
| 44 import org.tmatesoft.hg.util.Pair; | 41 import org.tmatesoft.hg.util.Pair; |
| 45 import org.tmatesoft.hg.util.Path; | 42 import org.tmatesoft.hg.util.Path; |
| 46 import org.tmatesoft.hg.util.PathRewrite; | 43 import org.tmatesoft.hg.util.PathRewrite; |
| 47 import org.tmatesoft.hg.util.ProgressSupport; | 44 import org.tmatesoft.hg.util.ProgressSupport; |
| 48 | 45 |
| 108 private HgBranches branches; | 105 private HgBranches branches; |
| 109 private HgMergeState mergeState; | 106 private HgMergeState mergeState; |
| 110 private SubrepoManager subRepos; | 107 private SubrepoManager subRepos; |
| 111 private HgBookmarks bookmarks; | 108 private HgBookmarks bookmarks; |
| 112 private HgExtensionsManager extManager; | 109 private HgExtensionsManager extManager; |
| 113 | |
| 114 private final org.tmatesoft.hg.internal.Internals impl; | |
| 115 private HgIgnore ignore; | 110 private HgIgnore ignore; |
| 116 private HgRepoConfig repoConfig; | 111 private HgRepoConfig repoConfig; |
| 112 | |
| 113 private final org.tmatesoft.hg.internal.Internals impl; | |
| 117 | 114 |
| 118 /* | 115 /* |
| 119 * TODO [post-1.0] move to a better place, e.g. WorkingCopy container that tracks both dirstate and branches | 116 * TODO [post-1.0] move to a better place, e.g. WorkingCopy container that tracks both dirstate and branches |
| 120 * (and, perhaps, undo, lastcommit and other similar information), and is change listener so that we don't need to | 117 * (and, perhaps, undo, lastcommit and other similar information), and is change listener so that we don't need to |
| 121 * worry about this cached value become stale | 118 * worry about this cached value become stale |
| 155 } | 152 } |
| 156 public RevlogStream getChangelogStream() { | 153 public RevlogStream getChangelogStream() { |
| 157 return HgRepository.this.getChangelog().content; | 154 return HgRepository.this.getChangelog().content; |
| 158 } | 155 } |
| 159 }); | 156 }); |
| 160 normalizePath = impl.buildNormalizePathRewrite(); | 157 normalizePath = impl.buildNormalizePathRewrite(); |
| 161 } | 158 } |
| 162 | 159 |
| 163 @Override | 160 @Override |
| 164 public String toString() { | 161 public String toString() { |
| 165 return getClass().getSimpleName() + "[" + getLocation() + (isInvalid() ? "(BAD)" : "") + "]"; | 162 return getClass().getSimpleName() + "[" + getLocation() + (isInvalid() ? "(BAD)" : "") + "]"; |
| 199 } | 196 } |
| 200 return manifest; | 197 return manifest; |
| 201 } | 198 } |
| 202 | 199 |
| 203 /** | 200 /** |
| 201 * Access snapshot of repository tags. | |
| 202 * | |
| 204 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 203 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> |
| 205 */ | 204 */ |
| 206 public HgTags getTags() throws HgInvalidControlFileException { | 205 public HgTags getTags() throws HgInvalidControlFileException { |
| 207 if (tags == null) { | 206 if (tags == null) { |
| 208 tags = new HgTags(this); | 207 tags = new HgTags(impl); |
| 209 HgDataFile hgTags = getFileNode(HgTags.getPath()); | 208 tags.read(); |
| 210 if (hgTags.exists()) { | 209 } else { |
| 211 for (int i = 0; i <= hgTags.getLastRevision(); i++) { // TODO post-1.0 in fact, would be handy to have walk(start,end) | 210 tags.reloadIfChanged(); |
| 212 // method for data files as well, though it looks odd. | |
| 213 try { | |
| 214 ByteArrayChannel sink = new ByteArrayChannel(); | |
| 215 hgTags.content(i, sink); | |
| 216 final String content = new String(sink.toArray(), "UTF8"); | |
| 217 tags.readGlobal(new StringReader(content)); | |
| 218 } catch (CancelledException ex) { | |
| 219 // IGNORE, can't happen, we did not configure cancellation | |
| 220 getSessionContext().getLog().dump(getClass(), Debug, ex, null); | |
| 221 } catch (IOException ex) { | |
| 222 // UnsupportedEncodingException can't happen (UTF8) | |
| 223 // only from readGlobal. Need to reconsider exceptions thrown from there: | |
| 224 // BufferedReader wraps String and unlikely to throw IOException, perhaps, log is enough? | |
| 225 getSessionContext().getLog().dump(getClass(), Error, ex, null); | |
| 226 // XXX need to decide what to do this. failure to read single revision shall not break complete cycle | |
| 227 } | |
| 228 } | |
| 229 } | |
| 230 File file2read = null; | |
| 231 try { | |
| 232 file2read = new File(getWorkingDir(), HgTags.getPath()); | |
| 233 tags.readGlobal(file2read); // XXX replace with HgDataFile.workingCopy | |
| 234 file2read = impl.getFileFromRepoDir(HgLocalTags.getName()); // XXX pass internalrepo to readLocal, keep filename there | |
| 235 tags.readLocal(file2read); | |
| 236 } catch (IOException ex) { | |
| 237 getSessionContext().getLog().dump(getClass(), Error, ex, null); | |
| 238 throw new HgInvalidControlFileException("Failed to read tags", ex, file2read); | |
| 239 } | |
| 240 } | 211 } |
| 241 return tags; | 212 return tags; |
| 242 } | 213 } |
| 243 | 214 |
| 244 /** | 215 /** |
| 245 * Access branch information | 216 * Access branch information. Returns a snapshot of branch information as it's available at the time of the call. |
| 217 * If repository get changed, use this method to obtain an up-to-date state. | |
| 218 * | |
| 246 * @return branch manager instance, never <code>null</code> | 219 * @return branch manager instance, never <code>null</code> |
| 247 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 220 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> |
| 248 */ | 221 */ |
| 249 public HgBranches getBranches() throws HgInvalidControlFileException { | 222 public HgBranches getBranches() throws HgInvalidControlFileException { |
| 223 final ProgressSupport ps = ProgressSupport.Factory.get(null); | |
| 250 if (branches == null) { | 224 if (branches == null) { |
| 251 branches = new HgBranches(impl); | 225 branches = new HgBranches(impl); |
| 252 branches.collect(ProgressSupport.Factory.get(null)); | 226 branches.collect(ps); |
| 227 } else { | |
| 228 branches.reloadIfChanged(ps); | |
| 253 } | 229 } |
| 254 return branches; | 230 return branches; |
| 255 } | 231 } |
| 256 | 232 |
| 257 /** | 233 /** |
| 368 */ | 344 */ |
| 369 public HgIgnore getIgnore() throws HgInvalidControlFileException { | 345 public HgIgnore getIgnore() throws HgInvalidControlFileException { |
| 370 // TODO read config for additional locations | 346 // TODO read config for additional locations |
| 371 if (ignore == null) { | 347 if (ignore == null) { |
| 372 ignore = new HgIgnore(getToRepoPathHelper()); | 348 ignore = new HgIgnore(getToRepoPathHelper()); |
| 373 File ignoreFile = new File(getWorkingDir(), HgIgnore.getPath()); | 349 ignore.read(impl); |
| 374 try { | 350 } else { |
| 375 final List<String> errors = ignore.read(ignoreFile); | 351 ignore.reloadIfChanged(impl); |
| 376 if (errors != null) { | |
| 377 getSessionContext().getLog().dump(getClass(), Warn, "Syntax errors parsing %s:\n%s", ignoreFile.getName(), Internals.join(errors, ",\n")); | |
| 378 } | |
| 379 } catch (IOException ex) { | |
| 380 final String m = String.format("Error reading %s file", ignoreFile); | |
| 381 throw new HgInvalidControlFileException(m, ex, ignoreFile); | |
| 382 } | |
| 383 } | 352 } |
| 384 return ignore; | 353 return ignore; |
| 385 } | 354 } |
| 386 | 355 |
| 387 /** | 356 /** |
| 463 */ | 432 */ |
| 464 public HgBookmarks getBookmarks() throws HgInvalidControlFileException { | 433 public HgBookmarks getBookmarks() throws HgInvalidControlFileException { |
| 465 if (bookmarks == null) { | 434 if (bookmarks == null) { |
| 466 bookmarks = new HgBookmarks(impl); | 435 bookmarks = new HgBookmarks(impl); |
| 467 bookmarks.read(); | 436 bookmarks.read(); |
| 437 } else { | |
| 438 bookmarks.reloadIfChanged(); | |
| 468 } | 439 } |
| 469 return bookmarks; | 440 return bookmarks; |
| 470 } | 441 } |
| 471 | 442 |
| 472 public HgExtensionsManager getExtensions() { | 443 public HgExtensionsManager getExtensions() { |
