Class: Mbeditor::GitLineDiffService

Inherits:
Object
  • Object
show all
Includes:
GitService
Defined in:
app/services/mbeditor/git_line_diff_service.rb

Overview

Per-line git status for one file, for colouring the editor's line numbers.

Wraps git diff -U0 (working tree vs HEAD) and turns its hunk headers into line ranges in the current file:

{
"added"    => [{ "start" => 12, "end" => 14 }, ...],
"modified" => [{ "start" => 30, "end" => 30 }, ...],
"deleted"  => [{ "start" => 47, "end" => 47 }, ...],
"tracked"  => true
}

A deletion has no lines left to mark, so it is reported as the single line the removed content sat after — line 0 when the file's opening lines were the ones deleted, which the frontend renders above the first line.

An untracked file has no HEAD side at all, so every line counts as added.

Constant Summary collapse

HUNK_HEADER =

@@ -<old_start>[,<old_count>] +<new_start>[,<new_count>] @@

/\A@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/

Constants included from GitService

Mbeditor::GitService::SAFE_GIT_REF

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from GitService

ahead_behind, base_branch?, current_branch, find_branch_base, parse_git_log, parse_git_log_with_parents, parse_name_status, parse_numstat, parse_numstat_z, parse_porcelain_status, resolve_path, run_git, upstream_branch

Constructor Details

#initialize(repo_path:, file_path:) ⇒ GitLineDiffService

Returns a new instance of GitLineDiffService.



29
30
31
32
# File 'app/services/mbeditor/git_line_diff_service.rb', line 29

def initialize(repo_path:, file_path:)
  @repo_path = repo_path.to_s
  @file_path = file_path.to_s
end

Instance Attribute Details

#file_pathObject (readonly)

Returns the value of attribute file_path.



27
28
29
# File 'app/services/mbeditor/git_line_diff_service.rb', line 27

def file_path
  @file_path
end

#repo_pathObject (readonly)

Returns the value of attribute repo_path.



27
28
29
# File 'app/services/mbeditor/git_line_diff_service.rb', line 27

def repo_path
  @repo_path
end

Instance Method Details

#callObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'app/services/mbeditor/git_line_diff_service.rb', line 34

def call
  output, status = GitService.run_git(
    repo_path, "diff", "--no-color", "--no-ext-diff", "-U0", "HEAD", "--", file_path
  )

  # ls-files only distinguishes "no changes" from "never tracked", so it
  # runs solely when the diff produced nothing. Asking first doubled the
  # subprocess count on a path the editor polls every 10s.
  return untracked_result if (!status.success? || output.empty?) && untracked?

  # A non-zero status here means the diff could not be produced at all (no
  # HEAD yet, path outside the repo). Report a clean file rather than
  # raising: line colouring is decoration, never a reason to fail a load.
  return empty_result unless status.success?

  parse(output)
end