<commit_before>let s:V = gita#vital()
let s:Prelude = s:V.import('Prelude')
let s:String = s:V.import('Data.String')
let s:Path = s:V.import('System.Filepath')
let s:Prompt = s:V.import('Vim.Prompt')
let s:Git = s:V.import('Git')
let s:GitInfo = s:V.import('Git.Info')
let s:GitTerm = s:V.import('Git.Term')

function! s:replace_filenames_in_diff(content, filename1, filename2, repl, ...) abort
  let is_windows = get(a:000, 0, s:Prelude.is_windows())
  " replace tempfile1/tempfile2 in the header to a:filename
  "
  "   diff --git a/<tempfile1> b/<tempfile2>
  "   index XXXXXXX..XXXXXXX XXXXXX
  "   --- a/<tempfile1>
  "   +++ b/<tempfile2>
  "
  let src1 = s:String.escape_pattern(a:filename1)
  let src2 = s:String.escape_pattern(a:filename2)
  if is_windows
    " NOTE:
    " '\' in {content} from 'git diff' are escaped so double escape is required
    " to substitute such path
    " NOTE:
    " escape(src1, '\') cannot be used while other characters such as '.' are
    " already escaped as well
    let src1 = substitute(src1, '\\\\', '\\\\\\\\', 'g')
    let src2 = substitute(src2, '\\\\', '\\\\\\\\', 'g')
  endif
  let repl = (a:filename1 =~# '^/' ? '/' : '') . a:repl
  let content = copy(a:content)
  let content[0] = substitute(content[0], src1, repl, '')
  let content[0] = substitute(content[0], src2, repl, '')
  let content[2] = substitute(content[2], src1, repl, '')
  let content[3] = substitute(content[3], src2, repl, '')
  return content
endfunction

function! s:get_diff_content(git, content, filename) abort
  let filename = gita#normalize#relpath(a:git, a:filename)
  let tempfile = tempname()
  let tempfile1 = tempfile . '.index'
  let tempfile2 = tempfile . '.buffer'
  try
    " save contents to temporary files
    let git = gita#core#get_or_fail()
    try
      let content = gita#process#execute(
            \ git,
            \ ['show', ':' . filename],
            \ { 'quiet': 1, 'encode_output': 0 }
            \).content
    catch /vital: Git.Process: Fail/
      " NOTE:
      " the content of filename does not exist
      let content = []
    endtry
    call writefile(content, tempfile1)
    call writefile(a:content, tempfile2)
    " create a diff content between index_content and content
    " NOTE:
    " --no-index force --exit-code option.
    " --exit-code mean that the program exits with 1 if there were differences
    " and 0 means no differences
    let content = gita#process#execute(
          \ git,
          \ ['diff', '--no-index', '--unified=1', '--', tempfile1, tempfile2],
          \ { 'quiet': 1, 'encode_output': 0, 'fail_silently': 1 }
          \).content
    if empty(content) || len(content) < 4
      " fail or no differences. Assume that there are no differences
      call s:Prompt.debug(content)
      call gita#throw('Attention: No differences are detected')
    endif
    return s:replace_filenames_in_diff(
          \ content,
          \ tempfile1,
          \ tempfile2,
          \ filename,
          \)
  finally
    call delete(tempfile1)
    call delete(tempfile2)
  endtry
endfunction

function! s:build_bufname(options) abort
  let options = extend({
        \ 'commit': '',
        \ 'filename': '',
        \ 'silent': 0,
        \ 'patch': 0,
        \ 'worktree': 0,
        \ 'ancestors': 0,
        \ 'ours': 0,
        \ 'theirs': 0,
        \}, a:options)
  if options.worktree
    let git = gita#core#get()
    let filename = gita#normalize#abspath(git, options.filename)
    if !filereadable(filename)
      call gita#throw(printf(
            \ 'A filename "%s" could not be found in the working tree',
            \ filename,
            \))
    endif
    return filename
  else
    let git = gita#core#get_or_fail()
    if options.ancestors || options.ours || options.theirs
      let treeish = printf(':%d:%s',
            \ options.ancestors ? 1 : options.ours ? 2 : 3,
            \ gita#normalize#relpath(git, options.filename),
            \)
    else
      let treeish = printf('%s:%s',
            \ options.commit,
            \ gita#normalize#relpath(git, options.filename),
            \)
    endif
    return gita#content#build_bufname('show', {
          \ 'extra_options': [
          \   options.silent ? 'silent': '',
          \   options.patch ? 'patch' : '',
          \ ],
          \ 'treeish': treeish,
          \})
  endif
