Mercurial > jhg
diff src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java @ 397:5e95b0da26f2 smartgit3
Issue 24: IAE, Underflow in FilterDataAccess. Issue 26:UnsupportedOperationException when patching empty base revision. Tests
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 23 Feb 2012 15:31:57 +0100 |
parents | 2fadf8695f8a |
children | 866fc3b597a0 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Tue Feb 21 19:18:40 2012 +0100 +++ b/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Thu Feb 23 15:31:57 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 TMate Software Ltd + * Copyright (c) 2011-2012 TMate Software Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,9 +30,9 @@ import java.util.Set; import java.util.TreeSet; -import org.tmatesoft.hg.core.HgBadStateException; import org.tmatesoft.hg.core.HgException; import org.tmatesoft.hg.core.HgInvalidControlFileException; +import org.tmatesoft.hg.core.HgInvalidFileException; import org.tmatesoft.hg.core.Nodeid; import org.tmatesoft.hg.internal.ByteArrayChannel; import org.tmatesoft.hg.internal.Experimental; @@ -291,22 +291,27 @@ } else if (!sizeEqual && r.size() >= 0) { inspector.modified(fname); } else { - // size is the same or unknown, and, perhaps, different timestamp - // check actual content to avoid false modified files - HgDataFile df = repo.getFileNode(fname); - if (!df.exists()) { - String msg = String.format("File %s known as normal in dirstate (%d, %d), doesn't exist at %s", fname, r.modificationTime(), r.size(), repo.getStoragePath(df)); - throw new HgBadStateException(msg); - } - Nodeid rev = getDirstateParentManifest().nodeid(fname); - // rev might be null here if fname comes to dirstate as a result of a merge operation - // where one of the parents (first parent) had no fname file, but second parent had. - // E.g. fork revision 3, revision 4 gets .hgtags, few modifications and merge(3,12) - // see Issue 14 for details - if (rev == null || !areTheSame(f, df, rev)) { - inspector.modified(df.getPath()); - } else { - inspector.clean(df.getPath()); + try { + // size is the same or unknown, and, perhaps, different timestamp + // check actual content to avoid false modified files + HgDataFile df = repo.getFileNode(fname); + if (!df.exists()) { + String msg = String.format("File %s known as normal in dirstate (%d, %d), doesn't exist at %s", fname, r.modificationTime(), r.size(), repo.getStoragePath(df)); + throw new HgInvalidFileException(msg, null).setFileName(fname); + } + Nodeid rev = getDirstateParentManifest().nodeid(fname); + // rev might be null here if fname comes to dirstate as a result of a merge operation + // where one of the parents (first parent) had no fname file, but second parent had. + // E.g. fork revision 3, revision 4 gets .hgtags, few modifications and merge(3,12) + // see Issue 14 for details + if (rev == null || !areTheSame(f, df, rev)) { + inspector.modified(df.getPath()); + } else { + inspector.clean(df.getPath()); + } + } catch (HgException ex) { + repo.getContext().getLog().warn(getClass(), ex, null); + inspector.invalid(fname, ex); } } } else if ((r = getDirstateImpl().checkAdded(fname)) != null) { @@ -383,14 +388,19 @@ // FALL THROUGH } if (r != null || (r = getDirstateImpl().checkMerged(fname)) != null || (r = getDirstateImpl().checkAdded(fname)) != null) { - // check actual content to see actual changes - // when added - seems to be the case of a file added once again, hence need to check if content is different - // either clean or modified - HgDataFile fileNode = repo.getFileNode(fname); - if (areTheSame(f, fileNode, nid1)) { - inspector.clean(fname); - } else { - inspector.modified(fname); + try { + // check actual content to see actual changes + // when added - seems to be the case of a file added once again, hence need to check if content is different + // either clean or modified + HgDataFile fileNode = repo.getFileNode(fname); + if (areTheSame(f, fileNode, nid1)) { + inspector.clean(fname); + } else { + inspector.modified(fname); + } + } catch (HgException ex) { + repo.getContext().getLog().warn(getClass(), ex, null); + inspector.invalid(fname, ex); } baseRevNames.remove(fname); // consumed, processed, handled. } else if (getDirstateImpl().checkRemoved(fname) != null) { @@ -409,10 +419,9 @@ // The question is whether original Hg treats this case (same content, different parents and hence nodeids) as 'modified' or 'clean' } - private boolean areTheSame(FileInfo f, HgDataFile dataFile, Nodeid revision) { + private boolean areTheSame(FileInfo f, HgDataFile dataFile, Nodeid revision) throws HgException { // XXX consider adding HgDataDile.compare(File/byte[]/whatever) operation to optimize comparison ByteArrayChannel bac = new ByteArrayChannel(); - boolean ioFailed = false; try { int fileRevisionIndex = dataFile.getRevisionIndex(revision); // need content with metadata striped off - although theoretically chances are metadata may be different, @@ -420,14 +429,11 @@ dataFile.content(fileRevisionIndex, bac); } catch (CancelledException ex) { // silently ignore - can't happen, ByteArrayChannel is not cancellable - } catch (HgException ex) { - repo.getContext().getLog().warn(getClass(), ex, null); - ioFailed = true; } - return !ioFailed && areTheSame(f, bac.toArray(), dataFile.getPath()); + return areTheSame(f, bac.toArray(), dataFile.getPath()); } - private boolean areTheSame(FileInfo f, final byte[] data, Path p) { + private boolean areTheSame(FileInfo f, final byte[] data, Path p) throws HgException { ReadableByteChannel is = null; class Check implements ByteChannel { final boolean debug = repo.getContext().getLog().isDebug(); @@ -498,7 +504,7 @@ repo.getContext().getLog().warn(getClass(), ex, "Unexpected cancellation"); return check.ultimatelyTheSame(); } catch (IOException ex) { - repo.getContext().getLog().warn(getClass(), ex, null); + throw new HgInvalidFileException("File comparison failed", ex).setFileName(p); } finally { if (is != null) { try { @@ -508,7 +514,6 @@ } } } - return false; } private static boolean todoCheckFlagsEqual(FileInfo f, HgManifest.Flags originalManifestFlags) {