git-hub 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile DELETED
@@ -1,104 +0,0 @@
1
- require 'rake/testtask'
2
-
3
- #
4
- # Helpers
5
- #
6
-
7
- def command?(command)
8
- `which #{command} 2>/dev/null`
9
- $?.success?
10
- end
11
-
12
- task :load_hub do
13
- $LOAD_PATH.unshift 'lib'
14
- require 'hub'
15
- end
16
-
17
- task :check_dirty do
18
- if !`git status`.include?('nothing to commit')
19
- abort "dirty index - not publishing!"
20
- end
21
- end
22
-
23
-
24
- #
25
- # Tests
26
- #
27
-
28
- task :default => :test
29
-
30
- if command? :turn
31
- desc "Run tests"
32
- task :test do
33
- suffix = "-n #{ENV['TEST']}" if ENV['TEST']
34
- sh "turn test/*.rb #{suffix}"
35
- end
36
- else
37
- Rake::TestTask.new do |t|
38
- t.libs << 'lib'
39
- t.ruby_opts << '-rubygems'
40
- t.pattern = 'test/**/*_test.rb'
41
- t.verbose = false
42
- end
43
- end
44
-
45
- if command? :kicker
46
- desc "Launch Kicker (like autotest)"
47
- task :kicker do
48
- puts "Kicking... (ctrl+c to cancel)"
49
- exec "kicker -e rake test lib"
50
- end
51
- end
52
-
53
-
54
- #
55
- # Ron
56
- #
57
-
58
- if command? :ronn
59
- desc "Show the manual"
60
- task :man => "man:build" do
61
- exec "man man/hub.1"
62
- end
63
-
64
- desc "Build the manual"
65
- task "man:build" do
66
- sh "ronn -br5 --organization=DEFUNKT --manual='Git Manual' man/*.ronn"
67
- end
68
- end
69
-
70
-
71
- #
72
- # Gems
73
- #
74
-
75
- desc "Build standalone script"
76
- task :standalone => :load_hub do
77
- require 'hub/standalone'
78
- Hub::Standalone.save('hub')
79
- end
80
-
81
- desc "Install standalone script and man pages"
82
- task :install => :standalone do
83
- prefix = ENV['PREFIX'] || ENV['prefix'] || '/usr/local'
84
-
85
- FileUtils.mkdir_p "#{prefix}/bin"
86
- FileUtils.cp "hub", "#{prefix}/bin"
87
-
88
- FileUtils.mkdir_p "#{prefix}/share/man/man1"
89
- FileUtils.cp "man/hub.1", "#{prefix}/share/man/man1"
90
- end
91
-
92
- desc "Publish to GitHub Pages"
93
- task :pages => [ "man:build", :check_dirty, :standalone ] do
94
- cp "man/hub.1.html", "html"
95
- sh "git checkout gh-pages"
96
- sh "mv hub standalone"
97
- sh "git add standalone*"
98
- sh "mv html hub.1.html"
99
- sh "git add hub.1.html"
100
- sh "git commit -m 'update standalone'"
101
- sh "git push origin gh-pages"
102
- sh "git checkout master"
103
- puts :done
104
- end
data/bin/hub DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # hub(1)
4
- # alias git=hub
5
-
6
- require 'hub'
7
- Hub::Runner.execute(*ARGV)
data/lib/hub.rb DELETED
@@ -1,5 +0,0 @@
1
- require 'hub/version'
2
- require 'hub/args'
3
- require 'hub/context'
4
- require 'hub/commands'
5
- require 'hub/runner'
@@ -1,99 +0,0 @@
1
- module Hub
2
- # The Args class exists to make it more convenient to work with
3
- # command line arguments intended for git from within the Hub
4
- # codebase.
5
- #
6
- # The ARGV array is converted into an Args instance by the Hub
7
- # instance when instantiated.
8
- class Args < Array
9
- attr_accessor :executable
10
-
11
- def initialize(*args)
12
- super
13
- @executable = ENV["GIT"] || "git"
14
- @after = nil
15
- @skip = false
16
- @original_args = args.first
17
- @chain = [nil]
18
- end
19
-
20
- # Adds an `after` callback.
21
- # A callback can be a command or a proc.
22
- def after(cmd_or_args = nil, args = nil, &block)
23
- @chain.insert(-1, normalize_callback(cmd_or_args, args, block))
24
- end
25
-
26
- # Adds a `before` callback.
27
- # A callback can be a command or a proc.
28
- def before(cmd_or_args = nil, args = nil, &block)
29
- @chain.insert(@chain.index(nil), normalize_callback(cmd_or_args, args, block))
30
- end
31
-
32
- # Tells if there are multiple (chained) commands or not.
33
- def chained?
34
- @chain.size > 1
35
- end
36
-
37
- # Returns an array of all commands.
38
- def commands
39
- chain = @chain.dup
40
- chain[chain.index(nil)] = self.to_exec
41
- chain
42
- end
43
-
44
- # Skip running this command.
45
- def skip!
46
- @skip ||= true
47
- end
48
-
49
- # Boolean indicating whether this command will run.
50
- def skip?
51
- @skip
52
- end
53
-
54
- # Array of `executable` followed by all args suitable as arguments
55
- # for `exec` or `system` calls.
56
- def to_exec(args = self)
57
- [executable].concat args
58
- end
59
-
60
- # All the words (as opposed to flags) contained in this argument
61
- # list.
62
- #
63
- # args = Args.new([ 'remote', 'add', '-f', 'tekkub' ])
64
- # args.words == [ 'remote', 'add', 'tekkub' ]
65
- def words
66
- reject { |arg| arg.index('-') == 0 }
67
- end
68
-
69
- # All the flags (as opposed to words) contained in this argument
70
- # list.
71
- #
72
- # args = Args.new([ 'remote', 'add', '-f', 'tekkub' ])
73
- # args.flags == [ '-f' ]
74
- def flags
75
- self - words
76
- end
77
-
78
- # Tests if arguments were modified since instantiation
79
- def changed?
80
- chained? or self != @original_args
81
- end
82
-
83
- private
84
-
85
- def normalize_callback(cmd_or_args, args, block)
86
- if block
87
- block
88
- elsif args
89
- [cmd_or_args].concat args
90
- elsif Array === cmd_or_args
91
- self.to_exec cmd_or_args
92
- elsif cmd_or_args
93
- cmd_or_args
94
- else
95
- raise ArgumentError, "command or block required"
96
- end
97
- end
98
- end
99
- end
@@ -1,716 +0,0 @@
1
- module Hub
2
- # See context.rb
3
- module Context; end
4
-
5
- # The Commands module houses the git commands that hub
6
- # lovingly wraps. If a method exists here, it is expected to have a
7
- # corresponding git command which either gets run before or after
8
- # the method executes.
9
- #
10
- # The typical flow is as follows:
11
- #
12
- # 1. hub is invoked from the command line:
13
- # $ hub clone rtomayko/tilt
14
- #
15
- # 2. The Hub class is initialized:
16
- # >> hub = Hub.new('clone', 'rtomayko/tilt')
17
- #
18
- # 3. The method representing the git subcommand is executed with the
19
- # full args:
20
- # >> Commands.clone('clone', 'rtomayko/tilt')
21
- #
22
- # 4. That method rewrites the args as it sees fit:
23
- # >> args[1] = "git://github.com/" + args[1] + ".git"
24
- # => "git://github.com/rtomayko/tilt.git"
25
- #
26
- # 5. The new args are used to run `git`:
27
- # >> exec "git", "clone", "git://github.com/rtomayko/tilt.git"
28
- #
29
- # An optional `after` callback can be set. If so, it is run after
30
- # step 5 (which then performs a `system` call rather than an
31
- # `exec`). See `Hub::Args` for more information on the `after` callback.
32
- module Commands
33
- # We are a blank slate.
34
- instance_methods.each { |m| undef_method(m) unless m =~ /(^__|send|to\?$)/ }
35
- extend self
36
-
37
- # Provides `github_url` and various inspection methods
38
- extend Context
39
-
40
- API_REPO = 'http://github.com/api/v2/yaml/repos/show/%s/%s'
41
- API_FORK = 'http://github.com/api/v2/yaml/repos/fork/%s/%s'
42
- API_CREATE = 'http://github.com/api/v2/yaml/repos/create'
43
-
44
- def run(args)
45
- # Hack to emulate git-style
46
- args.unshift 'help' if args.grep(/^[^-]|version|exec-path$|html-path/).empty?
47
-
48
- cmd = args[0]
49
- expanded_args = expand_alias(cmd)
50
- cmd = expanded_args[0] if expanded_args
51
-
52
- # git commands can have dashes
53
- cmd = cmd.sub(/(\w)-/, '\1_')
54
- if method_defined?(cmd) and cmd != 'run'
55
- args[0, 1] = expanded_args if expanded_args
56
- send(cmd, args)
57
- end
58
- end
59
-
60
- # $ hub clone rtomayko/tilt
61
- # > git clone git://github.com/rtomayko/tilt.
62
- #
63
- # $ hub clone -p kneath/hemingway
64
- # > git clone git@github.com:kneath/hemingway.git
65
- #
66
- # $ hub clone tilt
67
- # > git clone git://github.com/YOUR_LOGIN/tilt.
68
- #
69
- # $ hub clone -p github
70
- # > git clone git@github.com:YOUR_LOGIN/hemingway.git
71
- def clone(args)
72
- ssh = args.delete('-p')
73
- has_values = /^(--(upload-pack|template|depth|origin|branch|reference)|-[ubo])$/
74
-
75
- idx = 1
76
- while idx < args.length
77
- arg = args[idx]
78
- if arg.index('-') == 0
79
- idx += 1 if arg =~ has_values
80
- elsif arg.index('://') or arg.index('@') or File.directory?(arg)
81
- # Bail out early for URLs and local paths.
82
- break
83
- elsif arg.scan('/').size <= 1 && !arg.include?(':')
84
- # $ hub clone rtomayko/tilt
85
- # $ hub clone tilt
86
- args[args.index(arg)] = github_url(:repo => arg, :private => ssh)
87
- break
88
- end
89
- idx += 1
90
- end
91
- end
92
-
93
- # $ hub submodule add wycats/bundler vendor/bundler
94
- # > git submodule add git://github.com/wycats/bundler.git vendor/bundler
95
- #
96
- # $ hub submodule add -p wycats/bundler vendor/bundler
97
- # > git submodule add git@github.com:wycats/bundler.git vendor/bundler
98
- #
99
- # $ hub submodule add -b ryppl ryppl/pip vendor/bundler
100
- # > git submodule add -b ryppl git://github.com/ryppl/pip.git vendor/pip
101
- def submodule(args)
102
- return unless index = args.index('add')
103
- args.delete_at index
104
-
105
- branch = args.index('-b') || args.index('--branch')
106
- if branch
107
- args.delete_at branch
108
- branch_name = args.delete_at branch
109
- end
110
-
111
- clone(args)
112
-
113
- if branch_name
114
- args.insert branch, '-b', branch_name
115
- end
116
- args.insert index, 'add'
117
- end
118
-
119
- # $ hub remote add pjhyett
120
- # > git remote add pjhyett git://github.com/pjhyett/THIS_REPO.git
121
- #
122
- # $ hub remote add -p mojombo
123
- # > git remote add mojombo git@github.com:mojombo/THIS_REPO.git
124
- #
125
- # $ hub remote add origin
126
- # > git remote add origin git://github.com/YOUR_LOGIN/THIS_REPO.git
127
- def remote(args)
128
- return unless ['add','set-url'].include?(args[1]) && args.last !~ %r{.+?://|.+?@|^[./]}
129
-
130
- ssh = args.delete('-p')
131
-
132
- # user/repo
133
- args.last =~ /\b(.+?)(?:\/(.+))?$/
134
- user, repo = $1, $2
135
-
136
- if args.words[2] == 'origin' && args.words[3].nil?
137
- # Origin special case triggers default user/repo
138
- user = repo = nil
139
- elsif args.words[-2] == args.words[1]
140
- # rtomayko/tilt => rtomayko
141
- # Make sure you dance around flags.
142
- idx = args.index( args.words[-1] )
143
- args[idx] = user
144
- else
145
- # They're specifying the remote name manually (e.g.
146
- # git remote add blah rtomayko/tilt), so just drop the last
147
- # argument.
148
- args.replace args[0...-1]
149
- end
150
-
151
- args << github_url(:user => user, :repo => repo, :private => ssh)
152
- end
153
-
154
- # $ hub fetch mislav
155
- # > git remote add mislav git://github.com/mislav/REPO.git
156
- # > git fetch mislav
157
- #
158
- # $ hub fetch --multiple mislav xoebus
159
- # > git remote add mislav ...
160
- # > git remote add xoebus ...
161
- # > git fetch --multiple mislav xoebus
162
- def fetch(args)
163
- # $ hub fetch --multiple <name1>, <name2>, ...
164
- if args.include?('--multiple')
165
- names = args.words[1..-1]
166
- # $ hub fetch <name>
167
- elsif remote_name = args.words[1]
168
- # $ hub fetch <name1>,<name2>,...
169
- if remote_name =~ /^\w+(,\w+)+$/
170
- index = args.index(remote_name)
171
- args.delete(remote_name)
172
- names = remote_name.split(',')
173
- args.insert(index, *names)
174
- args.insert(index, '--multiple')
175
- else
176
- names = [remote_name]
177
- end
178
- else
179
- names = []
180
- end
181
-
182
- names.reject! { |name|
183
- name =~ /\W/ or remotes.include?(name) or
184
- remotes_group(name) or not repo_exists?(name)
185
- }
186
-
187
- if names.any?
188
- names.each do |name|
189
- args.before ['remote', 'add', name, github_url(:user => name)]
190
- end
191
- end
192
- end
193
-
194
- # $ git cherry-pick http://github.com/mislav/hub/commit/a319d88#comments
195
- # > git remote add -f mislav git://github.com/mislav/hub.git
196
- # > git cherry-pick a319d88
197
- #
198
- # $ git cherry-pick mislav@a319d88
199
- # > git remote add -f mislav git://github.com/mislav/hub.git
200
- # > git cherry-pick a319d88
201
- #
202
- # $ git cherry-pick mislav@SHA
203
- # > git fetch mislav
204
- # > git cherry-pick SHA
205
- def cherry_pick(args)
206
- unless args.include?('-m') or args.include?('--mainline')
207
- case ref = args.words.last
208
- when %r{^(?:https?:)//github.com/(.+?)/(.+?)/commit/([a-f0-9]{7,40})}
209
- user, repo, sha = $1, $2, $3
210
- args[args.index(ref)] = sha
211
- when /^(\w+)@([a-f1-9]{7,40})$/
212
- user, repo, sha = $1, nil, $2
213
- args[args.index(ref)] = sha
214
- else
215
- user = nil
216
- end
217
-
218
- if user
219
- if user == repo_owner
220
- # fetch from origin if the repo belongs to the user
221
- args.before ['fetch', default_remote]
222
- elsif remotes.include?(user)
223
- args.before ['fetch', user]
224
- else
225
- remote_url = github_url(:user => user, :repo => repo, :private => false)
226
- args.before ['remote', 'add', '-f', user, remote_url]
227
- end
228
- end
229
- end
230
- end
231
-
232
- # $ hub am https://github.com/defunkt/hub/pull/55
233
- # > curl https://github.com/defunkt/hub/pull/55.patch -o /tmp/55.patch
234
- # > git am /tmp/55.patch
235
- def am(args)
236
- if url = args.find { |a| a =~ %r{^https?://(gist\.)?github\.com/} }
237
- idx = args.index(url)
238
- gist = $1 == 'gist.'
239
- ext = gist ? '.txt' : '.patch'
240
- url += ext unless File.extname(url) == ext
241
- patch_file = File.join(ENV['TMPDIR'], "#{gist ? 'gist-' : ''}#{File.basename(url)}")
242
- args.before 'curl', ['-#LA', "hub #{Hub::Version}", url, '-o', patch_file]
243
- args[idx] = patch_file
244
- end
245
- end
246
-
247
- # $ hub init -g
248
- # > git init
249
- # > git remote add origin git@github.com:USER/REPO.git
250
- def init(args)
251
- if args.delete('-g')
252
- url = github_url(:private => true, :repo => current_dirname)
253
- args.after "git remote add origin #{url}"
254
- end
255
- end
256
-
257
- # $ hub fork
258
- # ... hardcore forking action ...
259
- # > git remote add -f YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
260
- def fork(args)
261
- # can't do anything without token and original owner name
262
- if github_user && github_token && repo_owner
263
- if repo_exists?(github_user)
264
- puts "#{github_user}/#{repo_name} already exists on GitHub"
265
- else
266
- fork_repo
267
- end
268
-
269
- if args.include?('--no-remote')
270
- exit
271
- else
272
- url = github_url(:private => true)
273
- args.replace %W"remote add -f #{github_user} #{url}"
274
- args.after { puts "new remote: #{github_user}" }
275
- end
276
- end
277
- rescue Net::HTTPExceptions
278
- response = $!.response
279
- warn "error creating fork: #{response.message} (HTTP #{response.code})"
280
- exit 1
281
- end
282
-
283
- # $ hub create
284
- # ... create repo on github ...
285
- # > git remote add -f origin git@github.com:YOUR_USER/CURRENT_REPO.git
286
- def create(args)
287
- if !is_repo?
288
- puts "'create' must be run from inside a git repository"
289
- args.skip!
290
- elsif github_user && github_token
291
- args.shift
292
- options = {}
293
- options[:private] = true if args.delete('-p')
294
-
295
- until args.empty?
296
- case arg = args.shift
297
- when '-d'
298
- options[:description] = args.shift
299
- when '-h'
300
- options[:homepage] = args.shift
301
- else
302
- puts "unexpected argument: #{arg}"
303
- return
304
- end
305
- end
306
-
307
- if repo_exists?(github_user)
308
- puts "#{github_user}/#{repo_name} already exists on GitHub"
309
- action = "set remote origin"
310
- else
311
- action = "created repository"
312
- create_repo(options)
313
- end
314
-
315
- url = github_url(:private => true)
316
-
317
- if remotes.first != 'origin'
318
- args.replace %W"remote add -f origin #{url}"
319
- else
320
- args.replace %W"remote -v"
321
- end
322
-
323
- args.after { puts "#{action}: #{github_user}/#{repo_name}" }
324
- end
325
- rescue Net::HTTPExceptions
326
- response = $!.response
327
- warn "error creating repository: #{response.message} (HTTP #{response.code})"
328
- exit 1
329
- end
330
-
331
- # $ hub push origin,staging cool-feature
332
- # > git push origin cool-feature
333
- # > git push staging cool-feature
334
- def push(args)
335
- return unless args[1] =~ /,/
336
-
337
- branch = args[2]
338
- remotes = args[1].split(',')
339
- args[1] = remotes.shift
340
-
341
- remotes.each do |name|
342
- args.after ['push', name, branch]
343
- end
344
- end
345
-
346
- # $ hub browse
347
- # > open https://github.com/CURRENT_REPO
348
- #
349
- # $ hub browse -- issues
350
- # > open https://github.com/CURRENT_REPO/issues
351
- #
352
- # $ hub browse pjhyett/github-services
353
- # > open https://github.com/pjhyett/github-services
354
- #
355
- # $ hub browse github-services
356
- # > open https://github.com/YOUR_LOGIN/github-services
357
- #
358
- # $ hub browse github-services wiki
359
- # > open https://github.com/YOUR_LOGIN/github-services/wiki
360
- def browse(args)
361
- args.shift
362
- browse_command(args) do
363
- user = repo = nil
364
- dest = args.shift
365
- dest = nil if dest == '--'
366
-
367
- if dest
368
- # $ hub browse pjhyett/github-services
369
- # $ hub browse github-services
370
- repo = dest
371
- elsif repo_user
372
- # $ hub browse
373
- user = repo_user
374
- else
375
- abort "Usage: hub browse [<USER>/]<REPOSITORY>"
376
- end
377
-
378
- params = { :user => user, :repo => repo }
379
-
380
- # $ hub browse -- wiki
381
- case subpage = args.shift
382
- when 'commits'
383
- branch = (!dest && tracked_branch) || 'master'
384
- params[:web] = "/commits/#{branch}"
385
- when 'tree', NilClass
386
- branch = !dest && tracked_branch
387
- params[:web] = "/tree/#{branch}" if branch && branch != 'master'
388
- else
389
- params[:web] = "/#{subpage}"
390
- end
391
-
392
- params
393
- end
394
- end
395
-
396
- # $ hub compare 1.0...fix
397
- # > open https://github.com/CURRENT_REPO/compare/1.0...fix
398
- # $ hub compare refactor
399
- # > open https://github.com/CURRENT_REPO/compare/refactor
400
- # $ hub compare myfork feature
401
- # > open https://github.com/myfork/REPO/compare/feature
402
- # $ hub compare -u 1.0...2.0
403
- # "https://github.com/CURRENT_REPO/compare/1.0...2.0"
404
- def compare(args)
405
- args.shift
406
- browse_command(args) do
407
- if args.empty?
408
- branch = tracked_branch
409
- if branch && branch != 'master'
410
- range, user = branch, repo_user
411
- else
412
- abort "Usage: hub compare [USER] [<START>...]<END>"
413
- end
414
- else
415
- range = args.pop
416
- user = args.pop || repo_user
417
- end
418
- { :user => user, :web => "/compare/#{range}" }
419
- end
420
- end
421
-
422
- # $ hub hub standalone
423
- # Prints the "standalone" version of hub for an easy, memorable
424
- # installation sequence:
425
- #
426
- # $ gem install git-hub
427
- # $ hub hub standalone > ~/bin/hub && chmod 755 ~/bin/hub
428
- # $ gem uninstall git-hub
429
- def hub(args)
430
- return help(args) unless args[1] == 'standalone'
431
- require 'hub/standalone'
432
- puts Hub::Standalone.build
433
- exit
434
- rescue LoadError
435
- abort "hub is running in standalone mode."
436
- end
437
-
438
- def alias(args)
439
- shells = {
440
- 'sh' => 'alias git=hub',
441
- 'bash' => 'alias git=hub',
442
- 'zsh' => 'function git(){hub "$@"}',
443
- 'csh' => 'alias git hub',
444
- 'fish' => 'alias git hub'
445
- }
446
-
447
- silent = args.delete('-s')
448
-
449
- if shell = args[1]
450
- if silent.nil?
451
- puts "Run this in your shell to start using `hub` as `git`:"
452
- print " "
453
- end
454
- else
455
- puts "usage: hub alias [-s] SHELL", ""
456
- puts "You already have hub installed and available in your PATH,"
457
- puts "but to get the full experience you'll want to alias it to"
458
- puts "`git`.", ""
459
- puts "To see how to accomplish this for your shell, run the alias"
460
- puts "command again with the name of your shell.", ""
461
- puts "Known shells:"
462
- shells.map { |key, _| key }.sort.each do |key|
463
- puts " " + key
464
- end
465
- puts "", "Options:"
466
- puts " -s Silent. Useful when using the output with eval, e.g."
467
- puts " $ eval `hub alias -s bash`"
468
-
469
- exit
470
- end
471
-
472
- if shells[shell]
473
- puts shells[shell]
474
- else
475
- abort "fatal: never heard of `#{shell}'"
476
- end
477
-
478
- exit
479
- end
480
-
481
- # $ hub version
482
- # > git version
483
- # (print hub version)
484
- def version(args)
485
- args.after do
486
- puts "hub version %s" % Version
487
- end
488
- end
489
- alias_method "--version", :version
490
-
491
- # $ hub help
492
- # (print improved help text)
493
- def help(args)
494
- command = args.grep(/^[^-]/)[1]
495
-
496
- if command == 'hub'
497
- puts hub_manpage
498
- exit
499
- elsif command.nil? && args.grep(/^--?a/).empty?
500
- ENV['GIT_PAGER'] = '' if args.grep(/^-{1,2}p/).empty? # Use `cat`.
501
- puts improved_help_text
502
- exit
503
- end
504
- end
505
- alias_method "--help", :help
506
-
507
- # The text print when `hub help` is run, kept in its own method
508
- # for the convenience of the author.
509
- def improved_help_text
510
- <<-help
511
- usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
512
- [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR]
513
- [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]
514
-
515
- Basic Commands:
516
- init Create an empty git repository or reinitialize an existing one
517
- add Add new or modified files to the staging area
518
- rm Remove files from the working directory and staging area
519
- mv Move or rename a file, a directory, or a symlink
520
- status Show the status of the working directory and staging area
521
- commit Record changes to the repository
522
-
523
- History Commands:
524
- log Show the commit history log
525
- diff Show changes between commits, commit and working tree, etc
526
- show Show information about commits, tags or files
527
-
528
- Branching Commands:
529
- branch List, create, or delete branches
530
- checkout Switch the active branch to another branch
531
- merge Join two or more development histories (branches) together
532
- tag Create, list, delete, sign or verify a tag object
533
-
534
- Remote Commands:
535
- clone Clone a remote repository into a new directory
536
- fetch Download data, tags and branches from a remote repository
537
- pull Fetch from and merge with another repository or a local branch
538
- push Upload data, tags and branches to a remote repository
539
- remote View and manage a set of remote repositories
540
-
541
- Advanced commands:
542
- reset Reset your staging area or working directory to another point
543
- rebase Re-apply a series of patches in one branch onto another
544
- bisect Find by binary search the change that introduced a bug
545
- grep Print files with lines matching a pattern in your codebase
546
-
547
- See 'git help COMMAND' for more information on a specific command.
548
- help
549
- end
550
-
551
- private
552
- #
553
- # Helper methods are private so they cannot be invoked
554
- # from the command line.
555
- #
556
-
557
- # Checks whether a command exists on this system in the $PATH.
558
- #
559
- # name - The String name of the command to check for.
560
- #
561
- # Returns a Boolean.
562
- def command?(name)
563
- `which #{name} 2>/dev/null`
564
- $?.success?
565
- end
566
-
567
- # Detects commands to launch the user's browser, checking $BROWSER
568
- # first then falling back to a few common launchers. Aborts with
569
- # an error if it can't find anything appropriate.
570
- #
571
- # Returns a launch command.
572
- def browser_launcher
573
- if ENV['BROWSER']
574
- ENV['BROWSER']
575
- elsif RUBY_PLATFORM.include?('darwin')
576
- "open"
577
- elsif command?("xdg-open")
578
- "xdg-open"
579
- elsif command?("cygstart")
580
- "cygstart"
581
- else
582
- abort "Please set $BROWSER to a web launcher to use this command."
583
- end
584
- end
585
-
586
- # Handles common functionality of browser commands like `browse`
587
- # and `compare`. Yields a block that returns params for `github_url`.
588
- def browse_command(args)
589
- url_only = args.delete('-u')
590
- $stderr.puts "Warning: the `-p` flag has no effect anymore" if args.delete('-p')
591
- params = yield
592
-
593
- args.executable = url_only ? 'echo' : browser_launcher
594
- args.push github_url({:web => true, :private => true}.update(params))
595
- end
596
-
597
-
598
- # Returns the terminal-formatted manpage, ready to be printed to
599
- # the screen.
600
- def hub_manpage
601
- return "** Can't find groff(1)" unless command?('groff')
602
-
603
- require 'open3'
604
- out = nil
605
- Open3.popen3(groff_command) do |stdin, stdout, _|
606
- stdin.puts hub_raw_manpage
607
- stdin.close
608
- out = stdout.read.strip
609
- end
610
- out
611
- end
612
-
613
- # The groff command complete with crazy arguments we need to run
614
- # in order to turn our raw roff (manpage markup) into something
615
- # readable on the terminal.
616
- def groff_command
617
- "groff -Wall -mtty-char -mandoc -Tascii"
618
- end
619
-
620
- # Returns the raw hub manpage. If we're not running in standalone
621
- # mode, it's a file sitting at the root under the `man`
622
- # directory.
623
- #
624
- # If we are running in standalone mode the manpage will be
625
- # included after the __END__ of the file so we can grab it using
626
- # DATA.
627
- def hub_raw_manpage
628
- if File.exists? file = File.dirname(__FILE__) + '/../../man/hub.1'
629
- File.read(file)
630
- else
631
- DATA.read
632
- end
633
- end
634
-
635
- # All calls to `puts` in after hooks or commands are paged,
636
- # git-style.
637
- def puts(*args)
638
- page_stdout
639
- super
640
- end
641
-
642
- # http://nex-3.com/posts/73-git-style-automatic-paging-in-ruby
643
- def page_stdout
644
- return unless $stdout.tty?
645
-
646
- read, write = IO.pipe
647
-
648
- if Kernel.fork
649
- # Parent process, become pager
650
- $stdin.reopen(read)
651
- read.close
652
- write.close
653
-
654
- # Don't page if the input is short enough
655
- ENV['LESS'] = 'FSRX'
656
-
657
- # Wait until we have input before we start the pager
658
- Kernel.select [STDIN]
659
-
660
- pager = ENV['GIT_PAGER'] ||
661
- `git config --get-all core.pager`.split.first || ENV['PAGER'] ||
662
- 'less -isr'
663
-
664
- pager = 'cat' if pager.empty?
665
-
666
- exec pager rescue exec "/bin/sh", "-c", pager
667
- else
668
- # Child process
669
- $stdout.reopen(write)
670
- $stderr.reopen(write) if $stderr.tty?
671
- read.close
672
- write.close
673
- end
674
- end
675
-
676
- # Determines whether a user has a fork of the current repo on GitHub.
677
- def repo_exists?(user)
678
- require 'net/http'
679
- url = API_REPO % [user, repo_name]
680
- Net::HTTPSuccess === Net::HTTP.get_response(URI(url))
681
- end
682
-
683
- # Forks the current repo using the GitHub API.
684
- #
685
- # Returns nothing.
686
- def fork_repo
687
- url = API_FORK % [repo_owner, repo_name]
688
- response = Net::HTTP.post_form(URI(url), 'login' => github_user, 'token' => github_token)
689
- response.error! unless Net::HTTPSuccess === response
690
- end
691
-
692
- # Creates a new repo using the GitHub API.
693
- #
694
- # Returns nothing.
695
- def create_repo(options = {})
696
- url = API_CREATE
697
- params = {'login' => github_user, 'token' => github_token, 'name' => repo_name}
698
- params['public'] = '0' if options[:private]
699
- params['description'] = options[:description] if options[:description]
700
- params['homepage'] = options[:homepage] if options[:homepage]
701
-
702
- response = Net::HTTP.post_form(URI(url), params)
703
- response.error! unless Net::HTTPSuccess === response
704
- end
705
-
706
- def expand_alias(cmd)
707
- if expanded = git_alias_for(cmd)
708
- if expanded.index('!') != 0
709
- require 'shellwords' unless expanded.respond_to? :shellsplit
710
- expanded.shellsplit
711
- end
712
- end
713
- end
714
-
715
- end
716
- end