Skip to content

GitSigns: Script breaks when the first anchor line is too long for git diff output #14

@mihawk90

Description

@mihawk90

OK so I've been using this script for the last couple days with no issues (and it's been a great help), but yesterday I ran into a problem where it was convinced that I didn't save my file and/or I was opening the wrong file or.. whatever, anyway, it was throwing this in my face:

Diff didn't match the subtitles! Make sure to save your file.

However, I could see actual git diff output, so that wasn't the issue. This git diff command ran locally:

handle = io.popen("#{get_git()} -C \"#{dir}\" diff --raw -p \"#{ref}\" \"#{aegisub.file_name()}\"")

outputs this:

:100644 100644 7f46be0 0000000 M        433/[AntBnecn] Naruto Shippuuden - 433 [720p] [29377B9D].ass

diff --git a/433/[AntBnecn] Naruto Shippuuden - 433 [720p] [29377B9D].ass b/433/[AntBnecn] Naruto Shippuuden - 433 [720p] [29377B9D].ass
index 7f46be0..cf7f8ff 100644
--- a/433/[AntBnecn] Naruto Shippuuden - 433 [720p] [29377B9D].ass      
+++ b/433/[AntBnecn] Naruto Shippuuden - 433 [720p] [29377B9D].ass      
@@ -80,8 +80,8 @@ Comment: 1,0:01:11.08,0:01:12.07,ED35 Romaji3,,0,0,0,karaoke,{\fad(300,200)}{\k3
 Comment: 1,0:01:12.07,0:01:20.32,ED35 Romaji,,0,0,0,karaoke,{\fad(300,200)}{\k14}a{\k19}{\k24}o{\k19}zo{\k19}ra {\k19}no {\k19}ha{\k19}te {\k19}ma{\k168}de {\fad(300,200)}{\k19}to{\k19}ba{\k19}shi{\k44}te {\k34}yu{\k317}ke
 Dialogue: 0,0:00:04.00,0:00:05.96,Default,,0,0,0,,This...can't be.
 Dialogue: 0,0:00:06.50,0:00:07.87,Default,,0,0,0,,What is happening?!
-Dialogue: 0,0:01:04.12,0:01:05.33,Default,,0,0,0,,{\i1}Right around then,{\i0}
-Dialogue: 0,0:01:05.46,0:01:08.16,Default,,0,0,0,,{\i1}the young shinobi{\i0} {\i1}who just became genin,{\i0}
+Dialogue: 0,0:01:04.12,0:01:05.45,Default,,0,0,0,,{\i1}Right around then,{\i0}
+Dialogue: 0,0:01:05.45,0:01:08.16,Default,,0,0,0,,{\i1}the young shinobi{\i0} {\i1}who just became genin,{\i0}
 Dialogue: 0,0:01:08.87,0:01:13.16,Default,,0,0,0,,{\i1}made their way to a village{\i0} {\i1}that had lost their Jōnin.{\i0}
 Dialogue: 0,0:01:14.83,0:01:19.62,Default,,0,0,0,,{\i1}Amongst them was{\i0} {\i1}the Child of Prophecy...Naruto.{\i0}
 Dialogue: 1,0:01:37.32,0:01:47.92,OP18 Eng,,0,0,0,,{\blur0.5}Throwing out a single excuse that, "It's finally nice outside!"
@@ -92,282 +92,282 @@ Dialogue: 1,0:01:59.55,0:02:10.15,OP18 Eng,,0,0,0,,{\blur0.5}My destination is s
…

Luckily that error message is only output in one place:

if offset == nil
aegisub.log("Diff didn't match the subtitles! Make sure to save your file.\n")
aegisub.cancel()

And so I went ahead and added some debug output:

--- arch.GitSigns.moon.orig     2025-07-06 19:18:53.608717043 +0200
+++ arch.GitSigns.moon  2025-07-06 19:19:29.782803540 +0200
@@ -125,13 +125,22 @@
 
     local offset
     for i, section in ipairs(sections)
+        aegisub.debug.out("section for loop #{i}\n")
         for {:newindex, :gline} in *iterate_diff_section(section.lines)
+            aegisub.debug.out('newindex for loop\n')
             if newindex > 1 and gline\match("^%+?Dialogue: ") or gline\match("^%+?Comment: ")
+                aegisub.debug.out('newindex > 1\n')
                 rl = gline\gsub("^%+", "")\gsub("\r$", "")
 
                 aegisub.log(5, "Trying to find anchor line #{gl}\n")
 
                 for si, s in ipairs(subs)
+                    aegisub.debug.out("subs for loop #{si}\n")
+                    aegisub.debug.out("s.raw: #{s.raw}\n")
+                    aegisub.debug.out("rl: #{rl}\n")
+                    aegisub.debug.out("section.newfrom: #{section.newfrom}\n")
+                    aegisub.debug.out("newindex: #{newindex}\n")
+
                     if s.raw == rl
                         offset = si - (section.newfrom + newindex - 1)
                         aegisub.log(5, "Found offset #{offset}")

Sifting through the output I eventually found the right line that would have to match:

section.newfrom: 80
newindex: 1
subs for loop 72
s.raw: Comment: 1,0:01:11.08,0:01:12.07,ED35 Romaji3,,0,0,0,karaoke,{\fad(300,200)}{\k39}GO {\k49}GO
rl: Comment: 1,0:01:11.08,0:01:12.07,ED35 Romaji3,,0,0,0,karaoke,{\fad(300,200)}{\k3

So the problem seems to be that the condition on L135 here fails:

for si, s in ipairs(subs)
if s.raw == rl
offset = si - (section.newfrom + newindex - 1)
aegisub.log(5, "Found offset #{offset}")
break

Which makes sense because git diff shortens the line, so it's not == the original line.

I'm not entirely sure how to work around this though. Of course string.find() is an option but I see a problem there when only later parts of the line (after git's cut-off) differ.

In the git man page I can't find any way to turn this shortening behaviour off. Even the --word-diff=porcelain still does this :/
So I think the only way to do this would be doing string.find() to find the anchor/offset, but then also check each individual removed line on whether or not it matches the lines in the script :/

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions