Class: Geet::Utils::GitClient

Inherits:
Object
  • Object
show all
Includes:
Helpers::OsHelper
Defined in:
lib/geet/utils/git_client.rb

Overview

Represents the git program interface; used for performing git operations.

Constant Summary collapse

ORIGIN_NAME =
'origin'
UPSTREAM_NAME =
'upstream'
REMOTE_ORIGIN_REGEX =

For simplicity, we match any character except the ones the separators.

%r{
  \A
  (?:https://(.+?)/|git@(.+?):)
  ([^/]+/.*?)
  (?:\.git)?
  \Z
}x
UPSTREAM_BRANCH_REGEX =
%r{\A[^/]+/([^/]+)\Z}
CLEAN_TREE_MESSAGE_REGEX =
/^nothing to commit, working tree clean$/

Instance Method Summary collapse

Methods included from Helpers::OsHelper

#execute_command, #open_file_with_default_application

Constructor Details

#initialize(location: nil) ⇒ GitClient

Returns a new instance of GitClient.



29
30
31
# File 'lib/geet/utils/git_client.rb', line 29

def initialize(location: nil)
  @location = location
end

Instance Method Details

#cherry(limit) ⇒ Object

Return the commit shas between HEAD and ‘limit`, excluding the already applied commits (which start with `-`)



40
41
42
43
44
# File 'lib/geet/utils/git_client.rb', line 40

def cherry(limit)
  raw_commits = execute_command("git #{gitdir_option} cherry #{limit.shellescape}")

  raw_commits.split("\n").grep(/^\+/).map { |line| line[3..-1] }
end

#current_branchObject



46
47
48
49
50
51
52
# File 'lib/geet/utils/git_client.rb', line 46

def current_branch
  branch = execute_command("git #{gitdir_option} rev-parse --abbrev-ref HEAD")

  raise "Couldn't find current branch" if branch == 'HEAD'

  branch
end

#path(upstream: false) ⇒ Object

Example: ‘donaldduck/geet`



92
93
94
95
96
# File 'lib/geet/utils/git_client.rb', line 92

def path(upstream: false)
  remote_name = upstream ? UPSTREAM_NAME : ORIGIN_NAME

  remote(remote_name)[REMOTE_ORIGIN_REGEX, 3]
end

#provider_domainObject



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/geet/utils/git_client.rb', line 98

def provider_domain
  # We assume that it's not possible to have origin and upstream on different providers.
  #
  remote_url = remote(ORIGIN_NAME)

  domain = remote_url[REMOTE_ORIGIN_REGEX, 1] || remote_url[REMOTE_ORIGIN_REGEX, 2]

  raise "Can't identify domain in the provider domain string: #{domain}" if domain !~ /(.*)\.\w+/

  domain
end

#push(upstream_branch: nil) ⇒ Object

upstream_branch: create an upstream branch.



143
144
145
146
147
# File 'lib/geet/utils/git_client.rb', line 143

def push(upstream_branch: nil)
  upstream_branch_option = "-u origin #{upstream_branch.shellescape}" if upstream_branch

  execute_command("git #{gitdir_option} push #{upstream_branch_option}")
end

#remote(name) ⇒ Object

Returns the URL of the remote with the given name. Sanity checks are performed.

The result is in the format ‘[email protected]:donaldduck/geet.git`



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/geet/utils/git_client.rb', line 115

def remote(name)
  remote_url = execute_command("git #{gitdir_option} ls-remote --get-url #{name}")

  if remote_url == name
    raise "Remote #{name.inspect} not found!"
  elsif remote_url !~ REMOTE_ORIGIN_REGEX
    raise "Unexpected remote reference format: #{remote_url.inspect}"
  end

  remote_url
end

#remote_defined?(name) ⇒ Boolean

Doesn’t sanity check for the remote url format; this action is for querying purposes, any any action that needs to work with the remote, uses #remote.

Returns:

  • (Boolean)


130
131
132
133
134
135
# File 'lib/geet/utils/git_client.rb', line 130

def remote_defined?(name)
  remote_url = execute_command("git #{gitdir_option} ls-remote --get-url #{name}")

  # If the remote is not define, `git ls-remote` will return the passed value.
  remote_url != name
end

#show_description(object) ⇒ Object

Show the description (“<subject>nn<body>”) for the given git object.



82
83
84
# File 'lib/geet/utils/git_client.rb', line 82

def show_description(object)
  execute_command("git #{gitdir_option} show --quiet --format='%s\n\n%b' #{object.shellescape}")
end

#upstream_branchObject

Not to be confused with ‘upstream` repository!

return: nil, if the upstream branch is not configured.



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/geet/utils/git_client.rb', line 58

def upstream_branch
  head_symbolic_ref = execute_command("git #{gitdir_option} symbolic-ref -q HEAD")

  raw_upstream_branch = execute_command("git #{gitdir_option} for-each-ref --format='%(upstream:short)' #{head_symbolic_ref.shellescape}").strip

  if raw_upstream_branch != ''
    raw_upstream_branch[UPSTREAM_BRANCH_REGEX, 1] || raise("Unexpected upstream format: #{raw_upstream_branch}")
  else
    nil
  end
end

#working_tree_clean?Boolean

Returns:

  • (Boolean)


70
71
72
73
74
# File 'lib/geet/utils/git_client.rb', line 70

def working_tree_clean?
  git_message = execute_command("git #{gitdir_option} status")

  !!(git_message =~ CLEAN_TREE_MESSAGE_REGEX)
end