Module: Hub::Commands

Extended by:
Commands, Context
Included in:
Commands
Defined in:
lib/hub/commands.rb

Overview

The Commands module houses the git commands that hub lovingly wraps. If a method exists here, it is expected to have a corresponding git command which either gets run before or after the method executes.

The typical flow is as follows:

  1. hub is invoked from the command line: $ hub clone rtomayko/tilt

  2. The Hub class is initialized: >> hub = Hub.new(‘clone’, ‘rtomayko/tilt’)

  3. The method representing the git subcommand is executed with the full args: >> Commands.clone(‘clone’, ‘rtomayko/tilt’)

  4. That method rewrites the args as it sees fit: >> args = “git://github.com/” + args + “.git”

    > “git://github.com/rtomayko/tilt.git”

  5. The new args are used to run ‘git`: >> exec “git”, “clone”, “git://github.com/rtomayko/tilt.git”

An optional ‘after` callback can be set. If so, it is run after step 5 (which then performs a `system` call rather than an `exec`). See `Hub::Args` for more information on the `after` callback.

Constant Summary collapse

API_REPO =
'http://github.com/api/v2/yaml/repos/show/%s/%s'
API_FORK =
'http://github.com/api/v2/yaml/repos/fork/%s/%s'

Constants included from Context

Hub::Context::GIT_CONFIG, Hub::Context::LGHCONF, Hub::Context::REMOTES

Instance Method Summary collapse

Methods included from Context

current_branch, current_remote, default_remote, github_token, github_url, github_user, http_clone?, normalize_branch, remote_for, repo_name, repo_owner, repo_user, tracked_branch, tracked_for

Instance Method Details

#alias(args) ⇒ Object



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/hub/commands.rb', line 295

def alias(args)
  shells = {
    'sh'   => 'alias git=hub',
    'bash' => 'alias git=hub',
    'zsh'  => 'function git(){hub "$@"}',
    'csh'  => 'alias git hub',
    'fish' => 'alias git hub'
  }

  silent = args.delete('-s')

  if shell = args[1]
    if silent.nil?
      puts "Run this in your shell to start using `hub` as `git`:"
      print "  "
    end
  else
    puts "usage: hub alias [-s] SHELL", ""
    puts "You already have hub installed and available in your PATH,"
    puts "but to get the full experience you'll want to alias it to"
    puts "`git`.", ""
    puts "To see how to accomplish this for your shell, run the alias"
    puts "command again with the name of your shell.", ""
    puts "Known shells:"
    shells.map { |key, _| key }.sort.each do |key|
      puts "  " + key
    end
    puts "", "Options:"
    puts "  -s   Silent. Useful when using the output with eval, e.g."
    puts "       $ eval `hub alias -s bash`"

    exit
  end

  if shells[shell]
    puts shells[shell]
  else
    abort "fatal: never heard of `#{shell}'"
  end

  exit
end

#browse(args) ⇒ Object

$ hub browse > open github.com/CURRENT_REPO

$ hub browse – issues > open github.com/CURRENT_REPO/issues

$ hub browse pjhyett/github-services > open github.com/pjhyett/github-services

$ hub browse -p pjhyett/github-fi > open github.com/pjhyett/github-fi

$ hub browse github-services > open github.com/YOUR_LOGIN/github-services

$ hub browse github-services wiki > open wiki.github.com/YOUR_LOGIN/github-services

$ hub browse -p github-fi > open github.com/YOUR_LOGIN/github-fi



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/hub/commands.rb', line 213

def browse(args)
  args.shift
  browse_command(args) do
    user = repo = nil
    dest = args.shift
    dest = nil if dest == '--'

    if dest
      # $ hub browse pjhyett/github-services
      # $ hub browse github-services
      repo = dest
    elsif repo_user
      # $ hub browse
      user = repo_user
    else
      abort "Usage: hub browse [<USER>/]<REPOSITORY>"
    end

    params = { :user => user, :repo => repo }

    # $ hub browse -- wiki
    case subpage = args.shift
    when 'wiki'
      params[:web] = 'wiki'
    when 'commits'
      branch = (!dest && tracked_branch) || 'master'
      params[:web] = "/commits/#{branch}"
    when 'tree', NilClass
      branch = !dest && tracked_branch
      params[:web] = "/tree/#{branch}" if branch && branch != 'master'
    else
      params[:web] = "/#{subpage}"
    end

    params
  end