endfunction

function! s:parse_bufname(bufinfo) abort
  let m = matchlist(a:bufinfo.treeish, '^\(\%(:[0-3]\)\?[^:]*\)\%(:\(.*\)\)\?$')
  if empty(m)
    call gita#throw(printf(
          \ 'A treeish part of a buffer name "%s" does not follow "%s" pattern',
          \ a:bufinfo.bufname, '<rev>:<filename> or :<n>:<filename>',
          \))
  endif
  let a:bufinfo.ancestors = m[1] =~# '^:1'
  let a:bufinfo.ours = m[1] =~# '^:2'
  let a:bufinfo.theirs = m[1] =~# '^:3'
  let a:bufinfo.commit = substitute(m[1], '^:\d\+', '', '')
  let a:bufinfo.filename = m[2]
  return a:bufinfo
endfunction

function! s:args_from_options(git, options) abort
  let options = extend({
        \ 'ancestors': 0,
        \ 'ours': 0,
        \ 'theirs': 0,
        \ 'commit': '',
        \ 'filename': '',
        \}, a:options)
  if options.ancestors || options.ours || options.theirs
    let treeish = printf(':%d:%s',
          \ options.ancestors ? 1 : options.ours ? 2 : 3,
          \ gita#normalize#relpath(a:git, options.filename),
          \)
  else
    let treeish = printf('%s:%s',
          \ gita#normalize#commit(a:git, options.commit),
          \ gita#normalize#relpath(a:git, options.filename),
          \)
  endif
  return ['show', treeish]
endfunction

function! s:execute_command(options) abort
  let git = gita#core#get_or_fail()
  let args = s:args_from_options(git, a:options)
  if get(a:options, 'silent')
    try
      return gita#process#execute(git, args, {
            \ 'quiet': 1,
            \ 'encode_output': 0,
            \}).content
    catch /vital: Git.Process: Fail/<commit_msg>Fix Gita show for repository<commit_after>let s:V = gita#vital()
let s:Prelude = s:V.import('Prelude')
let s:String = s:V.import('Data.String')
let s:Path = s:V.import('System.Filepath')
let s:Prompt = s:V.import('Vim.Prompt')
let s:Git = s:V.import('Git')
let s:GitInfo = s:V.import('Git.Info')
let s:GitTerm = s:V.import('Git.Term')

function! s:replace_filenames_in_diff(content, filename1, filename2, repl, ...) abort
  let is_windows = get(a:000, 0, s:Prelude.is_windows())
  " replace tempfile1/tempfile2 in the header to a:filename
  "
  "   diff --git a/<tempfile1> b/<tempfile2>
  "   index XXXXXXX..XXXXXXX XXXXXX
  "   --- a/<tempfile1>
  "   +++ b/<tempfile2>
  "
  let src1 = s:String.escape_pattern(a:filename1)
  let src2 = s:String.escape_pattern(a:filename2)
  if is_windows
    " NOTE:
    " '\' in {content} from 'git diff' are escaped so double escape is required
    " to substitute such path
    " NOTE:
    " escape(src1, '\') cannot be used while other characters such as '.' are
    " already escaped as well
    let src1 = substitute(src1, '\\\\', '\\\\\\\\', 'g')
    let src2 = substitute(src2, '\\\\', '\\\\\\\\', 'g')
  endif
  let repl = (a:filename1 =~# '^/' ? '/' : '') . a:repl
  let content = copy(a:content)
  let content[0] = substitute(content[0], src1, repl, '')
  let content[0] = substitute(content[0], src2, repl, '')
  let content[2] = substitute(content[2], src1, repl, '')
  let content[3] = substitute(content[3], src2, repl, '')
  return content
endfunction

function! s:get_diff_content(git, content, filename) abort
  let filename = gita#normalize#relpath(a:git, a:filename)
  let tempfile = tempname()
  let tempfile1 = tempfile . '.index'
  let tempfile2 = tempfile . '.buffer'
  try
    " save contents to temporary files
    let git = gita#core#get_or_fail()
    try
      let content = gita#process#execute(
            \ git,
            \ ['show', ':' . filename],
            \ { 'quiet': 1, 'encode_output': 0 }
            \).content
    catch /vital: Git.Process: Fail/
      " NOTE:
      " the content of filename does not exist
      let content = []
    endtry
    call writefile(content, tempfile1)
    call writefile(a:content, tempfile2)
    " create a diff content between index_content and content
    " NOTE:
    " --no-index force --exit-code option.
    " --exit-code mean that the program exits with 1 if there were differences
    " and 0 means no differences
    let content = gita#process#execute(
          \ git,
          \ ['diff', '--no-index', '--unified=1', '--', tempfile1, tempfile2],
          \ { 'quiet': 1, 'encode_output': 0, 'fail_silently': 1 }
          \).content
    if empty(content) || len(content) < 4
      " fail or no differences. Assume that there are no differences
      call s:Prompt.debug(content)
      call gita#throw('Attention: No differences are detected')
    endif
    return s:replace_filenames_in_diff(
          \ content,
          \ tempfile1,
          \ tempfile2,
          \ filename,
          \)
  finally
    call delete(tempfile1)
    call delete(tempfile2)
  endtry
