Module: Canopus::Workspace::GitHistory

Defined in:
lib/canopus/workspace/git_history.rb

Defined Under Namespace

Classes: GitCommitEntry

Constant Summary collapse

MAX_COMMITS =
200
MAX_HISTORY_TREE_ENTRIES =
200_000
MAX_COMMIT_PATHS =
2_000

Instance Method Summary collapse

Instance Method Details

#close_git ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/canopus/workspace/git_history.rb', line 57

def close_git
  @git_commit_history_generation = (@git_commit_history_generation || 0) + 1
  jobs = [*@git_commit_history_jobs].compact.uniq.reject { |thread| thread.equal?(Thread.current) }
  deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 0.1
  jobs.each do |thread|
    remaining = deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC)
    break unless remaining.positive?
    thread.join(remaining)
  end
  jobs.each { |thread| thread.kill if thread.alive? }
  jobs.each(&:join)
  @git_commit_history_jobs&.clear
  super
end

#git_commit_history(revision: "HEAD", limit: 100) ⇒ Object

Raises:



11
12
13
14
15
16
17
18
19
20
# File 'lib/canopus/workspace/git_history.rb', line 11

def git_commit_history(revision: "HEAD", limit: 100)
  state = git_state
  raise Error, "Not a Git repository" unless state
  revision = validate_git_revision(revision)
  unless limit.is_a?(Integer) && limit.between?(1, MAX_COMMITS)
    raise ArgumentError, "history limit must be between 1 and #{MAX_COMMITS}"
  end

  state.synchronize { |repository| collect_git_commit_history(repository, revision, limit) }
end

#open_git_commit(entry) ⇒ Object

Raises:

  • (ArgumentError)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/canopus/workspace/git_history.rb', line 42

def open_git_commit(entry)
  raise ArgumentError, "expected a Git commit entry" unless entry.is_a?(GitCommitEntry)
  if entry.paths.empty?
    self.message = entry.paths_truncated ? "Changed paths omitted by the history budget" : "Commit has no file changes"
    return
  end
  return compare_git_revisions(entry.parents.first, entry.oid, path: entry.paths.first) if entry.paths.one?

  labels = entry.paths.map { |path| scm_display_path(path) }
  self.palette = {kind: :git_commit_paths, query: +"", index: 0, matches: labels,
    all_matches: labels, items: entry.paths, commit: entry}
  update_palette
  @palette
end

#show_git_commit_history(revision: "HEAD", limit: 100, async: !!@window)) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/canopus/workspace/git_history.rb', line 22

def show_git_commit_history(revision: "HEAD", limit: 100, async: !!@window)
  revision = validate_git_revision(revision)
  if @window && async
    generation = @git_commit_history_generation = (@git_commit_history_generation || 0) + 1
    palette_generation = @palette_generation.to_i
    self.message = "Loading Git history…"
    worker = Thread.new do
      current = Thread.current
      entries = git_commit_history(revision: revision, limit: limit)
      post { finish_git_commit_history(current, generation, palette_generation, entries, nil) } unless @closed
    rescue StandardError => error
      post { finish_git_commit_history(current, generation, palette_generation, nil, error) } unless @closed
    end
    (@git_commit_history_jobs ||= []) << worker
    return worker
  end

  install_git_commit_history(git_commit_history(revision: revision, limit: limit))
end