Class: Releasinator::GitUtil

Inherits:
Object
  • Object
show all
Defined in:
lib/git_util.rb

Class Method Summary collapse

Class Method Details

.all_filesObject



24
25
26
27
# File 'lib/git_util.rb', line 24

def self.all_files()
  current_branch = get_current_branch()
  CommandProcessor.command("git ls-tree --name-only -r #{current_branch}")
end

.cachedObject



67
68
69
# File 'lib/git_util.rb', line 67

def self.cached
  CommandProcessor.command("git diff --cached")
end

.checkout(branch_name) ⇒ Object



89
90
91
92
93
# File 'lib/git_util.rb', line 89

def self.checkout(branch_name)
  if get_current_branch != branch_name
    CommandProcessor.command("git checkout #{branch_name}")
  end
end

.commit(message) ⇒ Object



186
187
188
# File 'lib/git_util.rb', line 186

def self.commit(message)
  CommandProcessor.command("git commit -m'#{message}'")
end

.commits(from_tag = nil, to_tag = "HEAD") ⇒ Object



194
195
196
197
198
199
200
201
202
# File 'lib/git_util.rb', line 194

def self.commits(from_tag=nil, to_tag="HEAD")
  rev = ""
  if from_tag
    rev = "#{from_tag}..#{to_tag}"
  end

  # Format: [short hash] [date] [commit message] ([author])
  CommandProcessor.command("git log #{rev} --pretty=format:'%h %ad%x20%s%x20%x28%an%x29' --date=short").split("\n").reverse!
end

.confirm_tag_overwrite(new_tag) ⇒ Object



95
96
97
98
99
100
101
102
# File 'lib/git_util.rb', line 95

def self.confirm_tag_overwrite(new_tag)
  tag_results = CommandProcessor.command('git tag -l')
  tag_results.split.each do |existing_tag|
    if existing_tag == new_tag
      Printer.check_proceed("Tag #{existing_tag} already present. Overwrite tag #{existing_tag}?", "Tag #{existing_tag} not overwritten.")
    end
  end
end

.delete_branch(branch_name) ⇒ Object



75
76
77
78
79
# File 'lib/git_util.rb', line 75

def self.delete_branch(branch_name)
  if has_branch? branch_name
    CommandProcessor.command("git branch -D #{branch_name}")
  end
end

.detached?Boolean

Returns:

  • (Boolean)


55
56
57
# File 'lib/git_util.rb', line 55

def self.detached?
  "" == CommandProcessor.command("git symbolic-ref --short -q HEAD | cat").strip
end

.diffObject



63
64
65
# File 'lib/git_util.rb', line 63

def self.diff
  CommandProcessor.command("git diff")
end

.exist?(path) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
21
22
# File 'lib/git_util.rb', line 18

def self.exist?(path)
  current_branch = get_current_branch()
  # grep is case sensitive, which is what we want.  Piped to cat so the grep error code is ignored.
  "" != CommandProcessor.command("git ls-tree --name-only -r #{current_branch} | grep ^#{path}$ | cat")
end

.fetchObject



14
15
16
# File 'lib/git_util.rb', line 14

def self.fetch()
  CommandProcessor.command("git fetch origin --prune --recurse-submodules -j9")
end

.get_current_branchObject



51
52
53
# File 'lib/git_util.rb', line 51

def self.get_current_branch
  CommandProcessor.command("git symbolic-ref --short HEAD").strip
end

.get_local_branch_sha1(branch_name) ⇒ Object



108
109
110
# File 'lib/git_util.rb', line 108

def self.get_local_branch_sha1(branch_name)
  rev_parse(branch_name)
end

.get_local_head_sha1Object



104
105
106
# File 'lib/git_util.rb', line 104

def self.get_local_head_sha1
  rev_parse("head")
end

.get_remote_branch_sha1(branch_name) ⇒ Object



112
113
114
# File 'lib/git_util.rb', line 112

def self.get_remote_branch_sha1(branch_name)
  rev_parse("origin/#{branch_name}")
end

.has_branch?(branch_name) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/git_util.rb', line 81

def self.has_branch?(branch_name)
  "" != CommandProcessor.command("git branch --list #{branch_name}").strip
end

.has_remote_branch?(branch_name) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/git_util.rb', line 85

def self.has_remote_branch?(branch_name)
  "" != CommandProcessor.command("git branch --list -r #{branch_name}").strip
end

.init_gh_pagesObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/git_util.rb', line 140

def self.init_gh_pages
  if !has_branch? "gh-pages"
    if has_remote_branch? "origin/gh-pages"
      checkout("gh-pages")
    else
      CommandProcessor.command("git checkout --orphan gh-pages")
      CommandProcessor.command("GLOBIGNORE='.git' git rm -rf *")
      #http://stackoverflow.com/questions/19363795/git-rm-doesnt-remove-all-files-in-one-go
      CommandProcessor.command("GLOBIGNORE='.git' git rm -rf *")
      CommandProcessor.command("touch README.md")
      CommandProcessor.command("git add .")
      CommandProcessor.command("git commit -am \"Initial gh-pages commit\"")
      CommandProcessor.command("git push -u origin gh-pages")
    end
  end