endfunction

function! s:build_bufname(options) abort
  let options = extend({
        \ 'commit': '',
        \ 'filename': '',
        \ 'silent': 0,
        \ 'patch': 0,
        \ 'worktree': 0,
        \ 'ancestors': 0,
        \ 'ours': 0,
        \ 'theirs': 0,
        \}, a:options)
  if options.worktree
    let git = gita#core#get()
    let filename = gita#normalize#abspath(git, options.filename)
    if !filereadable(filename)
      call gita#throw(printf(
            \ 'A filename "%s" could not be found in the working tree',
            \ filename,
            \))
    endif
    return filename
  else
    let git = gita#core#get_or_fail()
    if options.ancestors || options.ours || options.theirs
      let treeish = printf(':%d:%s',
            \ options.ancestors ? 1 : options.ours ? 2 : 3,
            \ gita#normalize#relpath(git, options.filename),
            \)
    else
      let treeish = printf('%s:%s',
            \ options.commit,
            \ gita#normalize#relpath(git, options.filename),
            \)
    endif
    return gita#content#build_bufname('show', {
          \ 'extra_options': [
          \   options.silent ? 'silent': '',
          \   options.patch ? 'patch' : '',
          \ ],
          \ 'treeish': treeish,
          \})
  endif
endfunction

function! s:parse_bufname(bufinfo) abort
  let m = matchlist(a:bufinfo.treeish, '^\(\%(:[0-3]\)\?[^:]*\)\%(:\(.*\)\)\?$')
  if empty(m)
    call gita#throw(printf(
          \ 'A treeish part of a buffer name "%s" does not follow "%s" pattern',
          \ a:bufinfo.bufname, '<rev>:<filename> or :<n>:<filename>',
          \))
  endif
  let a:bufinfo.ancestors = m[1] =~# '^:1'
  let a:bufinfo.ours = m[1] =~# '^:2'
  let a:bufinfo.theirs = m[1] =~# '^:3'
  let a:bufinfo.commit = substitute(m[1], '^:\d\+', '', '')
  let a:bufinfo.filename = m[2]
  return a:bufinfo
endfunction

function! s:args_from_options(git, options) abort
  let options = extend({
        \ 'ancestors': 0,
        \ 'ours': 0,
        \ 'theirs': 0,
        \ 'commit': '',
        \ 'filename': '',
        \}, a:options)
  if options.ancestors || options.ours || options.theirs
    let treeish = printf(':%d:%s',
          \ options.ancestors ? 1 : options.ours ? 2 : 3,
          \ gita#normalize#relpath(a:git, options.filename),
          \)
  else
    let treeish = printf('%s:%s',
          \ gita#normalize#commit(a:git, options.commit),
          \ gita#normalize#relpath(a:git, options.filename),
          \)
  endif
  let treeish = empty(options.filename)
        \ ? substitute(treeish, ':$', '', '')
        \ : treeish
  return filter(['show', treeish], '!empty(v:val)')
endfunction

function! s:execute_command(options) abort
  let git = gita#core#get_or_fail()
  let args = s:args_from_options(git, a:options)
  if get(a:options, 'silent')
    try
      return gita#process#execute(git, args, {
            \ 'quiet': 1,
            \ 'encode_output': 0,
            \}).content
    catch /vital: Git.Process: Fail/
{'fraction_non_alphanumeric': 0.15972798142312158, 'fraction_numerical': 0.013269198872118096, 'mean_word_length': 2.420022688598979, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4126586', 'n_tokens_mistral': 4203, 'n_tokens_neox': 4083, 'n_words': 971}