git_helpers 0.1.0 → 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89d50a9fc84a8451a75811aed19d8d5763114dbddda62abb44a2f32ee9784b60
4
- data.tar.gz: 2cec1efd8ac009542d1cc883dc94c8f56b2f0326434cbbea8e59a916b03eb6a0
3
+ metadata.gz: 7dff08d8485cf3609ef9a5c6a2d536f2b0536a32a310aaebfd526dbad0906f54
4
+ data.tar.gz: 69a45f7f856411b80b44d998725c31022dbdf3721afce6034be8560e696eddb1
5
5
  SHA512:
6
- metadata.gz: f4a638373b1051726dab1a69543347cea204aa63b3241499d911485f3448b65da34c7f6a42b5934b7e63bdd80dfa06e1f949de007cefca932db57d679dfb05b9
7
- data.tar.gz: 24577fa3a75b6a422bbb584a95519d9c269261161919e36c7e98f8d6b390541922d2775e00b796a3b0d7d99532052c598064fd7113c64c4730e4168cf9811f0b
6
+ metadata.gz: 98f579ba175ca949eadeab277fac7d115f6c6ec758e2497cba64ba26ce3490cfabd5116ea03a8b2041faa55bf3639ffa53e76e3e888a02b7ed797b5dd71ae25a
7
+ data.tar.gz: 12f6d9ea6bad79977fd4a40eef28a2dd81d811bb7669493fa8b0a4d704736f912d4a8e4f91e669b12327ee236c2cd85770e9fc6ef833e5d8a5eae54ecb9a1491
@@ -1,4 +1,101 @@
1
- ### 0.1.0 / 2016-06-03
1
+ == Release v0.2 (2020-02-18) ==
2
2
 
3
- * Initial release:
3
+ * Bump version
4
+ * Copyright
5
+ * sumdate is now a standard git format proposal (cf the ml)
6
+ * Small bugfixes
7
+ * Fixes for ruby 2.7 warnings
8
+ * branch_infos: better log options handling
9
+ * branch_infos: show logs
10
+ * branch_infos.rb: rework case @{u}=@{push}
11
+ * format_branch_infos: show when @{push}=@{u}
12
+ * branch: warn if upstream is nil
13
+ * Add todo
14
+ * status.rb: deleted or type change for submodules
15
+ * rescue if the dir does not exist
16
+ * Activate GIT_OPTIONAL_CLOCKS
17
+ * submodule: recursive foreach
18
+ * submodules foreach
19
+ * status.rb: show when status is shortened
20
+ * Update Rakefile
21
+ * Update Rakefile
22
+ * Bug fixes
23
+ * status.rb: more infos in sequencer
24
+ * status: max_length
25
+ * gitstatus: sequencer formatting
26
+ * status: extra infos optional in sequencer
27
+ * name: can specify several methods
28
+ * sequencer: show onto
29
+ * detached_infos
30
+ * Bug fixes
31
+ * sequencer
32
+ * branch#full_name
33
+ * detached infos
34
+ * branch_infos: cherry log
35
+ * status: Show submodules commited vs submodules changed
36
+ * infos: detached_name
37
+ * status.rb: ignored symbol
38
+ * Bug fix
39
+ * gitstatus.rb: more options
40
+ * status: full branch infos
41
+ * status.rb: branch infos
42
+ * gitstatus.rb options
43
+ * Branch#checkout
44
+ * recursive_upstream
45
+ * status: add 'T' type (= type change)
46
+ * diff-fancy.rb: integrate as library
47
+ * Fix --prompt
48
+ * Move gitstatus2.rb to gitstatus.rb
49
+ * gitstatus2: more options
50
+ * status: only show in a git repo
51
+ * Sequencer status
52
+ * status: minimal status when not in worktree
53
+ * status when not in a worktree
54
+ * More wrapping into run_simple
55
+ * Use run helpers
56
+ * git_helpers: reset cache and run wrappers
57
+ * sequencer: read extra informations
58
+ * branch: raw calls
59
+ * git_dir: use rev-parse to get all infos at once
60
+ * git_helpers.rb: split into multiple files
61
+ * sequencer + stash infos
62
+ * gitstatus2: bug fixes
63
+ * New version of gitstatus.rb
64
+ * git: status
65
+ * git_helpers.rb: status
66
+ * format_branch_infos
67
+ * branch infos: upstream and push branch names
68
+
69
+ == Release v0.1.0 (2019-04-08) ==
70
+
71
+ * branch infos
72
+ * extra_helpers: now can handle a repository
73
+ * extra_helpers: force --no-pager
74
+ * Add extra branch and stats helpers
75
+ * Bug fixes
76
+ * Add #head
77
+ * Import git_helpers from drain and improve the api
78
+ * Desactivate pattern for now
79
+ * diff-fancy: add default patterns to less
80
+ * Last commit checked date
81
+ * Readme + Commits checked
82
+ * GitDiff.output as a convenience class method
83
+ * Fix gemspec
84
+ * Add git versions in Gemfile
85
+ * Add .travis.yml
86
+ * Update gemspec
87
+ * Streamline rake and test files
88
+ * Copyright
89
+ * TODO--
90
+ * Update README
91
+ * gitstatus: check if folder exists
92
+ * Also handle the case of a binary removal
93
+ * Clean up 'binary file differ' in file creation
94
+ * Set default column to 80 if `tput col` fails
95
+ * scrub non utf-8 strings
96
+ * Better detection of submoldules boundaries
97
+ * diff-fancy: can specify diff-highlight location through an ENV variable
98
+ * Add standalone executables
99
+ * Copyright
100
+ * Initial commit.
4
101
 
