Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java @ 117:6c0be854d149
Enable filters for status operation (ToRepo case)
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 04 Feb 2011 02:12:30 +0100 |
parents | a3a2e5deb320 |
children | b19f0ac5ee62 |
comparison
equal
deleted
inserted
replaced
116:5d13dcaaff39 | 117:6c0be854d149 |
---|---|
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 java.lang.Math.min; | |
19 import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION; | 20 import static org.tmatesoft.hg.repo.HgRepository.BAD_REVISION; |
20 import static org.tmatesoft.hg.repo.HgRepository.TIP; | 21 import static org.tmatesoft.hg.repo.HgRepository.TIP; |
21 | 22 |
22 import java.io.BufferedInputStream; | 23 import java.io.BufferedInputStream; |
23 import java.io.File; | 24 import java.io.File; |
24 import java.io.FileInputStream; | 25 import java.io.FileInputStream; |
25 import java.io.IOException; | 26 import java.io.IOException; |
27 import java.nio.ByteBuffer; | |
28 import java.nio.channels.FileChannel; | |
26 import java.util.Collections; | 29 import java.util.Collections; |
27 import java.util.Set; | 30 import java.util.Set; |
28 import java.util.TreeSet; | 31 import java.util.TreeSet; |
29 | 32 |
30 import org.tmatesoft.hg.core.Nodeid; | 33 import org.tmatesoft.hg.core.Nodeid; |
34 import org.tmatesoft.hg.core.Path; | |
35 import org.tmatesoft.hg.internal.ByteArrayChannel; | |
36 import org.tmatesoft.hg.internal.FilterByteChannel; | |
31 import org.tmatesoft.hg.repo.HgStatusCollector.ManifestRevisionInspector; | 37 import org.tmatesoft.hg.repo.HgStatusCollector.ManifestRevisionInspector; |
38 import org.tmatesoft.hg.util.ByteChannel; | |
32 import org.tmatesoft.hg.util.FileWalker; | 39 import org.tmatesoft.hg.util.FileWalker; |
33 import org.tmatesoft.hg.util.PathPool; | 40 import org.tmatesoft.hg.util.PathPool; |
34 import org.tmatesoft.hg.util.PathRewrite; | 41 import org.tmatesoft.hg.util.PathRewrite; |
35 | 42 |
36 /** | 43 /** |
222 if (r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) { | 229 if (r.size /* XXX File.length() ?! */ != lengthAtRevision || flags != todoGenerateFlags(fname /*java.io.File*/)) { |
223 inspector.modified(getPathPool().path(fname)); | 230 inspector.modified(getPathPool().path(fname)); |
224 } else { | 231 } else { |
225 // check actual content to see actual changes | 232 // check actual content to see actual changes |
226 // XXX consider adding HgDataDile.compare(File/byte[]/whatever) operation to optimize comparison | 233 // XXX consider adding HgDataDile.compare(File/byte[]/whatever) operation to optimize comparison |
227 if (areTheSame(f, fileNode.content(nid1))) { | 234 if (areTheSame(f, fileNode.content(nid1), fileNode.getPath())) { |
228 inspector.clean(getPathPool().path(fname)); | 235 inspector.clean(getPathPool().path(fname)); |
229 } else { | 236 } else { |
230 inspector.modified(getPathPool().path(fname)); | 237 inspector.modified(getPathPool().path(fname)); |
231 } | 238 } |
232 } | 239 } |
240 // changeset nodeid + hash(actual content) => entry (Nodeid) in the next Manifest | 247 // changeset nodeid + hash(actual content) => entry (Nodeid) in the next Manifest |
241 // 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). | 248 // 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). |
242 // The question is whether original Hg treats this case (same content, different parents and hence nodeids) as 'modified' or 'clean' | 249 // The question is whether original Hg treats this case (same content, different parents and hence nodeids) as 'modified' or 'clean' |
243 } | 250 } |
244 | 251 |
252 private boolean areTheSame(File f, final byte[] data, Path p) { | |
253 FileInputStream fis = null; | |
254 try { | |
255 try { | |
256 fis = new FileInputStream(f); | |
257 FileChannel fc = fis.getChannel(); | |
258 ByteBuffer fb = ByteBuffer.allocate(min(data.length, 8192)); | |
259 final boolean[] checkValue = new boolean[] { true }; | |
260 ByteChannel check = new ByteChannel() { | |
261 int x = 0; | |
262 public int write(ByteBuffer buffer) throws Exception { | |
263 for (int i = buffer.remaining(); i > 0; i--, x++) { | |
264 if (data[x] != buffer.get()) { | |
265 checkValue[0] = false; | |
266 break; | |
267 } | |
268 } | |
269 buffer.position(buffer.limit()); // mark as read | |
270 return buffer.limit(); | |
271 } | |
272 }; | |
273 FilterByteChannel filters = new FilterByteChannel(check, repo.getFiltersFromWorkingDirToRepo(p)); | |
274 while (fc.read(fb) != -1 && checkValue[0]) { | |
275 fb.flip(); | |
276 filters.write(fb); | |
277 fb.compact(); | |
278 } | |
279 return checkValue[0]; | |
280 } catch (IOException ex) { | |
281 if (fis != null) { | |
282 fis.close(); | |
283 } | |
284 ex.printStackTrace(); // log warn | |
285 } | |
286 } catch (/*TODO typed*/Exception ex) { | |
287 ex.printStackTrace(); | |
288 } | |
289 return false; | |
290 } | |
291 | |
245 private static String todoGenerateFlags(String fname) { | 292 private static String todoGenerateFlags(String fname) { |
246 // FIXME implement | 293 // FIXME implement |
247 return null; | 294 return null; |
248 } | 295 } |
249 private static boolean areTheSame(File f, byte[] data) { | |
250 try { | |
251 BufferedInputStream is = new BufferedInputStream(new FileInputStream(f)); | |
252 int i = 0; | |
253 while (i < data.length && data[i] == is.read()) { | |
254 i++; // increment only for successful match, otherwise won't tell last byte in data was the same as read from the stream | |
255 } | |
256 return i == data.length && is.read() == -1; // although data length is expected to be the same (see caller), check that we reached EOF, no more data left. | |
257 } catch (IOException ex) { | |
258 ex.printStackTrace(); // log warn | |
259 } | |
260 return false; | |
261 } | |
262 | 296 |
263 } | 297 } |