end

#clone(args) ⇒ Object

$ hub clone rtomayko/tilt > git clone git://github.com/rtomayko/tilt.

$ hub clone -p kneath/hemingway > git clone [email protected]:kneath/hemingway.git

$ hub clone tilt > git clone git://github.com/YOUR_LOGIN/tilt.

$ hub clone -p github > git clone [email protected]:YOUR_LOGIN/hemingway.git



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/hub/commands.rb', line 54

def clone(args)
  ssh = args.delete('-p')

  last_args = args[1..-1].reject { |arg| arg == "--" }.last(3)
  last_args.each do |arg|
    if arg =~ /^-/
      # Skip mandatory arguments.
      last_args.shift if arg =~ /^(--(ref|o|br|u|t|d)[^=]+|-(o|b|u|d))$/
      next
    end

    if arg =~ %r{.+?://|.+?@} || File.directory?(arg)
      # Bail out early for URLs and local paths.
      break
    elsif arg.scan('/').size <= 1 && !arg.include?(':')
      # $ hub clone rtomayko/tilt
      # $ hub clone tilt
      args[args.index(arg)] = github_url(:repo => arg, :private => ssh)
      break
    end
  end
end

#compare(args) ⇒ Object

$ hub compare 1.0…fix > open github.com/CURRENT_REPO/compare/1.0…fix $ hub compare refactor > open github.com/CURRENT_REPO/compare/refactor $ hub compare myfork feature > open github.com/myfork/REPO/compare/feature $ hub compare -p myfork topsecret > open github.com/myfork/REPO/compare/topsecret $ hub compare -u 1.0…2.0 prints “github.com/CURRENT_REPO/compare/1.0…2.0



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/hub/commands.rb', line 261

def compare(args)
  args.shift
  browse_command(args) do
    if args.empty?
      branch = tracked_branch
      if branch && branch != 'master'
        range, user = branch, repo_user
      else
        abort "Usage: hub compare [USER] [<START>...]<END>"
      end
    else
      range = args.pop
      user = args.pop || repo_user
    end
    { :user => user, :web => "/compare/#{range}" }
  end
end

#fork(args) ⇒ Object

$ hub fork … hardcore forking action … > git remote add -f YOUR_USER [email protected]:YOUR_USER/CURRENT_REPO.git



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/hub/commands.rb', line 153

def fork(args)
  require 'net/http'

  # can't do anything without token and original owner name
  if github_user && github_token && repo_owner
    if own_repo_exists?
      puts "#{github_user}/#{repo_name} already exists on GitHub"
    else
      fork_repo
    end

    if args.include?('--no-remote')
      exit
    else
      url = github_url(:private => true)
      args.replace %W"remote add -f #{github_user} #{url}"
      args.after { puts "new remote: #{github_user}" }
    end
  end
end

#help(args) ⇒ Object Also known as: --help

$ hub help (print improved help text)



350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/hub/commands.rb', line 350

def help(args)
  command = args.grep(/^[^-]/)[1]

  if command == 'hub'
    puts hub_manpage
    exit
  elsif command.nil?
    ENV['GIT_PAGER'] = '' if args.grep(/^-{1,2}p/).empty? # Use `cat`.
    puts improved_help_text
    exit
  end
end

#hub(args) ⇒ Object

$ hub hub standalone Prints the “standalone” version of hub for an easy, memorable installation sequence:

$ gem install git-hub $ hub hub standalone > ~/bin/hub && chmod 755 ~/bin/hub $ gem uninstall git-hub



286
287
288
289
290
291
292
293
# File 'lib/hub/commands.rb', line 286

def hub(args)
  return help(args) unless args[1] == 'standalone'
  require 'hub/standalone'
  puts Hub::Standalone.build
  exit
rescue LoadError
  abort "hub is running in standalone mode."
end

#improved_help_textObject

The text print when ‘hub help` is run, kept in its own method for the convenience of the author.



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/hub/commands.rb', line 366

def improved_help_text
  <<-help
usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
[-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR]
[--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]

Basic Commands:
   init       Create an empty git repository or reinitialize an existing one
   add        Add new or modified files to the staging area
   rm         Remove files from the working directory and staging area
   mv         Move or rename a file, a directory, or a symlink
   status     Show the status of the working directory and staging area
   commit     Record changes to the repository

History Commands:
   log        Show the commit history log
   diff       Show changes between commits, commit and working tree, etc
   show       Show information about commits, tags or files

Branching Commands:
   branch     List, create, or delete branches
   checkout   Switch the active branch to another branch
   merge      Join two or more development histories (branches) together
   tag        Create, list, delete, sign or verify a tag object

Remote Commands:
   clone      Clone a remote repository into a new directory
   fetch      Download data, tags and branches from a remote repository
   pull       Fetch from and merge with another repository or a local branch
   push       Upload data, tags and branches to a remote repository
   remote     View and manage a set of remote repositories

Advanced commands:
   reset      Reset your staging area or working directory to another point
   rebase     Re-apply a series of patches in one branch onto another
   bisect     Find by binary search the change that introduced a bug
   grep       Print files with lines matching a pattern in your codebase

See 'git help COMMAND' for more information on a specific command.
help
end

#init(args) ⇒ Object

$ hub init -g > git init > git remote add origin [email protected]:USER/REPO.git



141
142
143
144
145
146
147
148
# File 'lib/hub/commands.rb', line 141

def init(args)
  if args.delete('-g')
    # Can't do anything if we don't have a USER set.

    url = github_url(:private => true)
    args.after "git remote add origin #{url}"
  end
end

#push(args) ⇒ Object

$ hub push origin,staging cool-feature > git push origin cool-feature > git push staging cool-feature



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/hub/commands.rb', line 177

def push(args)
  return unless args[1] =~ /,/

  branch  = args[2]
  remotes = args[1].split(',')
  args[1] = remotes.shift

  after = "git push #{remotes.shift} #{branch}"

  while remotes.length > 0
    after += "; git push #{remotes.shift} #{branch}"
  end

  args.after after
end

#remote(args) ⇒ Object

$ hub remote add pjhyett > git remote add pjhyett git://github.com/pjhyett/THIS_REPO.git

$ hub remote add -p mojombo > git remote add mojombo [email protected]:mojombo/THIS_REPO.git

$ hub remote add origin > git remote add origin git://github.com/YOUR_LOGIN/THIS_REPO.git



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/hub/commands.rb', line 111

def remote(args)
  return if args[1] != 'add' || args.last =~ %r{.+?://|.+?@|^[./]}

  ssh = args.delete('-p')

  # user/repo
  args.last =~ /\b(.+?)(?:\/(.+))?$/
  user, repo = $1, $2

  if args.words[2] == 'origin' && args.words[3].nil?
    # Origin special case triggers default user/repo
    user = repo = nil
  elsif args.words[-2] == args.words[1]
    # rtomayko/tilt => rtomayko
    # Make sure you dance around flags.
    idx = args.index( args.words[-1] )
    args[idx] = user
  else
    # They're specifying the remote name manually (e.g.
    # git remote add blah rtomayko/tilt), so just drop the last
    # argument.
    args.replace args[0...-1]
  end

  args << github_url(:user => user, :repo => repo, :private => ssh)
end

#submodule(args) ⇒ Object

$ hub submodule add wycats/bundler vendor/bundler > git submodule add git://github.com/wycats/bundler.git vendor/bundler

$ hub submodule add -p wycats/bundler vendor/bundler > git submodule add [email protected]:wycats/bundler.git vendor/bundler

$ hub submodule add -b ryppl ryppl/pip vendor/bundler > git submodule add -b ryppl git://github.com/ryppl/pip.git vendor/pip



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/hub/commands.rb', line 85

def submodule(args)
  return unless index = args.index('add')
  args.delete_at index

  branch = args.index('-b') || args.index('--branch')
  if branch
    args.delete_at branch
    branch_name = args.delete_at branch
  end

  clone(args)

  if branch_name
    args.insert branch, '-b', branch_name
  end
  args.insert index, 'add'
end

#version(args) ⇒ Object Also known as: --version

$ hub version > git version (print hub version)



341
342
343
344
345
# File 'lib/hub/commands.rb', line 341

def version(args)
  args.after do
    puts "hub version %s" % Version
  end
end