git_helpers 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/gitstatus.rb ADDED
@@ -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
@@ -0,0 +1,254 @@
1
+ commit 74804e377d4a54d1173d4393827d4e4b27e4d5d0
2
+ diff --cc libs/header_clean/header_clean.pl
3
+ index e8bcd92,5970580..ae279d0
4
+ --- a/libs/header_clean/header_clean.pl
5
+ +++ b/libs/header_clean/header_clean.pl
6
+ @@@ -105,13 -104,21 +104,23 @@@ for (my $i = 0; $i <= $#input; $i++) 
7
+ }
8
+ }
9
+ 
10
+ + # Courtesy of github.com/git/git/blob/ab5d01a/git-add--interactive.perl#L798-L805
11
+ + sub parse_hunk_header {
12
+ + my ($line) = @_;
13
+ + my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) =
14
+ + $line =~ /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
15
+ + $o_cnt = 1 unless defined $o_cnt;
16
+ + $n_cnt = 1 unless defined $n_cnt;
17
+ + return ($o_ofs, $o_cnt, $n_ofs, $n_cnt);
18
+ + }
19
+ + 
20
+ sub strip_empty_first_line {
21
+  - my $foo = shift(); # Array passed in by reference
22
+  + my $array = shift(); # Array passed in by reference
23
+ 
24
+ # If the first line is just whitespace remove it
25
+  - if (defined($foo->[0]) && $foo->[0] =~ /^\s*$/) {
26
+  - shift($foo);
27
+  + if (defined($array->[0]) && $array->[0] =~ /^\s*$/) {
28
+  + shift(@$array); # Throw away the first line
29
+ }
30
+  +
31
+  + return 1;
32
+ }
33
+ diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js b/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js
34
+ index 4f9adf8..8c13743 100644
35
+ --- a/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js
36
+ +++ b/third_party/WebKit/Source/devtools/front_end/ui/Dialog.js
37
+ @@ -32,7 +32,7 @@
38
+ * @constructor
39
+ * @extends {WebInspector.Widget}
40
+ */
41
+ -WebInspector.Dialog = function()
42
+ +WebInspector.Dialog = function(isModalToElement)
43
+ {
44
+ WebInspector.Widget.call(this, true);
45
+ this.markAsRoot();
46
+ @@ -45,6 +45,10 @@ WebInspector.Dialog = function()
47
+ 
48
+ this._wrapsContent = false;
49
+ this._dimmed = false;
50
+ + this._isModalToElement = isModalToElement;
51
+ +
52
+ + this._glassPane = new WebInspector.GlassPane(relativeToElement, isModalToElement);
53
+ +
54
+ /** @type {!Map<!HTMLElement, number>} */
55
+ this._tabIndexMap = new Map();
56
+ }
57
+ @@ -62,16 +65,16 @@ WebInspector.Dialog.prototype = {
58
+ /**
59
+ * @override
60
+ */
61
+ - show: function()
62
+ + show: function(isModalToElement)
63
+ {
64
+ if (WebInspector.Dialog._instance)
65
+ WebInspector.Dialog._instance.detach();
66
+ WebInspector.Dialog._instance = this;
67
+ 
68
+ - var document = /** @type {!Document} */ (WebInspector.Dialog._modalHostView.element.ownerDocument);
69
+ + var document = /** @type {!Document} */ (WebInspector.Dialog._modalHostView.element.ownerDocument, isModalToElement);
70
+ this._disableTabIndexOnElements(document);
71
+ 
72
+ - this._glassPane = new WebInspector.GlassPane(document, this._dimmed);
73
+ + this._glassPane = new WebInspector.GlassPane(document, isModalToElement);
74
+ this._glassPane.element.addEventListener("click", this._onGlassPaneClick.bind(this), false);
75
+ WebInspector.GlassPane.DefaultFocusedViewStack.push(this);
76
+ 
77
+ commit 6e50ba922f45d810b77de941a6a848df4a9ab44a (HEAD -> master)
78
+ Author: Damien Robert <damien.olivier.robert+git@gmail.com>
79
+ Date: Sun Mar 13 18:58:41 2016 +0100
80
+
81
+ Rename symlink
82
+
83
+ diff --git a/d b/d
84
+ deleted file mode 100755
85
+ index 4bcfe98..0000000
86
+ --- a/d
87
+ +++ /dev/null
88
+ @@ -1 +0,0 @@
89
+ -d
90
+ diff --git a/d b/d
91
+ new file mode 120000
92
+ index 0000000..c59d9b6
93
+ --- /dev/null
94
+ +++ b/d
95
+ @@ -0,0 +1 @@
96
+ +d
97
+ 
98
+ diff --git a/e b/e
99
+ deleted file mode 120000
100
+ index c59d9b6..0000000
101
+ --- a/e
102
+ +++ /dev/null
103
+ @@ -1 +0,0 @@
104
+ -d
105
+ 
106
+
107
+ commit 8b9d73ca7c9e9da18bdb0beff3ab38c49b4e5ae1
108
+ Author: Damien Robert <damien.olivier.robert+git@gmail.com>
109
+ Date: Sun Mar 13 18:58:31 2016 +0100
110
+
111
+ symlink
112
+
113
+ diff --git a/e b/e
114
+ new file mode 120000
115
+ index 0000000..c59d9b6
116
+ --- /dev/null
117
+ +++ b/e
118
+ @@ -0,0 +1 @@
119
+ +d
120
+ 
121
+
122
+ commit 00c13fb19a63a7e753a2f06aaa214c05726c9bfb
123
+ Author: Damien Robert <damien.olivier.robert+git@gmail.com>
124
+ Date: Sun Mar 13 18:58:21 2016 +0100
125
+
126
+ copy + file permission
127
+
128
+ diff --git a/b2 b/c2
129
+ similarity index 100%
130
+ copy from b2
131
+ copy to c2
132
+ diff --git a/d b/d
133
+ old mode 100644
134
+ new mode 100755
135
+
136
+ commit 8af4fb242d1040e291897a7d047da4dfbe97e9ef
137
+ Author: Damien Robert <damien.olivier.robert+git@gmail.com>
138
+ Date: Sun Mar 13 18:58:02 2016 +0100
139
+
140
+ Rename
141
+
142
+ diff --git a/b b/b2
143
+ similarity index 100%
144
+ rename from b
145
+ rename to b2
146
+
147
+ commit a1aad6c1153b923e0c5d14bc1bbbdf5e39d89591
148
+ Author: Damien Robert <damien.olivier.robert+git@gmail.com>
149
+ Date: Sun Mar 13 18:57:39 2016 +0100
150
+
151
+ Adding d, new line to b
152
+
153
+ diff --git a/b b/b
154
+ index 6178079..0939735 100644
155
+ --- a/b
156
+ +++ b/b
157
+ @@ -1 +1,2 @@
158
+ b
159
+ +new line on b
160
+ diff --git a/d b/d
161
+ new file mode 100644
162
+ index 0000000..4bcfe98
163
+ --- /dev/null
164
+ +++ b/d
165
+ @@ -0,0 +1 @@
166
+ +d
167
+
168
+ commit fcf9b0274a1f034ced762c269f835e198693704a
169
+ Author: Damien Robert <damien.olivier.robert+git@gmail.com>
170
+ Date: Sun Mar 13 18:57:39 2016 +0100
171
+
172
+ Adding b
173
+
174
+ diff --git a/b b/b
175
+ new file mode 100644
176
+ index 0000000..6178079
177
+ --- /dev/null
178
+ +++ b/b
179
+ @@ -0,0 +1 @@
180
+ +b
181
+
182
+ commit 6fa1c4ab2a8b2be408791d874155c95511ecc0ce
183
+ Author: Damien Robert <damien.olivier.robert+git@gmail.com>
184
+ Date: Sun Mar 13 18:57:39 2016 +0100
185
+
186
+ Adding a
187
+
188
+ diff --git a/a b/a
189
+ new file mode 100644
190
+ index 0000000..7898192
191
+ --- /dev/null
192
+ +++ b/a
193
+ @@ -0,0 +1 @@
194
+ +a
195
+
196
+ Submodule ruby/gems/simplecolor contains untracked content
197
+ Submodule ruby/gems/simplecolor contains modified content
198
+ Submodule ruby/gems/simplecolor a5c060d..ac178d7:
199
+ > Concatenate ANSI escape sequences inside the \e
200
+ > Add possibility to copy colors
201
+ > Sometimes \e[m is abused for \e[0m
202
+ > More exceptions
203
+ > Merge some color regexp and raise exception on bogus colors
204
+ > Fix SimpleColor#uncolor!
205
+ > Change ANSI Regexps
206
+ > rake doc fails for now with Rake 11
207
+ > Add uncolor tests
208
+ > ColorWrapper: unify gestion of arg
209
+
210
+ Submodule script/others/republique f4c0876...0000000 (submodule deleted)
211
+ Submodule script/others/republique 0000000...f4c0876 (not checked out)
212
+ Submodule plam 0000000...c43a6e4 (new submodule)
213
+ Submodule plam c43a6e4...9215cb5 (commits not present)
214
+ Submodule plam 9215cb5..4b41ae0 (rewind):
215
+ < Adding d, new line to b
216
+ Submodule plam de44db5...d6ed7c1:
217
+ > Uhihih
218
+ < Ohoho
219
+
220
+ diff --git i/a w/a
221
+ index 7898192..442406a 100644
222
+ --- i/a
223
+ +++ w/a
224
+ @@ -1 +1,2 @@
225
+ a
226
+ +
227
+ diff --git i/b2 w/b2
228
+ index 0939735..d70291d 100644
229
+ --- i/b2
230
+ +++ w/b2
231
+ @@ -1,2 +1,2 @@
232
+ -b
233
+ +b 
234
+ new line on b
235
+ diff --git i/b w/b
236
+ index 3cd10f0..3cc89da 100644
237
+ --- i/b
238
+ +++ w/b
239
+ @@ -1,5 +1,5 @@
240
+ b
241
+ new line on b
242
+ ohoh
243
+ - 
244
+ +
245
+ bl2
246
+
247
+ diff --git 1/2/umount 2/2/umount
248
+ new file mode 100755
249
+ index 0000000..bb9ce29
250
+ Binary files /dev/null and 2/2/umount differ
251
+ diff --git 1/2/umount 2/2/umount
252
+ deleted file mode 100755
253
+ index bb9ce29..0000000
254
+ Binary files 1/2/umount and /dev/null differ