Skip to content

Crash on a particular file when used as git's external diff toolΒ #941

@KaappoRaivio

Description

@KaappoRaivio

Thanks for the awesome tool!!

(1) A description of the issue. A screenshot is often helpful too.
when running difftastic as an external diff tool of git, it panics on a changed file (with RUST_BACKTRACE=full):

$ git diff path/to/file.js
thread 'main' panicked at src/display/hunks.rs:517:17:
internal error: entered unreachable code: Should be impossible: every LHS Unchanged MatchedPos should have a corresponding RHS Unchanged MatchedPos
  None
  Some(MatchedPos { kind: UnchangedToken { highlight: Atom(Normal), self_pos: [SingleLineSpan { line: LineNumber: 89 (zero-indexed: 88), start_col: 27, end_col: 28 }], opposite_pos: [SingleLineSpan { line: LineNumber: 90 (zero-indexed: 89), start_col: 27, end_col: 28 }] }, pos: SingleLineSpan { line: LineNumber: 89 (zero-indexed: 88), start_col: 27, end_col: 28 } })
stack backtrace:
   0:        0x1045a93c0 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h2260af3a60e707d0
   1:        0x10441e708 - core::fmt::write::h40c2acd4666eb4d3
   2:        0x1045b5b1c - std::io::Write::write_fmt::h41d6e98dca6ecc3d
   3:        0x1045a9280 - std::sys::backtrace::BacktraceLock::print::h6927682eb47cb165
   4:        0x1045a07cc - std::panicking::default_hook::{{closure}}::h3800acb1d5aa9da8
   5:        0x1045a0674 - std::panicking::default_hook::hdb07ba29d8151fe7
   6:        0x1045a0dc4 - std::panicking::rust_panic_with_hook::h3a42c361c08813d5
   7:        0x1045a9df0 - std::panicking::begin_panic_handler::{{closure}}::h483101861bc4cead
   8:        0x1045a95fc - std::sys::backtrace::__rust_end_short_backtrace::he99aa938f9475e2a
   9:        0x1045a085c - _rust_begin_unwind
  10:        0x104cde848 - core::panicking::panic_fmt::h5a90ea35d2c8d236
  11:        0x10443b13c - difft::display::hunks::matched_pos_to_hunks::he238e1d80833a2db
  12:        0x104464c48 - difft::diff_file_content::h5d91f870f5122248
  13:        0x104463130 - difft::diff_file::hdb2ec1671155d295
  14:        0x1044622a4 - difft::main::hcf402fba38dc0b84
  15:        0x10449ca40 - std::sys::backtrace::__rust_begin_short_backtrace::hffeba46affa7e93f
  16:        0x10447e12c - std::rt::lang_start::{{closure}}::h3196f9eb4519e72f
  17:        0x104598dcc - std::rt::lang_start_internal::hadea728b8c40134b
  18:        0x104465bc4 - _main
fatal: external diff died, stopping at path/to/file.js

(2) A copy of what you're diffing. If you're diffing files, include the before and after files. If you're using difftastic with a VCS repository (e.g. git), include the URL and commit hash.

Due to NDA I unfortunately can't include the repo and commits (so feel free to close) but here's the diff using git's built-in diff tool:

`$ git diff --no-ext-diff path/to/file.js`
--- path/to/file.js
+++ path/to/file.js
@@ -7,9 +7,7 @@ import PrismicTypography from '../../prismic-typography';
 import Iconify from '../../../iconify';
 import Tag from './tag';
 
