git_helpers 0.1.0 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
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