From 9844bbb4f9a7791cdd93d2479a99ee93dc6c831d Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 22 Jun 2011 16:12:09 -0700 Subject: [PATCH] Don't use the "ignore all whitespace" algorithm on multi-hunk diffs Summary: Diffs with missing context don't render properly in the "ignore all whitespace" algorith, so don't try to use it. These diffs can occur if someone creates a diff via the web interface, for example, or if they muck around in their copy of 'arc'. See D473, T246 (a problem with D473), rPe5bb756b5191720 (revert of D473) and T231. Test Plan: Viewed a diff with missing context from the web interface. Verified normal diffs still rendered with all whitespace ignored. Reviewed By: fratrik Reviewers: jungejason, aran, tuomaspelkonen, fratrik Commenters: jungejason CC: aran, epriestley, fratrik, jungejason Differential Revision: 500 --- .../changeset/DifferentialChangesetParser.php | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/applications/differential/parser/changeset/DifferentialChangesetParser.php b/src/applications/differential/parser/changeset/DifferentialChangesetParser.php index 67ecbfc556..de48e8e970 100644 --- a/src/applications/differential/parser/changeset/DifferentialChangesetParser.php +++ b/src/applications/differential/parser/changeset/DifferentialChangesetParser.php @@ -745,7 +745,25 @@ class DifferentialChangesetParser { if ($changeset->getFileType() == DifferentialChangeType::FILE_TEXT || $changeset->getFileType() == DifferentialChangeType::FILE_SYMLINK) { if ($skip_cache || !$this->loadCache()) { - if ($this->whitespaceMode == self::WHITESPACE_IGNORE_ALL) { + + // The "ignore all whitespace" algorithm depends on rediffing the + // files, and we currently need complete representations of both + // files to do anything reasonable. If we only have parts of the files, + // don't use the "ignore all" algorithm. + $can_use_ignore_all = true; + $hunks = $changeset->getHunks(); + if (count($hunks) !== 1) { + $can_use_ignore_all = false; + } else { + $first_hunk = reset($hunks); + if ($first_hunk->getOldOffset() != 1 || + $first_hunk->getNewOffset() != 1) { + $can_use_ignore_all = false; + } + } + + if ($this->whitespaceMode == self::WHITESPACE_IGNORE_ALL && + $can_use_ignore_all) { // Huge mess. Generate a "-bw" (ignore all whitespace changes) diff, // parse it out, and then play a shell game with the parsed format