-const SuccessStory = ({
-  successStory: { featureImage, title, publishedAt, tags, description, url },
-}) => (
+const SuccessStory = ({ successStory: { featureImage, title, tags, description, url } }) => (
   <Link
     href={url}
     sx={{ color: 'text.primary' }}
@@ -17,7 +15,7 @@ const SuccessStory = ({
     target="_blank"
     rel="noopener noreferrer"
   >
-    <Stack gap={1.5} /* sx={{ gridTemplateRows: '2fr 2fr' }} */>
+    <Stack gap={1.5}>
       <Box
         bgcolor="background.neutral"
         sx={{ maxHeight: '100%', overflow: 'hidden', borderRadius: 1, height: '250px' }}
@@ -53,21 +51,22 @@ const SuccessStory = ({
         <Stack
           direction="row"
           gap={1}
-          // sx={{
-          // }}
+          sx={{
+            display: 'inline-flex',
+            width: 'fit-content',
+            borderBottom: '1px solid',
+            borderColor: 'text.primary',
+          }}
         >
           <Typography
             sx={{
-              display: 'inline-flex',
               fontWeight: 500,
               fontSize: { xs: '16px', md: '10px' },
-              borderBottom: '1px solid',
-              borderColor: 'text.primary',
             }}
           >
-            Read the case study&nbsp;
-            <Iconify icon="solar:arrow-right-outline" width={16} />
+            Read the case study
           </Typography>
+          <Iconify icon="solar:arrow-right-outline" width={16} />
         </Stack>
       </Stack>
     </Stack>

Here's the source itself:

path/to/file.js
import React from 'react';
import { Link, Box, Stack, Typography } from '@mui/material';

import { PrismicImage } from '@prismicio/react';
import PropTypes from 'prop-types';
import PrismicTypography from '../../prismic-typography';
import Iconify from '../../../iconify';
import Tag from './tag';

const SuccessStory = ({ successStory: { featureImage, title, tags, description, url } }) => (
  <Link
    href={url}
    sx={{ color: 'text.primary' }}
    underline="none"
    target="_blank"
    rel="noopener noreferrer"
  >
    <Stack gap={1.5}>
      <Box
        bgcolor="background.neutral"
        sx={{ maxHeight: '100%', overflow: 'hidden', borderRadius: 1, height: '250px' }}
      >
        <PrismicImage
          field={featureImage}
          style={{ borderRadius: '8px', objectFit: 'cover', height: '100%', maxHeight: '100%' }}
        />
      </Box>

      <Stack spacing={1.5}>
        <Stack direction="row" spacing={1.2}>
          {[...tags].map((tag) => (
            <Tag>{tag}</Tag>
          ))}
        </Stack>
        <PrismicTypography
          variant="subtitle1"
          component="h2"
          sx={{ fontSize: { xs: '24px', md: '20px' }, lineHeight: 1.4, fontWeight: 500 }}
        >
          {title}
        </PrismicTypography>
        <PrismicTypography
          variant="body2"
          sx={{
            fontSize: { xs: '16px', md: '12px' },
          }}
        >
          {description}
        </PrismicTypography>

        <Stack
          direction="row"
          gap={1}
          sx={{
            display: 'inline-flex',
            width: 'fit-content',
            borderBottom: '1px solid',
            borderColor: 'text.primary',
          }}
        >
          <Typography
            sx={{
              fontWeight: 500,
              fontSize: { xs: '16px', md: '10px' },
            }}
          >
            Read the case study
          </Typography>
          <Iconify icon="solar:arrow-right-outline" width={16} />
        </Stack>
      </Stack>
    </Stack>
  </Link>
);

export const SuccessStoryPropType = PropTypes.shape({
  title: PropTypes.string.isRequired,
  description: PropTypes.object.isRequired,
  featureImage: PropTypes.object.isRequired,
  url: PropTypes.string.isRequired,
  tags: PropTypes.arrayOf(PropTypes.string).isRequired,
  publishedAt: PropTypes.string.isRequired,
});

SuccessStory.propTypes = {
  successStory: SuccessStoryPropType,
};

export default SuccessStory;

prettier and eslint are happy, and the file works without issues in React

(3) The version of difftastic you're using (see difft --version) and your operating system.

$ difft --version
Difftastic 0.62.0

Toolchain: 1.83.0
System:    macos aarch64

edit: also repros on

$ difft --version
Difftastic 0.67.0

Toolchain: 1.91.1
System:    macos aarch64

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions