Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/WorkingCopyStatusCollector.java @ 93:d55d4eedfc57
Switch to Path instead of String in filenames returned by various status operations
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Thu, 27 Jan 2011 21:15:21 +0100 |
| parents | c2ce1cfaeb9e |
| children |
comparison
equal
deleted
inserted
replaced
| 92:bf304cb14247 | 93:d55d4eedfc57 |
|---|---|
| 28 import java.util.TreeSet; | 28 import java.util.TreeSet; |
| 29 | 29 |
| 30 import org.tmatesoft.hg.core.Nodeid; | 30 import org.tmatesoft.hg.core.Nodeid; |
| 31 import org.tmatesoft.hg.repo.StatusCollector.ManifestRevisionInspector; | 31 import org.tmatesoft.hg.repo.StatusCollector.ManifestRevisionInspector; |
| 32 import org.tmatesoft.hg.util.FileWalker; | 32 import org.tmatesoft.hg.util.FileWalker; |
| 33 import org.tmatesoft.hg.util.PathPool; | |
| 34 import org.tmatesoft.hg.util.PathRewrite; | |
| 33 | 35 |
| 34 /** | 36 /** |
| 35 * | 37 * |
| 36 * @author Artem Tikhomirov | 38 * @author Artem Tikhomirov |
| 37 * @author TMate Software Ltd. | 39 * @author TMate Software Ltd. |
| 40 | 42 |
| 41 private final HgRepository repo; | 43 private final HgRepository repo; |
| 42 private final FileWalker repoWalker; | 44 private final FileWalker repoWalker; |
| 43 private HgDirstate dirstate; | 45 private HgDirstate dirstate; |
| 44 private StatusCollector baseRevisionCollector; | 46 private StatusCollector baseRevisionCollector; |
| 47 private PathPool pathPool; | |
| 45 | 48 |
| 46 public WorkingCopyStatusCollector(HgRepository hgRepo) { | 49 public WorkingCopyStatusCollector(HgRepository hgRepo) { |
| 47 this(hgRepo, hgRepo.createWorkingDirWalker()); | 50 this(hgRepo, hgRepo.createWorkingDirWalker()); |
| 48 } | 51 } |
| 49 | 52 |
| 57 * @param sc may be null | 60 * @param sc may be null |
| 58 */ | 61 */ |
| 59 public void setBaseRevisionCollector(StatusCollector sc) { | 62 public void setBaseRevisionCollector(StatusCollector sc) { |
| 60 baseRevisionCollector = sc; | 63 baseRevisionCollector = sc; |
| 61 } | 64 } |
| 65 | |
| 66 /*package-local*/ PathPool getPathPool() { | |
| 67 if (pathPool == null) { | |
| 68 if (baseRevisionCollector == null) { | |
| 69 pathPool = new PathPool(new PathRewrite.Empty()); | |
| 70 } else { | |
| 71 return baseRevisionCollector.getPathPool(); | |
| 72 } | |
| 73 } | |
| 74 return pathPool; | |
| 75 } | |
| 76 | |
| 77 public void setPathPool(PathPool pathPool) { | |
| 78 this.pathPool = pathPool; | |
| 79 } | |
| 80 | |
| 62 | 81 |
| 63 private HgDirstate getDirstate() { | 82 private HgDirstate getDirstate() { |
| 64 if (dirstate == null) { | 83 if (dirstate == null) { |
| 65 dirstate = repo.loadDirstate(); | 84 dirstate = repo.loadDirstate(); |
| 66 } | 85 } |
| 67 return dirstate; | 86 return dirstate; |
| 68 } | 87 } |
| 69 | 88 |
| 70 // may be invoked few times | 89 // may be invoked few times |
| 71 public void walk(int baseRevision, StatusCollector.Inspector inspector) { | 90 public void walk(int baseRevision, HgStatusInspector inspector) { |
| 72 final HgIgnore hgIgnore = repo.getIgnore(); | 91 final HgIgnore hgIgnore = repo.getIgnore(); |
| 73 TreeSet<String> knownEntries = getDirstate().all(); | 92 TreeSet<String> knownEntries = getDirstate().all(); |
| 74 final boolean isTipBase; | 93 final boolean isTipBase; |
| 75 if (baseRevision == TIP) { | 94 if (baseRevision == TIP) { |
| 76 baseRevision = repo.getManifest().getRevisionCount() - 1; | 95 baseRevision = repo.getManifest().getRevisionCount() - 1; |
| 92 if (inspector instanceof StatusCollector.Record) { | 111 if (inspector instanceof StatusCollector.Record) { |
| 93 StatusCollector sc = baseRevisionCollector == null ? new StatusCollector(repo) : baseRevisionCollector; | 112 StatusCollector sc = baseRevisionCollector == null ? new StatusCollector(repo) : baseRevisionCollector; |
| 94 ((StatusCollector.Record) inspector).init(baseRevision, BAD_REVISION, sc); | 113 ((StatusCollector.Record) inspector).init(baseRevision, BAD_REVISION, sc); |
| 95 } | 114 } |
| 96 repoWalker.reset(); | 115 repoWalker.reset(); |
| 116 final PathPool pp = getPathPool(); | |
| 97 while (repoWalker.hasNext()) { | 117 while (repoWalker.hasNext()) { |
| 98 repoWalker.next(); | 118 repoWalker.next(); |
| 99 String fname = repoWalker.name(); | 119 String fname = repoWalker.name(); |
| 100 File f = repoWalker.file(); | 120 File f = repoWalker.file(); |
| 101 if (hgIgnore.isIgnored(fname)) { | 121 if (hgIgnore.isIgnored(fname)) { |
| 102 inspector.ignored(fname); | 122 inspector.ignored(pp.path(fname)); |
| 103 } else if (knownEntries.remove(fname)) { | 123 } else if (knownEntries.remove(fname)) { |
| 104 // modified, added, removed, clean | 124 // modified, added, removed, clean |
| 105 if (collect != null) { // need to check against base revision, not FS file | 125 if (collect != null) { // need to check against base revision, not FS file |
| 106 checkLocalStatusAgainstBaseRevision(baseRevFiles, collect, baseRevision, fname, f, inspector); | 126 checkLocalStatusAgainstBaseRevision(baseRevFiles, collect, baseRevision, fname, f, inspector); |
| 107 baseRevFiles.remove(fname); | 127 baseRevFiles.remove(fname); |
| 108 } else { | 128 } else { |
| 109 checkLocalStatusAgainstFile(fname, f, inspector); | 129 checkLocalStatusAgainstFile(fname, f, inspector); |
| 110 } | 130 } |
| 111 } else { | 131 } else { |
| 112 inspector.unknown(fname); | 132 inspector.unknown(pp.path(fname)); |
| 113 } | 133 } |
| 114 } | 134 } |
| 115 if (collect != null) { | 135 if (collect != null) { |
| 116 for (String r : baseRevFiles) { | 136 for (String r : baseRevFiles) { |
| 117 inspector.removed(r); | 137 inspector.removed(pp.path(r)); |
| 118 } | 138 } |
| 119 } | 139 } |
| 120 for (String m : knownEntries) { | 140 for (String m : knownEntries) { |
| 121 // missing known file from a working dir | 141 // missing known file from a working dir |
| 122 if (getDirstate().checkRemoved(m) == null) { | 142 if (getDirstate().checkRemoved(m) == null) { |
| 123 // not removed from the repository = 'deleted' | 143 // not removed from the repository = 'deleted' |
| 124 inspector.missing(m); | 144 inspector.missing(pp.path(m)); |
| 125 } else { | 145 } else { |
| 126 // removed from the repo | 146 // removed from the repo |
| 127 // if we check against non-tip revision, do not report files that were added past that revision and now removed. | 147 // if we check against non-tip revision, do not report files that were added past that revision and now removed. |
| 128 if (collect == null || baseRevFiles.contains(m)) { | 148 if (collect == null || baseRevFiles.contains(m)) { |
| 129 inspector.removed(m); | 149 inspector.removed(pp.path(m)); |
| 130 } | 150 } |
| 131 } | 151 } |
| 132 } | 152 } |
| 133 } | 153 } |
| 134 | 154 |
| 139 } | 159 } |
| 140 | 160 |
| 141 //******************************************** | 161 //******************************************** |
| 142 | 162 |
| 143 | 163 |
| 144 private void checkLocalStatusAgainstFile(String fname, File f, StatusCollector.Inspector inspector) { | 164 private void checkLocalStatusAgainstFile(String fname, File f, HgStatusInspector inspector) { |
| 145 HgDirstate.Record r; | 165 HgDirstate.Record r; |
| 146 if ((r = getDirstate().checkNormal(fname)) != null) { | 166 if ((r = getDirstate().checkNormal(fname)) != null) { |
| 147 // either clean or modified | 167 // either clean or modified |
| 148 if (f.lastModified() / 1000 == r.time && r.size == f.length()) { | 168 if (f.lastModified() / 1000 == r.time && r.size == f.length()) { |
| 149 inspector.clean(fname); | 169 inspector.clean(getPathPool().path(fname)); |
| 150 } else { | 170 } else { |
| 151 // FIXME check actual content to avoid false modified files | 171 // FIXME check actual content to avoid false modified files |
| 152 inspector.modified(fname); | 172 inspector.modified(getPathPool().path(fname)); |
| 153 } | 173 } |
| 154 } else if ((r = getDirstate().checkAdded(fname)) != null) { | 174 } else if ((r = getDirstate().checkAdded(fname)) != null) { |
| 155 if (r.name2 == null) { | 175 if (r.name2 == null) { |
| 156 inspector.added(fname); | 176 inspector.added(getPathPool().path(fname)); |
| 157 } else { | 177 } else { |
| 158 inspector.copied(r.name2, fname); | 178 inspector.copied(getPathPool().path(r.name2), getPathPool().path(fname)); |
| 159 } | 179 } |
| 160 } else if ((r = getDirstate().checkRemoved(fname)) != null) { | 180 } else if ((r = getDirstate().checkRemoved(fname)) != null) { |
| 161 inspector.removed(fname); | 181 inspector.removed(getPathPool().path(fname)); |
| 162 } else if ((r = getDirstate().checkMerged(fname)) != null) { | 182 } else if ((r = getDirstate().checkMerged(fname)) != null) { |
| 163 inspector.modified(fname); | 183 inspector.modified(getPathPool().path(fname)); |
| 164 } | 184 } |
| 165 } | 185 } |
| 166 | 186 |
| 167 // XXX refactor checkLocalStatus methods in more OO way | 187 // XXX refactor checkLocalStatus methods in more OO way |
| 168 private void checkLocalStatusAgainstBaseRevision(Set<String> baseRevNames, ManifestRevisionInspector collect, int baseRevision, String fname, File f, StatusCollector.Inspector inspector) { | 188 private void checkLocalStatusAgainstBaseRevision(Set<String> baseRevNames, ManifestRevisionInspector collect, int baseRevision, String fname, File f, HgStatusInspector inspector) { |
| 169 // fname is in the dirstate, either Normal, Added, Removed or Merged | 189 // fname is in the dirstate, either Normal, Added, Removed or Merged |
| 170 Nodeid nid1 = collect.nodeid(fname); | 190 Nodeid nid1 = collect.nodeid(fname); |
| 171 String flags = collect.flags(fname); | 191 String flags = collect.flags(fname); |
| 172 HgDirstate.Record r; | 192 HgDirstate.Record r; |
| 173 if (nid1 == null) { | 193 if (nid1 == null) { |
| 175 // added: not known at the time of baseRevision, shall report | 195 // added: not known at the time of baseRevision, shall report |
| 176 // merged: was not known, report as added? | 196 // merged: was not known, report as added? |
| 177 if ((r = getDirstate().checkNormal(fname)) != null) { | 197 if ((r = getDirstate().checkNormal(fname)) != null) { |
| 178 String origin = StatusCollector.getOriginIfCopy(repo, fname, baseRevNames, baseRevision); | 198 String origin = StatusCollector.getOriginIfCopy(repo, fname, baseRevNames, baseRevision); |
| 179 if (origin != null) { | 199 if (origin != null) { |
| 180 inspector.copied(origin, fname); | 200 inspector.copied(getPathPool().path(origin), getPathPool().path(fname)); |
| 181 return; | 201 return; |
| 182 } | 202 } |
| 183 } else if ((r = getDirstate().checkAdded(fname)) != null) { | 203 } else if ((r = getDirstate().checkAdded(fname)) != null) { |
| 184 if (r.name2 != null && baseRevNames.contains(r.name2)) { | 204 if (r.name2 != null && baseRevNames.contains(r.name2)) { |
| 185 baseRevNames.remove(r.name2); // XXX surely I shall not report rename source as Removed? | 205 baseRevNames.remove(r.name2); // XXX surely I shall not report rename source as Removed? |
| 186 inspector.copied(r.name2, fname); | 206 inspector.copied(getPathPool().path(r.name2), getPathPool().path(fname)); |
| 187 return; | 207 return; |
| 188 } | 208 } |
| 189 // fall-through, report as added | 209 // fall-through, report as added |
| 190 } else if (getDirstate().checkRemoved(fname) != null) { | 210 } else if (getDirstate().checkRemoved(fname) != null) { |
| 191 // removed: removed file was not known at the time of baseRevision, and we should not report it as removed | 211 // removed: removed file was not known at the time of baseRevision, and we should not report it as removed |
| 192 return; | 212 return; |
| 193 } | 213 } |
| 194 inspector.added(fname); | 214 inspector.added(getPathPool().path(fname)); |
| 195 } else { | 215 } else { |
| 196 // was known; check whether clean or modified | 216 // was known; check whether clean or modified |
| 197 // when added - seems to be the case of a file added once again, hence need to check if content is different | 217 // when added - seems to be the case of a file added once again, hence need to check if content is different |
| 198 if ((r = getDirstate().checkNormal(fname)) != null || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) { | 218 if ((r = getDirstate().checkNormal(fname)) != null || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) { |
| 199 // either clean or modified | 219 // either clean or modified |
| 200 HgDataFile fileNode = repo.getFileNode(fname); | 220 HgDataFile fileNode = repo.getFileNode(fname); |
| 201 final int lengthAtRevision = fileNode.length(nid1); | 221 final int lengthAtRevision = fileNode.length(nid1); |
| 202 if (r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) { | 222 if (r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) { |
| 203 inspector.modified(fname); | 223 inspector.modified(getPathPool().path(fname)); |
| 204 } else { | 224 } else { |
| 205 // check actual content to see actual changes | 225 // check actual content to see actual changes |
| 206 // XXX consider adding HgDataDile.compare(File/byte[]/whatever) operation to optimize comparison | 226 // XXX consider adding HgDataDile.compare(File/byte[]/whatever) operation to optimize comparison |
| 207 if (areTheSame(f, fileNode.content(nid1))) { | 227 if (areTheSame(f, fileNode.content(nid1))) { |
| 208 inspector.clean(fname); | 228 inspector.clean(getPathPool().path(fname)); |
| 209 } else { | 229 } else { |
| 210 inspector.modified(fname); | 230 inspector.modified(getPathPool().path(fname)); |
| 211 } | 231 } |
| 212 } | 232 } |
| 213 } | 233 } |
| 214 // only those left in idsMap after processing are reported as removed | 234 // only those left in idsMap after processing are reported as removed |
| 215 } | 235 } |
