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 }