Mercurial > jhg
comparison src/com/tmate/hgkit/ll/LocalHgRepo.java @ 57:8b0d6f1bd6b4
Local status is back
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 17 Jan 2011 05:54:25 +0100 |
parents | 05829a70b30b |
children | 4cfc47bc14cc |
comparison
equal
deleted
inserted
replaced
56:576d6e8a09f6 | 57:8b0d6f1bd6b4 |
---|---|
9 import java.io.FileInputStream; | 9 import java.io.FileInputStream; |
10 import java.io.IOException; | 10 import java.io.IOException; |
11 import java.io.InputStreamReader; | 11 import java.io.InputStreamReader; |
12 import java.lang.ref.SoftReference; | 12 import java.lang.ref.SoftReference; |
13 import java.util.Arrays; | 13 import java.util.Arrays; |
14 import java.util.Collections; | |
14 import java.util.HashMap; | 15 import java.util.HashMap; |
15 import java.util.LinkedList; | 16 import java.util.LinkedList; |
17 import java.util.Set; | |
16 import java.util.TreeSet; | 18 import java.util.TreeSet; |
17 | 19 |
18 import com.tmate.hgkit.fs.DataAccessProvider; | 20 import com.tmate.hgkit.fs.DataAccessProvider; |
19 | 21 |
20 /** | 22 /** |
44 @Override | 46 @Override |
45 public String getLocation() { | 47 public String getLocation() { |
46 return repoLocation; | 48 return repoLocation; |
47 } | 49 } |
48 | 50 |
49 // public void statusLocal(int baseRevision, StatusCollector.Inspector inspector) { | 51 public void statusLocal(int baseRevision, StatusCollector.Inspector inspector) { |
50 // LinkedList<File> folders = new LinkedList<File>(); | 52 LinkedList<File> folders = new LinkedList<File>(); |
51 // final File rootDir = repoDir.getParentFile(); | 53 final File rootDir = repoDir.getParentFile(); |
52 // folders.add(rootDir); | 54 folders.add(rootDir); |
53 // final HgDirstate dirstate = loadDirstate(); | 55 final HgDirstate dirstate = loadDirstate(); |
54 // final HgIgnore hgignore = loadIgnore(); | 56 final HgIgnore hgignore = loadIgnore(); |
55 // TreeSet<String> knownEntries = dirstate.all(); | 57 TreeSet<String> knownEntries = dirstate.all(); |
56 // final boolean isTipBase = baseRevision == TIP || baseRevision == getManifest().getRevisionCount(); | 58 final boolean isTipBase = baseRevision == TIP || baseRevision == getManifest().getRevisionCount(); |
57 // final StatusCollector.ManifestRevisionInspector collect = isTipBase ? null : new StatusCollector.ManifestRevisionInspector(); | 59 StatusCollector.ManifestRevisionInspector collect = null; |
58 // if (!isTipBase) { | 60 Set<String> baseRevFiles = Collections.emptySet(); |
59 // getManifest().walk(baseRevision, baseRevision, collect); | 61 if (!isTipBase) { |
60 // } | 62 collect = new StatusCollector.ManifestRevisionInspector(baseRevision, baseRevision); |
61 // do { | 63 getManifest().walk(baseRevision, baseRevision, collect); |
62 // File d = folders.removeFirst(); | 64 baseRevFiles = new TreeSet<String>(collect.files(baseRevision)); |
63 // for (File f : d.listFiles()) { | 65 } |
64 // if (f.isDirectory()) { | 66 do { |
65 // if (!".hg".equals(f.getName())) { | 67 File d = folders.removeFirst(); |
66 // folders.addLast(f); | 68 for (File f : d.listFiles()) { |
67 // } | 69 if (f.isDirectory()) { |
68 // } else { | 70 if (!".hg".equals(f.getName())) { |
69 // // FIXME path relative to rootDir - need more robust approach | 71 folders.addLast(f); |
70 // String fname = normalize(f.getPath().substring(rootDir.getPath().length() + 1)); | 72 } |
71 // if (hgignore.isIgnored(fname)) { | 73 } else { |
72 // inspector.ignored(fname); | 74 // FIXME path relative to rootDir - need more robust approach |
73 // } else { | 75 String fname = normalize(f.getPath().substring(rootDir.getPath().length() + 1)); |
74 // if (knownEntries.remove(fname)) { | 76 if (hgignore.isIgnored(fname)) { |
75 // // modified, added, removed, clean | 77 inspector.ignored(fname); |
76 // if (collect != null) { // need to check against base revision, not FS file | 78 } else { |
77 // checkLocalStatusAgainstBaseRevision(collect, fname, f, dirstate, inspector); | 79 if (knownEntries.remove(fname)) { |
78 // } else { | 80 // modified, added, removed, clean |
79 // checkLocalStatusAgainstFile(fname, f, dirstate, inspector); | 81 if (collect != null) { // need to check against base revision, not FS file |
80 // } | 82 Nodeid nid1 = collect.nodeid(baseRevision, fname); |
81 // } else { | 83 String flags = collect.flags(baseRevision, fname); |
82 // inspector.unknown(fname); | 84 checkLocalStatusAgainstBaseRevision(baseRevFiles, nid1, flags, fname, f, dirstate, inspector); |
83 // } | 85 baseRevFiles.remove(fname); |
84 // } | 86 } else { |
85 // } | 87 checkLocalStatusAgainstFile(fname, f, dirstate, inspector); |
86 // } | 88 } |
87 // } while (!folders.isEmpty()); | 89 } else { |
88 // if (collect != null) { | 90 inspector.unknown(fname); |
89 // for (String r : collect.idsMap.keySet()) { | 91 } |
90 // inspector.removed(r); | 92 } |
91 // } | 93 } |
92 // } | 94 } |
93 // for (String m : knownEntries) { | 95 } while (!folders.isEmpty()); |
94 // // removed from the repository and missing from working dir shall not be reported as 'deleted' | 96 if (collect != null) { |
95 // if (dirstate.checkRemoved(m) == null) { | 97 for (String r : baseRevFiles) { |
96 // inspector.missing(m); | 98 inspector.removed(r); |
97 // } | 99 } |
98 // } | 100 } |
99 // } | 101 for (String m : knownEntries) { |
100 // | 102 // removed from the repository and missing from working dir shall not be reported as 'deleted' |
101 // private static void checkLocalStatusAgainstFile(String fname, File f, HgDirstate dirstate, StatusCollector.Inspector inspector) { | 103 if (dirstate.checkRemoved(m) == null) { |
102 // HgDirstate.Record r; | 104 inspector.missing(m); |
103 // if ((r = dirstate.checkNormal(fname)) != null) { | 105 } |
104 // // either clean or modified | 106 } |
105 // if (f.lastModified() / 1000 == r.time && r.size == f.length()) { | 107 } |
106 // inspector.clean(fname); | 108 |
107 // } else { | 109 private static void checkLocalStatusAgainstFile(String fname, File f, HgDirstate dirstate, StatusCollector.Inspector inspector) { |
108 // // FIXME check actual content to avoid false modified files | 110 HgDirstate.Record r; |
109 // inspector.modified(fname); | 111 if ((r = dirstate.checkNormal(fname)) != null) { |
110 // } | 112 // either clean or modified |
111 // } else if ((r = dirstate.checkAdded(fname)) != null) { | 113 if (f.lastModified() / 1000 == r.time && r.size == f.length()) { |
112 // if (r.name2 == null) { | 114 inspector.clean(fname); |
113 // inspector.added(fname); | 115 } else { |
114 // } else { | 116 // FIXME check actual content to avoid false modified files |
115 // inspector.copied(fname, r.name2); | 117 inspector.modified(fname); |
116 // } | 118 } |
117 // } else if ((r = dirstate.checkRemoved(fname)) != null) { | 119 } else if ((r = dirstate.checkAdded(fname)) != null) { |
118 // inspector.removed(fname); | 120 if (r.name2 == null) { |
119 // } else if ((r = dirstate.checkMerged(fname)) != null) { | 121 inspector.added(fname); |
120 // inspector.modified(fname); | 122 } else { |
121 // } | 123 inspector.copied(fname, r.name2); |
122 // } | 124 } |
123 // | 125 } else if ((r = dirstate.checkRemoved(fname)) != null) { |
124 // // XXX refactor checkLocalStatus methods in more OO way | 126 inspector.removed(fname); |
125 // private void checkLocalStatusAgainstBaseRevision(StatusCollector.ManifestRevisionInspector collect, String fname, File f, HgDirstate dirstate, StatusCollector.Inspector inspector) { | 127 } else if ((r = dirstate.checkMerged(fname)) != null) { |
126 // // fname is in the dirstate, either Normal, Added, Removed or Merged | 128 inspector.modified(fname); |
127 // Nodeid nid1 = collect.idsMap.remove(fname); | 129 } |
128 // String flags = collect.flagsMap.remove(fname); | 130 } |
129 // HgDirstate.Record r; | 131 |
130 // if (nid1 == null) { | 132 // XXX refactor checkLocalStatus methods in more OO way |
131 // // normal: added? | 133 private void checkLocalStatusAgainstBaseRevision(Set<String> baseRevNames, Nodeid nid1, String flags, String fname, File f, HgDirstate dirstate, StatusCollector.Inspector inspector) { |
132 // // added: not known at the time of baseRevision, shall report | 134 // fname is in the dirstate, either Normal, Added, Removed or Merged |
133 // // merged: was not known, report as added? | 135 HgDirstate.Record r; |
134 // if ((r = dirstate.checkAdded(fname)) != null) { | 136 if (nid1 == null) { |
135 // if (r.name2 != null && collect.idsMap.containsKey(r.name2)) { | 137 // normal: added? |
136 // collect.idsMap.remove(r.name2); | 138 // added: not known at the time of baseRevision, shall report |
137 // collect.idsMap.remove(r.name2); | 139 // merged: was not known, report as added? |
138 // inspector.copied(r.name2, fname); | 140 if ((r = dirstate.checkAdded(fname)) != null) { |
139 // return; | 141 if (r.name2 != null && baseRevNames.contains(r.name2)) { |
140 // } | 142 baseRevNames.remove(r.name2); |
141 // // fall-through, report as added | 143 inspector.copied(r.name2, fname); |
142 // } else if (dirstate.checkRemoved(fname) != null) { | 144 return; |
143 // // removed: removed file was not known at the time of baseRevision, and we should not report it as removed | 145 } |
144 // return; | 146 // fall-through, report as added |
145 // } | 147 } else if (dirstate.checkRemoved(fname) != null) { |
146 // inspector.added(fname); | 148 // removed: removed file was not known at the time of baseRevision, and we should not report it as removed |
147 // } else { | 149 return; |
148 // // was known; check whether clean or modified | 150 } |
149 // // when added - seems to be the case of a file added once again, hence need to check if content is different | 151 inspector.added(fname); |
150 // if ((r = dirstate.checkNormal(fname)) != null || (r = dirstate.checkMerged(fname)) != null || (r = dirstate.checkAdded(fname)) != null) { | 152 } else { |
151 // // either clean or modified | 153 // was known; check whether clean or modified |
152 // HgDataFile fileNode = getFileNode(fname); | 154 // when added - seems to be the case of a file added once again, hence need to check if content is different |
153 // final int lengthAtRevision = fileNode.length(nid1); | 155 if ((r = dirstate.checkNormal(fname)) != null || (r = dirstate.checkMerged(fname)) != null || (r = dirstate.checkAdded(fname)) != null) { |
154 // if (r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) { | 156 // either clean or modified |
155 // inspector.modified(fname); | 157 HgDataFile fileNode = getFileNode(fname); |
156 // } else { | 158 final int lengthAtRevision = fileNode.length(nid1); |
157 // // check actual content to see actual changes | 159 if (r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) { |
158 // // XXX consider adding HgDataDile.compare(File/byte[]/whatever) operation to optimize comparison | 160 inspector.modified(fname); |
159 // if (areTheSame(f, fileNode.content(nid1))) { | 161 } else { |
160 // inspector.clean(fname); | 162 // check actual content to see actual changes |
161 // } else { | 163 // XXX consider adding HgDataDile.compare(File/byte[]/whatever) operation to optimize comparison |
162 // inspector.modified(fname); | 164 if (areTheSame(f, fileNode.content(nid1))) { |
163 // } | 165 inspector.clean(fname); |
164 // } | 166 } else { |
165 // } | 167 inspector.modified(fname); |
166 // // only those left in idsMap after processing are reported as removed | 168 } |
167 // } | 169 } |
168 // | 170 } |
169 // // TODO think over if content comparison may be done more effectively by e.g. calculating nodeid for a local file and comparing it with nodeid from manifest | 171 // only those left in idsMap after processing are reported as removed |
170 // // we don't need to tell exact difference, hash should be enough to detect difference, and it doesn't involve reading historical file content, and it's relatively | 172 } |
171 // // cheap to calc hash on a file (no need to keep it completely in memory). OTOH, if I'm right that the next approach is used for nodeids: | 173 |
172 // // changeset nodeid + hash(actual content) => entry (Nodeid) in the next Manifest | 174 // TODO think over if content comparison may be done more effectively by e.g. calculating nodeid for a local file and comparing it with nodeid from manifest |
173 // // then it's sufficient to check parents from dirstate, and if they do not match parents from file's baseRevision (non matching parents means different nodeids). | 175 // we don't need to tell exact difference, hash should be enough to detect difference, and it doesn't involve reading historical file content, and it's relatively |
174 // // The question is whether original Hg treats this case (same content, different parents and hence nodeids) as 'modified' or 'clean' | 176 // cheap to calc hash on a file (no need to keep it completely in memory). OTOH, if I'm right that the next approach is used for nodeids: |
175 // } | 177 // changeset nodeid + hash(actual content) => entry (Nodeid) in the next Manifest |
178 // then it's sufficient to check parents from dirstate, and if they do not match parents from file's baseRevision (non matching parents means different nodeids). | |
179 // The question is whether original Hg treats this case (same content, different parents and hence nodeids) as 'modified' or 'clean' | |
180 } | |
176 | 181 |
177 private static String todoGenerateFlags(String fname) { | 182 private static String todoGenerateFlags(String fname) { |
178 // FIXME implement | 183 // FIXME implement |
179 return null; | 184 return null; |
180 } | 185 } |