@@ -1,4 +1,4 @@
1
- Copyright © 2016–2017 Damien Robert
1
+ Copyright © 2016–2020 Damien Robert
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,15 +1,5 @@
1
1
  require 'rake'
2
2
 
3
- begin
4
- require 'rubygems/tasks'
5
- Gem::Tasks.new(sign: {checksum: true, pgp: true},
6
- scm: {status: true}) do |tasks|
7
- tasks.console.command = 'pry'
8
- end
9
- rescue LoadError => e
10
- warn e.message
11
- end
12
-
13
3
  require 'rake/testtask'
14
4
  Rake::TestTask.new do |test|
15
5
  test.libs << 'test'
@@ -27,3 +17,10 @@ rescue LoadError => e
27
17
  end
28
18
  task :doc => :yard
29
19
 
20
+ begin
21
+ require 'dr/rake_gems'
22
+ Gem::MyTasks.new
23
+ rescue LoadError => e
24
+ warn e.message
25
+ end
26
+
@@ -0,0 +1 @@
1
+ ../lib/git_helpers/diff.rb
@@ -0,0 +1,349 @@
1
+ #!/usr/bin/env ruby
2
+ # Inspired by https://github.com/olivierverdier/zsh-git-prompt
3
+ # [commit: 350be32093d0585f395413253536d891c247f538,
4
+ # last commit checked: 0a6c8b610e799040b612db8888945f502a2ddd9d (2016-02-14)]
5
+ #Inspired by the contrib git script
6
+
7
+ require "open3"
8
+ require "pathname"
9
+ require "shellwords"
10
+ require "optparse"
11
+ require "simplecolor"
12
+ #require "dr/git" #TODO merge the two implems
13
+ SimpleColor.mix_in_string
14
+
15
+ module GitStatus
16
+ module Run
17
+ extend(self)
18
+ #if we get interrupted once, we don't want to launch any more commands
19
+ @interrupted=false
20
+ def runstatus(*args)
21
+ if !@interrupted
22
+ begin
23
+ if Open3.respond_to?(:capture3) then
24
+ out, error, status=Open3.capture3(*args)
25
+ return out, status.success?
26
+ else
27
+ out = `#{args} 2>/dev/null`
28
+ status=$?
29
+ return out, status.success?
30
+ end
31
+ rescue Interrupt #interruption
32
+ @interrupted=true
33
+ return "", false
34
+ end
35
+ else
36
+ return "", false
37
+ end
38
+ end
39
+ def run(*args)
40
+ msg,_=runstatus(*args)
41
+ return msg
42
+ end
43
+ end
44
+
45
+ class Git
46
+ include GitStatus::Run
47
+ attr_reader :msg
48
+
49
+ def git?
50
+ if @git.nil?
51
+ _,@git=runstatus "git rev-parse"
52
+ end
53
+ return @git
54
+ end
55
+ def getgitdir
56
+ return Pathname.new((run "git rev-parse --git-dir").chomp)
57
+ end
58
+ def ingitdir?
59
+ return (run "git rev-parse --is-inside-git-dir") == "true\n"
60
+ end
61
+ def worktree?
62
+ return (run "git rev-parse --is-inside-work-tree") == "true\n"
63
+ end
64
+ def bare?
65
+ return (run "git rev-parse --is-bare-repository") == "true\n"
66
+ end
67
+
68
+ def cd_and_exec(*args)
69
+ if @path.nil? then
70
+ yield(*args)
71
+ else
72
+ if File.directory?(@path)
73
+ Dir.chdir(@path) do
74
+ yield(*args)
75
+ end
76
+ else
77
+ warn "#{@path} is not a directory"
78
+ end
79
+ end
80
+ end
81
+
82
+ def initialize(path=nil)
83
+ #a nil path means we want information on the current directory
84
+ if !path.nil?
85
+ @path=Pathname.new(path).expand_path
86
+ end
87
+ cd_and_exec {git?}
88
+ end
89
+
90
+ def get_msg
91
+ #gitst="git status --porcelain --branch"
92
+ #too many git are too old to mix --porcelain with --branch
93
+ gitm=git="git"
94
+ gitm="#{git} -c color.ui=always" if $opts[:color]
95
+ gitm="#{gitm} status --short --branch"
96
+ @msg=run(gitm)
97
+ end
98
+
99
+ def describe_detached_head
100
+ case $opts[:describe]
101
+ when "sha1"
102
+ describe=(run "git rev-parse --short HEAD").chomp
103
+ when "describe"
104
+ describe=(run "git describe HEAD").chomp
105
+ when "contains"
106
+ describe=(run "git describe --contains HEAD").chomp
107
+ when "branch"
108
+ describe=(run "git describe --contains --all HEAD").chomp
109
+ when "match"
110
+ describe=(run "git describe --tags --exact-match HEAD").chomp
111
+ when "all" #try --contains all, then --all
112
+ describe=(run "git describe --contains --all HEAD").chomp
113
+ describe=(run "git describe --all HEAD").chomp if describe.nil? or describe.empty?
114
+ when "magic"
115
+ describe1=(run "git describe --contains --all HEAD").chomp
116
+ describe2=(run "git describe --all HEAD").chomp
117
+ describe= describe1.length < describe2.length ? describe1 : describe2
118
+ describe=describe1 if describe2.empty?
119
+ describe=describe2 if describe1.empty?
120
+ else
121
+ describe=(run($opts[:describe])).chomp
122
+ end
123
+ if describe.empty?
124
+ describe=(run "git rev-parse --short HEAD").chomp
125
+ end
126
+ @branch=":#{describe}"
127
+ end
128
+
129
+ def parse_head(head)
130
+ @ahead=@behind=0
131
+ if (head =~ /## Initial commit on (\S*)/) then
132
+ @branch=$1
133
+ if @branch =~ /(\S*)\.\.\./
134
+ @branch=$1
135
+ end
136
+ @branch+="…"
137
+ elsif (head =~ /## (\S*) \(no branch\)/) then
138
+ describe_detached_head
139
+ elsif (head =~ /## (\S*)(.*)/) then
140
+ branchs=$1
141
+ rest=$2
142
+ if (branchs =~ /(\S*)\.\.\.(\S*)/) then
143
+ @branch=$1
144
+ remote=$2
145
+ else
146
+ @branch=branchs
147
+ end
148
+ if (rest =~ /.*\[ahead\s+(\d*)(.*)/) then
149
+ @ahead=$1.to_i
150
+ rest=$2
151
+ end
152
+ if (rest =~ /.*behind\s+(\d*)\]/) then
153
+ @behind=$1.to_i
154
+ end
155
+ end
156
+ end
157
+
158
+ def parse_msg
159
+ msg=@msg
160
+ #find the branch name, and if we are behind/ahead of upstream
161
+ lines=msg.uncolor.lines.to_a
162
+ return if lines.empty?
163
+ head=lines.shift
164
+ parse_head(head)
165
+
166
+ #get status of files
167
+ @changed=@staged=@untracked=@conflicts=0
168
+ lines.each do |line|
169
+ index = line[0];
170
+ workdir = line[1];
171
+ #puts "index: #{index}, workdir: #{workdir}"
172
+ if index=~/[DRAMTC]/ then
173
+ @staged+=1
174
+ end
175
+ if workdir=~ /[DMT]/ then
176
+ @changed+=1
177
+ end
178
+ if workdir=='?' || index=='?' then
179
+ @untracked+=1
180
+ end
181
+ if workdir=='U' || index=='U' then
182
+ @conflicts+=1
183
+ end
184
+ end
185
+ @clean=true
186
+ @clean=false if @staged != 0 || @changed !=0 ||
187
+ @untracked !=0 || @conflicts !=0
188
+ end
189
+
190
+ def get_status
191
+ if worktree?
192
+ get_msg
193
+ parse_msg
194
+ if $opts[:sequencer] and !@msg.empty?
195
+ @sequencer=""
196
+ gitdir=getgitdir
197
+ if (gitdir+"rebase-merge").directory?
198
+ if (gitdir+"rebase-merge/interactive").file?
199
+ @sequencer<<" rb-i " #REBASE-i
200
+ else
201
+ @sequencer<<" rb-m " #REBASE-m
202
+ end
203
+ @sequencer<<(gitdir+"rebase-merge/head-name").read.chomp.sub(/^refs\/heads\//,"")
204
+ end
205
+ if (gitdir+"rebase-apply").directory?
206
+ if (gitdir+"rebase-apply/rebasing").file?
207
+ @sequencer<<" rb" #RB
208
+ elsif (gitdir+"rebase-apply/applying").file?
209
+ @sequencer<<" am" #AM
210
+ else
211
+ @sequencer<<" am/rb" #AM/REBASE
212
+ end
213
+ end
214
+ if (gitdir+"MERGE_HEAD").file?
215
+ @sequencer<<" mg" #MERGING
216
+ end
217
+ if (gitdir+"CHERRY_PICK_HEAD").file?
218
+ @sequencer<<" ch" #CHERRY-PICKING
219
+ end
220
+ if (gitdir+"BISECT_LOG").file?
221
+ @sequencer<<" bi" #BISECTING
222
+ end
223
+ _,stashstatus=runstatus "git rev-parse --verify refs/stash"
224
+ if stashstatus
225
+ stashs=run "git rev-list -g refs/stash"
226
+ @sequencer<<" $#{stashs.lines.to_a.length}" #Stash
227
+ end
228
+ end
229
+ return !@msg.empty?
230
+ else
231
+ if $opts[:sequencer]
232
+ if ingitdir?
233
+ if bare?
234
+ @branch="|bare|"
235
+ else
236
+ @branch="|.git|"
237
+ end
238
+ end
239
+ end
240
+ end
241
+ return false
242
+ end
243
+
244
+ def status
245
+ cd_and_exec { get_status } if git?
246
+ end
247
+
248
+ def prompt
249
+ if status
250
+ return "(" <<
251
+ @branch.color(:magenta,:bold) <<
252
+ (@ahead==0 ? "" : "↑"<<@ahead.to_s ) <<
253
+ (@behind==0 ? "" : "↓"<<@behind.to_s ) <<
254
+ "|" <<
255
+ (@staged==0 ? "" : ("●"+@staged.to_s).color(:red) ) <<
256
+ (@conflicts==0 ? "" : ("✖"+@conflicts.to_s).color(:red) ) <<
257
+ (@changed==0 ? "" : ("✚"+@changed.to_s).color(:blue) ) <<
258
+ (@untracked==0 ? "" : "…" ) <<
259
+ (@clean ? "✔".color(:green,:bold) : "" ) <<
260
+ (@sequencer.empty? ? "" : @sequencer.color(:yellow) ) <<
261
+ ")"
262
+ else
263
+ return "(" << @branch.color(:magenta,:bold) << ")" if @branch
264
+ end
265
+ end
266
+
267
+ def porcelain
268
+ if git?
269
+ return "#{@branch}\n#{@ahead}\n#{@behind}\n#{@staged}\n#{@conflicts}\n#{@changed}\n#{@untracked}\n#{@clean?1:0}\n#{@sequencer}\n"
270
+ else
271
+ return ""
272
+ end
273
+ end
274
+ end
275
+ end
276
+
277
+ $opts={:color => true, :indent => nil, :sequencer => true, :describe => "magic"}
278
+ optparse = OptionParser.new do |opt|
279
+ opt.banner= "#{File.basename($0)} [options] git_dirs"
280
+ opt.on("-p", "--[no-]prompt", "To be used in shell prompt", "This ensure that color ansi sequence are escaped so that they are not counted as text by the shell") do |v|
281
+ $opts[:prompt]=v
282
+ end
283
+ opt.on("--[no-]porcelain", "Don't format the status but output it in a machine convenient format") do |v|
284
+ $opts[:porcelain]=v
285
+ end
286
+ opt.on("-s", "--[no-]status", "List file", "Print the output of git status additionally of what this program parse") do |v|
287
+ $opts[:status]=v
288
+ end
289
+ opt.on("-c", "--[no-]color", "Color output", "on by default") do |v|
290
+ $opts[:color]=v
291
+ end
292
+ opt.on("--[no-]sequencer", "Show sequencer data (and also look for bare directory)", "on by default") do |v|
293
+ $opts[:sequencer]=v
294
+ end
295
+ opt.on("--indent spaces", Integer, "Indent to use if showing git status", "2 by default, 0 for empty ARGV") do |v|
296
+ $opts[:indent]=v
297
+ end
298
+ opt.on("--describe sha1/describe/contains/branch/match/all/magic", "How to describe a detached HEAD", "'magic' by default") do |v|
299
+ $opts[:describe]=v
300
+ end
301
+ opt.on("--sm", "Recurse on each submodules") do |v|
302
+ $opts[:submodules]=v
303
+ end
304
+ end
305
+ optparse.parse!
306
+
307
+ if !$opts[:color]
308
+ SimpleColor.enabled=false
309
+ end
310
+
311
+ def prettify_dir(dir)
312
+ return dir.sub(/^#{ENV['HOME']}/,"~")
313
+ end
314
+
315
+ def gs_output(dir)
316
+ g=GitStatus::Git.new(dir)
317
+ puts "#{prettify_dir(dir)+": " if dir}#{g.prompt}"
318
+ if $opts[:status] and g.git?
319
+ g.msg.lines.each do |line|
320
+ print " "*$opts[:indent] + line
321
+ end
322
+ end
323
+ end
324
+
325
+ if $opts[:porcelain]
326
+ puts GitStatus::Git.new.porcelain
327
+ elsif $opts[:prompt]
328
+ SimpleColor.enabled=:shell
329
+ prompt=GitStatus::Git.new.prompt
330
+ puts prompt if prompt #in ruby1.8, puts nil output nil...
331
+ else
332
+ args=ARGV
333
+ if args.empty?
334
+ $opts[:indent]=0 unless $opts[:indent]
335
+ args=[nil]
336
+ else
337
+ $opts[:indent]=2 unless $opts[:indent]
338
+ end
339
+ args.each do |dir|
340
+ gs_output(dir)
341
+ if $opts[:submodules]
342
+ Dir.chdir(dir||".") do
343
+ %x/git submodule status/.each_line.map { |l| l.split[1] }.each do |dir|
344
+ gs_output(dir)
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end