end

.is_ancestor?(root_branch, child_branch) ⇒ Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/git_util.rb', line 125

def self.is_ancestor?(root_branch, child_branch)
  "0" == CommandProcessor.command("git merge-base --is-ancestor #{root_branch} #{child_branch}; echo $?").strip
end

.is_clean_git?Boolean

Returns:

  • (Boolean)


46
47
48
49
# File 'lib/git_util.rb', line 46

def self.is_clean_git?
  any_changes = CommandProcessor.command("git status --porcelain")
  '' == any_changes
end

.move(old_path, new_path) ⇒ Object



29
30
31
32
# File 'lib/git_util.rb', line 29

def self.move(old_path, new_path)
  puts "Renaming #{old_path} to #{new_path}".yellow
  CommandProcessor.command("git mv -f #{old_path} #{new_path}")
end

.push_branch(branch_name) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/git_util.rb', line 34

def self.push_branch(branch_name)
  checkout(branch_name)
  fetch()
  # always merge to include any extra commits added during release process
  CommandProcessor.command("git merge origin/#{branch_name} --no-edit")
  CommandProcessor.command("git push origin #{branch_name}")
end

.push_tag(tag_name) ⇒ Object



42
43
44
# File 'lib/git_util.rb', line 42

def self.push_tag(tag_name)
  CommandProcessor.command("git push origin #{tag_name}")
end

.repo_urlObject



71
72
73
# File 'lib/git_util.rb', line 71

def self.repo_url
  CommandProcessor.command("git config --get remote.origin.url").strip
end

.reset_head(hard = false) ⇒ Object



190
191
192
# File 'lib/git_util.rb', line 190

def self.reset_head(hard=false)
  CommandProcessor.command("git reset#{' --hard' if hard} HEAD")
end

.reset_repo(branch_name) ⇒ Object



6
7
8
9
10
11
12
# File 'lib/git_util.rb', line 6

def self.reset_repo(branch_name)
  # resets the repo to a clean state
  checkout(branch_name)
  fetch()
  CommandProcessor.command("git reset --hard origin/#{branch_name}")
  CommandProcessor.command("git clean -x -d -f")
end

.rev_parse(branch_name) ⇒ Object



116
117
118
119
120
121
122
123
# File 'lib/git_util.rb', line 116

def self.rev_parse(branch_name)
  output = CommandProcessor.command("git rev-parse --verify #{branch_name} 2>&1 | cat").strip
  if output.include? 'fatal: Needed a single revision'
    puts "error: branch or commit '#{branch_name}' does not exist. You may need to checkout this branch.".red
    abort()
  end
  output
end

.stage(files = ".") ⇒ Object



182
183
184
# File 'lib/git_util.rb', line 182

def self.stage(files=".")
  CommandProcessor.command("git add #{files}")
end

.tag(new_tag, changelog) ⇒ Object



129
130
131
132
133
134
135
136
137
138
# File 'lib/git_util.rb', line 129

def self.tag(new_tag, changelog)
  confirm_tag_overwrite(new_tag)
  puts "tagging with changelog: \n\n#{changelog}\n".yellow
  changelog_tempfile = Tempfile.new("#{new_tag}.changelog")
  changelog_tempfile.write(changelog)
  changelog_tempfile.close
  # include changelog in annotated tag
  CommandProcessor.command("git tag -a -f #{new_tag} -F #{changelog_tempfile.path}")
  changelog_tempfile.unlink
end

.tagged_versions(remote = false, raw_tags = false) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/git_util.rb', line 167

def self.tagged_versions(remote=false, raw_tags=false)
  version_reg = Semantic::Version::SemVerRegexp
  tags = self.tags(remote)

  tags.select { |tag|
    tag = tag[1..tag.size] if tag.start_with? "v"
    tag =~ version_reg
  }.map { |tag|
    if !raw_tags and tag.start_with? "v"
      tag = tag[1..tag.size]
    end
    tag
  }.compact
end

.tags(remote = false) ⇒ Object



157
158
159
160
161
162
163
164
165
# File 'lib/git_util.rb', line 157

def self.tags(remote=false)
  if remote
    CommandProcessor.command("git ls-remote --tags").split("\n")
      .map { |tag| tag.split()[1].strip.gsub("refs/tags/", "") }
      .keep_if { |tag| !tag.include? "{}" }
  else
    CommandProcessor.command("git tag --list").split("\n")
  end
end

.untracked_filesObject



59
60
61
# File 'lib/git_util.rb', line 59

def self.untracked_files
  CommandProcessor.command("git ls-files --others --exclude-standard")
end