Hi,

Perhaps something like the attached patch can be used?

// Erik

On 13 February 2017 at 10:38, Erik Johansson <[email protected]> wrote:

> Hi,
>
> If one posts a review containing a removed symlink you get "There was an
> error displaying this diff." when looking at the diff view. This is with
> reviewboard 2.5.8 and a git repository.
>
> The attached patch reproduces the problem in a unit test. Let me know if
> you need any more info.
>
> Also, it seems like the tags for the just released reviewboard versions
> aren't pushed to github.
>
> // Erik
>
> --
> Erik Johansson
> Home Page: http://ejohansson.se/
> PGP Key: http://ejohansson.se/erik.asc
>



-- 
Erik Johansson
Home Page: http://ejohansson.se/
PGP Key: http://ejohansson.se/erik.asc

-- 
Supercharge your Review Board with Power Pack: 
https://www.reviewboard.org/powerpack/
Want us to host Review Board for you? Check out RBCommons: 
https://rbcommons.com/
Happy user? Let us know! https://www.reviewboard.org/users/
--- 
You received this message because you are subscribed to the Google Groups 
"reviewboard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/reviewboard/scmtools/git.py b/reviewboard/scmtools/git.py
index e76f0cc..8a955cf 100644
--- a/reviewboard/scmtools/git.py
+++ b/reviewboard/scmtools/git.py
@@ -4,6 +4,7 @@ import logging
 import os
 import re
 import platform
+import stat
 
 from django.utils import six
 from django.utils.six.moves.urllib.parse import (quote as urlquote,
@@ -101,6 +102,24 @@ class GitTool(SCMTool):
         except (FileNotFoundError, InvalidRevisionFormatError):
             return False
 
+    def normalize_patch(self, patch, filename, revision):
+        """
+        Make new and deleted symlinks look like regular files.
+
+        Otherwise patch fails to apply the diff, complaining about the file not
+        being a symlink.
+        """
+        match = GitDiffParser.NEW_DELETED_FILE_MODE_REGEXP.search(patch)
+        if not match:
+            return patch
+
+        mode = int(match.group(1), 8)
+        if not stat.S_ISLNK(mode):
+            return patch
+
+        mode = stat.S_IFREG | stat.S_IMODE(mode)
+        return patch[:match.start(1)] + (b"%o" % mode) + patch[match.end(1):]
+
     def parse_diff_revision(self, file_str, revision_str, moved=False,
                             copied=False, *args, **kwargs):
         revision = revision_str
@@ -150,6 +169,9 @@ class GitDiffParser(DiffParser):
     """
     pre_creation_regexp = re.compile(b"^0+$")
 
+    NEW_DELETED_FILE_MODE_REGEXP = \
+        re.compile(b'^(?:new|deleted) file mode (\d+)$', re.M)
+
     DIFF_GIT_LINE_RES = [
         # Match with a/ and b/ prefixes. Common case.
         re.compile(

Reply via email to