git-hub 1.4.1 → 1.5.0

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.
@@ -7,15 +7,16 @@ hub(1) -- git + hub = github
7
7
  `hub alias` [`-s`] <SHELL>
8
8
 
9
9
  `git init -g` <OPTIONS>
10
- `git create` [`-p`] [`-d <DESCRIPTION>`] [`-h <HOMEPAGE>`]:
10
+ `git create` [`-p`] [`-d <DESCRIPTION>`] [`-h <HOMEPAGE>`]
11
11
  `git clone` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>
12
12
  `git remote add` [`-p`] <OPTIONS> <USER>[/<REPOSITORY>]
13
13
  `git remote set-url` [`-p`] <OPTIONS> <REMOTE-NAME> <USER>[/<REPOSITORY>]
14
14
  `git fetch` <USER-1>,[<USER-2>,...]
15
15
  `git cherry-pick` <GITHUB-REF>
16
+ `git am` <GITHUB-URL>
16
17
  `git push` <REMOTE-1>,<REMOTE-2>,...,<REMOTE-N> <REF>
17
- `git browse` [`-p`] [`-u`] [[<USER>`/`]<REPOSITORY>] [SUBPAGE]
18
- `git compare` [`-p`] [`-u`] [<USER>] [<START>...]<END>
18
+ `git browse` [`-u`] [[<USER>`/`]<REPOSITORY>] [SUBPAGE]
19
+ `git compare` [`-u`] [<USER>] [<START>...]<END>
19
20
  `git submodule add` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>
20
21
  `git fork` [`--no-remote`]
21
22
 
@@ -35,7 +36,7 @@ alias command displays information on configuring your environment:
35
36
  "git@github.com:<USER>/<REPOSITORY>.git"; <USER> is your GitHub username and
36
37
  <REPOSITORY> is the current working directory's basename.
37
38
 
38
- * `git create` [`-p`] [`-d <DESCRIPTION>`] [`-h <HOMEPAGE>`]:
39
+ * `git create` [`-p`] [`-d <DESCRIPTION>`] [`-h <HOMEPAGE>`]:
39
40
  Create a new public github repository from the current git
40
41
  repository and add remote `origin` at
41
42
  "git@github.com:<USER>/<REPOSITORY>.git"; <USER> is your GitHub
@@ -43,13 +44,13 @@ alias command displays information on configuring your environment:
43
44
  basename. With `-p`, create a private repository. `-d` and `-h`
44
45
  set the repository's description and homepage, respectively.
45
46
 
46
- * `git clone` [`-p`] <OPTIONS> [<USER>`/`]<REPOSITORY> <DIRECTORY>:
47
+ * `git clone` [`-p`] <OPTIONS> [<USER>`/`]<REPOSITORY> <DIRECTORY>:
47
48
  Clone repository "git://github.com/<USER>/<REPOSITORY>.git" into
48
49
  <DIRECTORY> as with git-clone(1). When <USER>/ is omitted, assumes
49
50
  your GitHub login. With `-p`, use private remote
50
51
  "git@github.com:<USER>/<REPOSITORY>.git".
51
52
 
52
- * `git remote add` [`-p`] <OPTIONS> <USER>[`/`<REPOSITORY>]:
53
+ * `git remote add` [`-p`] <OPTIONS> <USER>[`/`<REPOSITORY>]:
53
54
  Add remote "git://github.com/<USER>/<REPOSITORY>.git" as with
54
55
  git-remote(1). When /<REPOSITORY> is omitted, the basename of the
55
56
  current working directory is used. With `-p`, use private remote
@@ -70,25 +71,30 @@ alias command displays information on configuring your environment:
70
71
  doesn't yet exist, it will be added. A `git fetch <user>` is issued
71
72
  prior to the cherry-pick attempt.
72
73
 
74
+ * `git am` <GITHUB-URL>:
75
+ Downloads the patch file for the pull request or commit at the URL and
76
+ applies that patch from disk with `git am`. Similar to `cherry-pick`, but
77
+ doesn't add new remotes.
78
+
73
79
  * `git push` <REMOTE-1>,<REMOTE-2>,...,<REMOTE-N> <REF>:
74
80
  Push <REF> to each of <REMOTE-1> through <REMOTE-N> by executing
75
81
  multiple `git push` commands.
76
82
 
77
- * `git browse` [`-p`] [`-u`] [[<USER>`/`]<REPOSITORY>] [SUBPAGE]:
78
- Open repository's GitHub page in the system's default web browser
79
- using `open(1)` or the `BROWSER` env variable. Use `-p` to open a
80
- page with https. If the repository isn't specified, `browse` opens
81
- the page of the repository found in the current directory. If SUBPAGE
82
- is specified, the browser will open on the specified subpage: one of
83
- "wiki", "commits", "issues" or other (the default is "tree").
83
+ * `git browse` [`-u`] [[<USER>`/`]<REPOSITORY>] [SUBPAGE]:
84
+ Open repository's GitHub page in the system's default web browser using
85
+ `open(1)` or the `BROWSER` env variable. If the repository isn't
86
+ specified, `browse` opens the page of the repository found in the current
87
+ directory. If SUBPAGE is specified, the browser will open on the specified
88
+ subpage: one of "wiki", "commits", "issues" or other (the default is
89
+ "tree").
84
90
 
85
- * `git compare` [`-p`] [`-u`] [<USER>] [<START>...]<END>:
91
+ * `git compare` [`-u`] [<USER>] [<START>...]<END>:
86
92
  Open a GitHub compare view page in the system's default web browser.
87
93
  <START> to <END> are branch names, tag names, or commit SHA1s specifying
88
94
  the range of history to compare. If <START> is omitted, GitHub will
89
95
  compare against the base branch (the default is "master").
90
96
 
91
- * `git submodule add` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>:
97
+ * `git submodule add` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>:
92
98
  Submodule repository "git://github.com/<USER>/<REPOSITORY>.git" into
93
99
  <DIRECTORY> as with git-submodule(1). When <USER>/ is omitted, assumes
94
100
  your GitHub login. With `-p`, use private remote
@@ -121,6 +127,14 @@ cloning:
121
127
 
122
128
  $ git config --global --bool hub.http-clone true
123
129
 
130
+ Want to use environment variables instead of a local gitconfig for
131
+ authentication?
132
+
133
+ * `GITHUB_USER` - If set, this will be used instead of the `github.user` config
134
+ value to determine your GitHub username.
135
+ * `GITHUB_TOKEN` - If set, this will be used instead of the `github.token`
136
+ config value to determine your GitHub API token.
137
+
124
138
  ## EXAMPLES
125
139
 
126
140
  ### git clone
@@ -173,6 +187,16 @@ cloning:
173
187
  > git fetch mislav
174
188
  > git cherry-pick SHA
175
189
 
190
+ ### git am
191
+
192
+ $ git am https://github.com/defunkt/hub/pull/55
193
+ > curl https://github.com/defunkt/hub/pull/55.patch -o /tmp/55.patch
194
+ > git am /tmp/55.patch
195
+
196
+ $ git am --ignore-whitespace https://github.com/davidbalbert/hub/commit/fdb9921
197
+ > curl https://github.com/davidbalbert/hub/commit/fdb9921.patch -o /tmp/fdb9921.patch
198
+ > git am --ignore-whitespace /tmp/fdb9921.patch
199
+
176
200
  ### git fork
177
201
 
178
202
  $ git fork
@@ -201,39 +225,33 @@ cloning:
201
225
  ### git browse
202
226
 
203
227
  $ git browse
204
- > open http://github.com/CURRENT_REPO
228
+ > open https://github.com/CURRENT_REPO
205
229
 
206
230
  $ git browse -- issues
207
- > open http://github.com/CURRENT_REPO/issues
231
+ > open https://github.com/CURRENT_REPO/issues
208
232
 
209
233
  $ git browse schacon/ticgit
210
- > open http://github.com/schacon/ticgit
211
-
212
- $ git browse -p schacon/ticgit
213
234
  > open https://github.com/schacon/ticgit
214
235
 
215
236
  $ git browse resque
216
- > open http://github.com/YOUR_USER/resque
237
+ > open https://github.com/YOUR_USER/resque
217
238
 
218
239
  $ git browse resque network
219
- > open http://github.com/YOUR_USER/resque/network
220
-
221
- $ git browse -p resque
222
- > open https://github.com/YOUR_USER/resque
240
+ > open https://github.com/YOUR_USER/resque/network
223
241
 
224
242
  ### git compare
225
243
 
226
244
  $ git compare refactor
227
- > open http://github.com/CURRENT_REPO/compare/refactor
245
+ > open https://github.com/CURRENT_REPO/compare/refactor
228
246
 
229
247
  $ git compare 1.0...1.1
230
- > open http://github.com/CURRENT_REPO/compare/1.0...1.1
248
+ > open https://github.com/CURRENT_REPO/compare/1.0...1.1
231
249
 
232
250
  $ git compare -u fix
233
- > (http://github.com/CURRENT_REPO/compare/fix)
251
+ > (https://github.com/CURRENT_REPO/compare/fix)
234
252
 
235
253
  $ git compare other-user patch
236
- > open http://github.com/other-user/REPO/compare/patch
254
+ > open https://github.com/other-user/REPO/compare/patch
237
255
 
238
256
  ### git help
239
257
 
@@ -246,9 +264,9 @@ cloning:
246
264
 
247
265
  <http://github.com/defunkt/hub/issues>
248
266
 
249
- ## AUTHOR
267
+ ## AUTHORS
250
268
 
251
- Chris Wanstrath :: chris@ozmm.org :: @defunkt
269
+ <https://github.com/defunkt/hub/contributors>
252
270
 
253
271
  ## SEE ALSO
254
272
 
@@ -1,6 +1,10 @@
1
1
  #!/bin/sh
2
- if [[ $1 == "--version" ]]; then
2
+ if [ "$1" = "--version" ]; then
3
3
  echo "git version 1.7.0.4"
4
+ elif [ "$1" = "--exec-path" ]; then
5
+ echo "/usr/lib/git-core"
6
+ elif [ "$1" = "--html-path" ]; then
7
+ echo "/usr/share/doc/git-doc"
4
8
  else
5
9
  echo "ERROR: git was called, but wasn't supposed to:" git $*
6
10
  exit 1
@@ -70,6 +70,17 @@ class Test::Unit::TestCase
70
70
  assert_equal expected, Hub(input).command, "$ git #{input}"
71
71
  end
72
72
 
73
+ def assert_commands(*expected)
74
+ input = expected.pop
75
+ assert_equal expected, Hub(input).commands
76
+ end
77
+
78
+ # Asserts that the command will be forwarded to git without changes
79
+ def assert_forwarded(input)
80
+ cmd = Hub(input)
81
+ assert !cmd.args.changed?, "arguments were not supposed to change: #{cmd.args.inspect}"
82
+ end
83
+
73
84
  # Asserts that `hub` will show a specific alias command for a
74
85
  # specific shell.
75
86
  #
@@ -2,8 +2,18 @@ $LOAD_PATH.unshift File.dirname(__FILE__)
2
2
  require 'helper'
3
3
  require 'webmock/test_unit'
4
4
 
5
+ WebMock::BodyPattern.class_eval do
6
+ undef normalize_hash
7
+ # override normalizing hash since it otherwise requires JSON
8
+ def normalize_hash(hash) hash end
9
+ end
10
+
5
11
  class HubTest < Test::Unit::TestCase
6
- include WebMock
12
+ if defined? WebMock::API
13
+ include WebMock::API
14
+ else
15
+ include WebMock
16
+ end
7
17
 
8
18
  COMMANDS = []
9
19
 
@@ -16,6 +26,8 @@ class HubTest < Test::Unit::TestCase
16
26
 
17
27
  def setup
18
28
  COMMANDS.replace %w[open groff]
29
+ Hub::Context::DIRNAME.replace 'hub'
30
+ Hub::Context::REMOTES.clear
19
31
 
20
32
  @git = Hub::Context::GIT_CONFIG.replace(Hash.new { |h, k|
21
33
  raise ArgumentError, "`git #{k}` not stubbed"
@@ -24,8 +36,8 @@ class HubTest < Test::Unit::TestCase
24
36
  'symbolic-ref -q HEAD' => 'refs/heads/master',
25
37
  'config github.user' => 'tpw',
26
38
  'config github.token' => 'abc123',
27
- 'config remote.origin.url' => 'git://github.com/defunkt/hub.git',
28
- 'config remote.mislav.url' => 'git://github.com/mislav/hub.git',
39
+ 'config --get-all remote.origin.url' => 'git://github.com/defunkt/hub.git',
40
+ 'config --get-all remote.mislav.url' => 'git://github.com/mislav/hub.git',
29
41
  'config branch.master.remote' => 'origin',
30
42
  'config branch.master.merge' => 'refs/heads/master',
31
43
  'config branch.feature.remote' => 'mislav',
@@ -228,18 +240,18 @@ class HubTest < Test::Unit::TestCase
228
240
  stub_remotes_group('xoebus', nil)
229
241
  stub_existing_fork('xoebus')
230
242
 
231
- h = Hub("fetch xoebus")
232
- assert_equal "git remote add xoebus git://github.com/xoebus/hub.git", h.command
233
- assert_equal "git fetch xoebus", h.after
243
+ assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
244
+ "git fetch xoebus",
245
+ "fetch xoebus"
234
246
  end
235
247
 
236
248
  def test_fetch_new_remote_with_options
237
249
  stub_remotes_group('xoebus', nil)
238
250
  stub_existing_fork('xoebus')
239
251
 
240
- h = Hub("fetch --depth=1 --prune xoebus")
241
- assert_equal "git remote add xoebus git://github.com/xoebus/hub.git", h.command
242
- assert_equal "git fetch --depth=1 --prune xoebus", h.after
252
+ assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
253
+ "git fetch --depth=1 --prune xoebus",
254
+ "fetch --depth=1 --prune xoebus"
243
255
  end
244
256
 
245
257
  def test_fetch_multiple_new_remotes
@@ -248,12 +260,10 @@ class HubTest < Test::Unit::TestCase
248
260
  stub_existing_fork('xoebus')
249
261
  stub_existing_fork('rtomayko')
250
262
 
251
- h = Hub("fetch --multiple xoebus rtomayko")
252
-
253
- assert_equal "git remote add xoebus git://github.com/xoebus/hub.git", h.command
254
- expected = ["git remote add rtomayko git://github.com/rtomayko/hub.git"] <<
255
- "git fetch --multiple xoebus rtomayko"
256
- assert_equal expected.join('; '), h.after
263
+ assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
264
+ "git remote add rtomayko git://github.com/rtomayko/hub.git",
265
+ "git fetch --multiple xoebus rtomayko",
266
+ "fetch --multiple xoebus rtomayko"
257
267
  end
258
268
 
259
269
  def test_fetch_multiple_comma_separated_remotes
@@ -262,12 +272,10 @@ class HubTest < Test::Unit::TestCase
262
272
  stub_existing_fork('xoebus')
263
273
  stub_existing_fork('rtomayko')
264
274
 
265
- h = Hub("fetch xoebus,rtomayko")
266
-
267
- assert_equal "git remote add xoebus git://github.com/xoebus/hub.git", h.command
268
- expected = ["git remote add rtomayko git://github.com/rtomayko/hub.git"] <<
269
- "git fetch --multiple xoebus rtomayko"
270
- assert_equal expected.join('; '), h.after
275
+ assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
276
+ "git remote add rtomayko git://github.com/rtomayko/hub.git",
277
+ "git fetch --multiple xoebus rtomayko",
278
+ "fetch xoebus,rtomayko"
271
279
  end
272
280
 
273
281
  def test_fetch_multiple_new_remotes_with_filtering
@@ -282,84 +290,80 @@ class HubTest < Test::Unit::TestCase
282
290
  # mygrp: a remotes group; skipped
283
291
  # URL: can't be a username; skipped
284
292
  # typo: fork doesn't exist; skipped
285
- h = Hub("fetch --multiple mislav xoebus mygrp git://example.com typo")
286
-
287
- assert_equal "git remote add xoebus git://github.com/xoebus/hub.git", h.command
288
- expected = "git fetch --multiple mislav xoebus mygrp git://example.com typo"
289
- assert_equal expected, h.after
293
+ assert_commands "git remote add xoebus git://github.com/xoebus/hub.git",
294
+ "git fetch --multiple mislav xoebus mygrp git://example.com typo",
295
+ "fetch --multiple mislav xoebus mygrp git://example.com typo"
290
296
  end
291
297
 
292
298
  def test_cherry_pick
293
- h = Hub("cherry-pick a319d88")
294
- assert_equal "git cherry-pick a319d88", h.command
295
- assert !h.args.after?
299
+ assert_forwarded "cherry-pick a319d88"
296
300
  end
297
301
 
298
302
  def test_cherry_pick_url
299
303
  url = 'http://github.com/mislav/hub/commit/a319d88'
300
- h = Hub("cherry-pick #{url}")
301
- assert_equal "git fetch mislav", h.command
302
- assert_equal "git cherry-pick a319d88", h.after
304
+ assert_commands "git fetch mislav", "git cherry-pick a319d88", "cherry-pick #{url}"
303
305
  end
304
306
 
305
307
  def test_cherry_pick_url_with_fragment
306
308
  url = 'http://github.com/mislav/hub/commit/abcdef0123456789#comments'
307
- h = Hub("cherry-pick #{url}")
308
- assert_equal "git fetch mislav", h.command
309
- assert_equal "git cherry-pick abcdef0123456789", h.after
309
+ assert_commands "git fetch mislav", "git cherry-pick abcdef0123456789", "cherry-pick #{url}"
310
310
  end
311
311
 
312
312
  def test_cherry_pick_url_with_remote_add
313
- url = 'http://github.com/xoebus/hub/commit/a319d88'
314
- h = Hub("cherry-pick #{url}")
315
- assert_equal "git remote add -f xoebus git://github.com/xoebus/hub.git", h.command
316
- assert_equal "git cherry-pick a319d88", h.after
317
- end
318
-
319
- def test_cherry_pick_private_url_with_remote_add
320
313
  url = 'https://github.com/xoebus/hub/commit/a319d88'
321
- h = Hub("cherry-pick #{url}")
322
- assert_equal "git remote add -f xoebus git@github.com:xoebus/hub.git", h.command
323
- assert_equal "git cherry-pick a319d88", h.after
314
+ assert_commands "git remote add -f xoebus git://github.com/xoebus/hub.git",
315
+ "git cherry-pick a319d88",
316
+ "cherry-pick #{url}"
324
317
  end
325
318
 
326
319
  def test_cherry_pick_origin_url
327
320
  url = 'https://github.com/defunkt/hub/commit/a319d88'
328
- h = Hub("cherry-pick #{url}")
329
- assert_equal "git fetch origin", h.command
330
- assert_equal "git cherry-pick a319d88", h.after
321
+ assert_commands "git fetch origin", "git cherry-pick a319d88", "cherry-pick #{url}"
331
322
  end
332
323
 
333
324
  def test_cherry_pick_github_user_notation
334
- h = Hub("cherry-pick mislav@a319d88")
335
- assert_equal "git fetch mislav", h.command
336
- assert_equal "git cherry-pick a319d88", h.after
325
+ assert_commands "git fetch mislav", "git cherry-pick a319d88", "cherry-pick mislav@a319d88"
337
326
  end
338
327
 
339
328
  def test_cherry_pick_github_user_repo_notation
340
329
  # not supported
341
- h = Hub("cherry-pick mislav/hubbub@a319d88")
342
- assert_equal "git cherry-pick mislav/hubbub@a319d88", h.command
343
- assert !h.args.after?
330
+ assert_forwarded "cherry-pick mislav/hubbub@a319d88"
344
331
  end
345
332
 
346
333
  def test_cherry_pick_github_notation_too_short
347
- h = Hub("cherry-pick mislav@a319")
348
- assert_equal "git cherry-pick mislav@a319", h.command
349
- assert !h.args.after?
334
+ assert_forwarded "cherry-pick mislav@a319"
350
335
  end
351
336
 
352
337
  def test_cherry_pick_github_notation_with_remote_add
353
- h = Hub("cherry-pick xoebus@a319d88")
354
- assert_equal "git remote add -f xoebus git://github.com/xoebus/hub.git", h.command
355
- assert_equal "git cherry-pick a319d88", h.after
338
+ assert_commands "git remote add -f xoebus git://github.com/xoebus/hub.git",
339
+ "git cherry-pick a319d88",
340
+ "cherry-pick xoebus@a319d88"
341
+ end
342
+
343
+ def test_am_untouched
344
+ assert_forwarded "am some.patch"
345
+ end
346
+
347
+ def test_am_pull_request
348
+ with_tmpdir('/tmp/') do
349
+ assert_commands "curl -#LA 'hub #{Hub::Version}' https://github.com/defunkt/hub/pull/55.patch -o /tmp/55.patch",
350
+ "git am --signoff /tmp/55.patch -p2",
351
+ "am --signoff https://github.com/defunkt/hub/pull/55 -p2"
352
+ end
353
+ end
354
+
355
+ def test_am_commit_url
356
+ with_tmpdir('/tmp/') do
357
+ url = 'https://github.com/davidbalbert/hub/commit/fdb9921'
358
+
359
+ assert_commands "curl -#LA 'hub #{Hub::Version}' #{url}.patch -o /tmp/fdb9921.patch",
360
+ "git am --signoff /tmp/fdb9921.patch -p2",
361
+ "am --signoff #{url} -p2"
362
+ end
356
363
  end
357
364
 
358
365
  def test_init
359
- dirname = File.basename(Dir.pwd)
360
- h = Hub("init -g")
361
- assert_equal "git init", h.command
362
- assert_equal "git remote add origin git@github.com:tpw/#{dirname}.git", h.after
366
+ assert_commands "git init", "git remote add origin git@github.com:tpw/hub.git", "init -g"
363
367
  end
364
368
 
365
369
  def test_init_no_login
@@ -371,55 +375,75 @@ class HubTest < Test::Unit::TestCase
371
375
  end
372
376
 
373
377
  def test_push_two
374
- h = Hub("push origin,staging cool-feature")
375
- assert_equal "git push origin cool-feature", h.command
376
- assert_equal "git push staging cool-feature", h.after
378
+ assert_commands "git push origin cool-feature", "git push staging cool-feature",
379
+ "push origin,staging cool-feature"
377
380
  end
378
381
 
379
382
  def test_push_more
380
- h = Hub("push origin,staging,qa cool-feature")
381
- assert_equal "git push origin cool-feature", h.command
382
- assert_equal "git push staging cool-feature; git push qa cool-feature", h.after
383
+ assert_commands "git push origin cool-feature",
384
+ "git push staging cool-feature",
385
+ "git push qa cool-feature",
386
+ "push origin,staging,qa cool-feature"
383
387
  end
384
388
 
385
389
  def test_create
386
- Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
390
+ stub_no_remotes
387
391
  stub_nonexisting_fork('tpw')
388
- stub_request(:post, "github.com/api/v2/yaml/repos/create").with { |req|
389
- params = Hash[*req.body.split(/[&=]/)]
390
- params == { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub' }
391
- }
392
+ stub_request(:post, "github.com/api/v2/yaml/repos/create").
393
+ with(:body => { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub' })
394
+
392
395
  expected = "remote add -f origin git@github.com:tpw/hub.git\n"
393
396
  expected << "created repository: tpw/hub\n"
394
397
  assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
395
398
  end
396
399
 
400
+ def test_create_with_env_authentication
401
+ stub_no_remotes
402
+ stub_nonexisting_fork('mojombo')
403
+
404
+ old_user = ENV['GITHUB_USER']
405
+ old_token = ENV['GITHUB_TOKEN']
406
+ ENV['GITHUB_USER'] = 'mojombo'
407
+ ENV['GITHUB_TOKEN'] = '123abc'
408
+
409
+ stub_request(:post, "github.com/api/v2/yaml/repos/create").
410
+ with(:body => { 'login'=>'mojombo', 'token'=>'123abc', 'name' => 'hub' })
411
+
412
+ expected = "remote add -f origin git@github.com:mojombo/hub.git\n"
413
+ expected << "created repository: mojombo/hub\n"
414
+ assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
415
+
416
+ ensure
417
+ ENV['GITHUB_USER'] = old_user
418
+ ENV['GITHUB_TOKEN'] = old_token
419
+ end
420
+
397
421
  def test_create_private_repository
398
- Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
422
+ stub_no_remotes
399
423
  stub_nonexisting_fork('tpw')
400
- stub_request(:post, "github.com/api/v2/yaml/repos/create").with { |req|
401
- params = Hash[*req.body.split(/[&=]/)]
402
- params == { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub', 'public' => '0' }
403
- }
424
+ stub_request(:post, "github.com/api/v2/yaml/repos/create").
425
+ with(:body => { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub', 'public' => '0' })
426
+
404
427
  expected = "remote add -f origin git@github.com:tpw/hub.git\n"
405
428
  expected << "created repository: tpw/hub\n"
406
429
  assert_equal expected, hub("create -p") { ENV['GIT'] = 'echo' }
407
430
  end
408
431
 
409
432
  def test_create_with_description_and_homepage
410
- Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
433
+ stub_no_remotes
411
434
  stub_nonexisting_fork('tpw')
412
- stub_request(:post, "github.com/api/v2/yaml/repos/create").with { |req|
413
- params = Hash[*req.body.split(/[&=]/)]
414
- params == { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub', 'description' => 'description', 'homepage' => 'http%3a%2f%2fgithub.com%2ftpw%2fhub.git' }
415
- }
435
+ stub_request(:post, "github.com/api/v2/yaml/repos/create").with(:body => {
436
+ 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub',
437
+ 'description' => 'toyproject', 'homepage' => 'http://example.com'
438
+ })
439
+
416
440
  expected = "remote add -f origin git@github.com:tpw/hub.git\n"
417
441
  expected << "created repository: tpw/hub\n"
418
- assert_equal expected, hub("create -d description -h http://github.com/tpw/hub.git") { ENV['GIT'] = 'echo' }
442
+ assert_equal expected, hub("create -d toyproject -h http://example.com") { ENV['GIT'] = 'echo' }
419
443
  end
420
444
 
421
445
  def test_create_with_existing_repository
422
- Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
446
+ stub_no_remotes
423
447
  stub_existing_fork('tpw')
424
448
 
425
449
  expected = "tpw/hub already exists on GitHub\n"
@@ -429,7 +453,7 @@ class HubTest < Test::Unit::TestCase
429
453
  end
430
454
 
431
455
  def test_create_no_user
432
- Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
456
+ stub_no_remotes
433
457
  out = hub("create") do
434
458
  stub_github_token(nil)
435
459
  end
@@ -437,19 +461,14 @@ class HubTest < Test::Unit::TestCase
437
461
  end
438
462
 
439
463
  def test_create_outside_git_repo
440
- @git = Hub::Context::GIT_CONFIG.replace(Hash.new { |h, k|
441
- nil
442
- })
443
-
464
+ stub_no_git_repo
444
465
  assert_equal "'create' must be run from inside a git repository\n", hub("create")
445
466
  end
446
467
 
447
468
  def test_create_origin_already_exists
448
469
  stub_nonexisting_fork('tpw')
449
- stub_request(:post, "github.com/api/v2/yaml/repos/create").with { |req|
450
- params = Hash[*req.body.split(/[&=]/)]
451
- params == { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub' }
452
- }
470
+ stub_request(:post, "github.com/api/v2/yaml/repos/create").
471
+ with(:body => { 'login'=>'tpw', 'token'=>'abc123', 'name' => 'hub' })
453
472
 
454
473
  expected = "remote -v\ncreated repository: tpw/hub\n"
455
474
  assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
@@ -457,10 +476,8 @@ class HubTest < Test::Unit::TestCase
457
476
 
458
477
  def test_fork
459
478
  stub_nonexisting_fork('tpw')
460
- stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub").with { |req|
461
- params = Hash[*req.body.split(/[&=]/)]
462
- params == { 'login'=>'tpw', 'token'=>'abc123' }
463
- }
479
+ stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub").
480
+ with(:body => { 'login'=>'tpw', 'token'=>'abc123' })
464
481
 
465
482
  expected = "remote add -f tpw git@github.com:tpw/hub.git\n"
466
483
  expected << "new remote: tpw\n"
@@ -489,6 +506,21 @@ class HubTest < Test::Unit::TestCase
489
506
  assert_includes "hub version #{Hub::Version}", out
490
507
  end
491
508
 
509
+ def test_exec_path
510
+ out = hub('--exec-path')
511
+ assert_equal "/usr/lib/git-core\n", out
512
+ end
513
+
514
+ def test_exec_path_arg
515
+ out = hub('--exec-path=/home/wombat/share/my-l33t-git-core')
516
+ assert_equal Hub::Commands.improved_help_text, hub("")
517
+ end
518
+
519
+ def test_html_path
520
+ out = hub('--html-path')
521
+ assert_equal "/usr/share/doc/git-doc\n", out
522
+ end
523
+
492
524
  def test_help
493
525
  assert_equal Hub::Commands.improved_help_text, hub("help")
494
526
  end
@@ -504,7 +536,6 @@ class HubTest < Test::Unit::TestCase
504
536
  def test_help_hub
505
537
  help_manpage = hub("help hub")
506
538
  assert_includes "git + hub = github", help_manpage
507
- assert_includes "Chris Wanstrath :: chris@ozmm.org", help_manpage
508
539
  assert_includes <<-config, help_manpage
509
540
  Use git-config(1) to display the currently configured GitHub username:
510
541
  config
@@ -522,7 +553,7 @@ config
522
553
 
523
554
  def test_hub_compare
524
555
  assert_command "compare refactor",
525
- "open http://github.com/defunkt/hub/compare/refactor"
556
+ "open https://github.com/defunkt/hub/compare/refactor"
526
557
  end
527
558
 
528
559
  def test_hub_compare_nothing
@@ -540,93 +571,81 @@ config
540
571
  stub_branch('refs/heads/feature')
541
572
 
542
573
  assert_command "compare",
543
- "open http://github.com/mislav/hub/compare/experimental"
574
+ "open https://github.com/mislav/hub/compare/experimental"
544
575
  end
545
576
 
546
577
  def test_hub_compare_range
547
578
  assert_command "compare 1.0...fix",
548
- "open http://github.com/defunkt/hub/compare/1.0...fix"
579
+ "open https://github.com/defunkt/hub/compare/1.0...fix"
549
580
  end
550
581
 
551
582
  def test_hub_compare_fork
552
583
  assert_command "compare myfork feature",
553
- "open http://github.com/myfork/hub/compare/feature"
554
- end
555
-
556
- def test_hub_compare_private
557
- assert_command "compare -p myfork topsecret",
558
- "open https://github.com/myfork/hub/compare/topsecret"
584
+ "open https://github.com/myfork/hub/compare/feature"
559
585
  end
560
586
 
561
587
  def test_hub_compare_url
562
588
  assert_command "compare -u 1.0...1.1",
563
- "echo http://github.com/defunkt/hub/compare/1.0...1.1"
589
+ "echo https://github.com/defunkt/hub/compare/1.0...1.1"
564
590
  end
565
591
 
566
592
  def test_hub_browse
567
- assert_command "browse mojombo/bert", "open http://github.com/mojombo/bert"
593
+ assert_command "browse mojombo/bert", "open https://github.com/mojombo/bert"
568
594
  end
569
595
 
570
596
  def test_hub_browse_tracking_nothing
571
597
  stub_tracking_nothing
572
- assert_command "browse mojombo/bert", "open http://github.com/mojombo/bert"
598
+ assert_command "browse mojombo/bert", "open https://github.com/mojombo/bert"
573
599
  end
574
600
 
575
601
  def test_hub_browse_url
576
- assert_command "browse -u mojombo/bert", "echo http://github.com/mojombo/bert"
577
- end
578
-
579
- def test_hub_browse_private
580
- assert_command "browse -p bmizerany/sinatra",
581
- "open https://github.com/bmizerany/sinatra"
602
+ assert_command "browse -u mojombo/bert", "echo https://github.com/mojombo/bert"
582
603
  end
583
604
 
584
605
  def test_hub_browse_self
585
- assert_command "browse resque", "open http://github.com/tpw/resque"
606
+ assert_command "browse resque", "open https://github.com/tpw/resque"
586
607
  end
587
608
 
588
609
  def test_hub_browse_subpage
589
610
  assert_command "browse resque commits",
590
- "open http://github.com/tpw/resque/commits/master"
611
+ "open https://github.com/tpw/resque/commits/master"
591
612
  assert_command "browse resque issues",
592
- "open http://github.com/tpw/resque/issues"
613
+ "open https://github.com/tpw/resque/issues"
593
614
  assert_command "browse resque wiki",
594
- "open http://wiki.github.com/tpw/resque/"
615
+ "open https://github.com/tpw/resque/wiki"
595
616
  end
596
617
 
597
618
  def test_hub_browse_on_branch
598
619
  stub_branch('refs/heads/feature')
599
620
 
600
- assert_command "browse resque", "open http://github.com/tpw/resque"
621
+ assert_command "browse resque", "open https://github.com/tpw/resque"
601
622
  assert_command "browse resque commits",
602
- "open http://github.com/tpw/resque/commits/master"
623
+ "open https://github.com/tpw/resque/commits/master"
603
624
 
604
625
  assert_command "browse",
605
- "open http://github.com/mislav/hub/tree/experimental"
626
+ "open https://github.com/mislav/hub/tree/experimental"
606
627
  assert_command "browse -- tree",
607
- "open http://github.com/mislav/hub/tree/experimental"
628
+ "open https://github.com/mislav/hub/tree/experimental"
608
629
  assert_command "browse -- commits",
609
- "open http://github.com/mislav/hub/commits/experimental"
610
- end
611
-
612
- def test_hub_browse_self_private
613
- assert_command "browse -p github", "open https://github.com/tpw/github"
630
+ "open https://github.com/mislav/hub/commits/experimental"
614
631
  end
615
632
 
616
633
  def test_hub_browse_current
617
- assert_command "browse", "open http://github.com/defunkt/hub"
618
- assert_command "browse --", "open http://github.com/defunkt/hub"
634
+ assert_command "browse", "open https://github.com/defunkt/hub"
635
+ assert_command "browse --", "open https://github.com/defunkt/hub"
619
636
  end
620
637
 
621
638
  def test_hub_browse_current_subpage
622
639
  assert_command "browse -- network",
623
- "open http://github.com/defunkt/hub/network"
640
+ "open https://github.com/defunkt/hub/network"
624
641
  assert_command "browse -- anything/everything",
625
- "open http://github.com/defunkt/hub/anything/everything"
642
+ "open https://github.com/defunkt/hub/anything/everything"
626
643
  end
627
644
 
628
- def test_hub_browse_current_private
629
- assert_command "browse -p", "open https://github.com/defunkt/hub"
645
+ def test_hub_browse_deprecated_private
646
+ with_browser_env('echo') do
647
+ assert_includes "Warning: the `-p` flag has no effect anymore\n", hub("browse -p defunkt/hub")
648
+ end
630
649
  end
631
650
 
632
651
  def test_hub_browse_no_repo
@@ -668,6 +687,20 @@ config
668
687
  end
669
688
  end
670
689
 
690
+ def test_context_method_doesnt_hijack_git_command
691
+ assert_command 'remotes', 'git remotes'
692
+ end
693
+
694
+ def test_not_choking_on_ruby_methods
695
+ assert_forwarded 'id'
696
+ assert_forwarded 'name'
697
+ end
698
+
699
+ def test_multiple_remote_urls
700
+ stub_repo_url("git://example.com/other.git\ngit://github.com/my/repo.git")
701
+ assert_command "browse", "open https://github.com/my/repo"
702
+ end
703
+
671
704
  protected
672
705
 
673
706
  def stub_github_user(name)
@@ -679,7 +712,7 @@ config
679
712
  end
680
713
 
681
714
  def stub_repo_url(value)
682
- @git['config remote.origin.url'] = value
715
+ @git['config --get-all remote.origin.url'] = value
683
716
  Hub::Context::REMOTES.clear
684
717
  end
685
718
 
@@ -696,6 +729,14 @@ config
696
729
  @git["config remotes.#{name}"] = value
697
730
  end
698
731
 
732
+ def stub_no_remotes
733
+ @git['remote'] = ''
734
+ end
735
+
736
+ def stub_no_git_repo
737
+ @git.replace({})
738
+ end
739
+
699
740
  def stub_existing_fork(user)
700
741
  stub_fork(user, 200)
701
742
  end
@@ -720,8 +761,15 @@ config
720
761
  ENV['BROWSER'] = browser
721
762
  end
722
763
 
764
+ def with_tmpdir(value)
765
+ dir, ENV['TMPDIR'] = ENV['TMPDIR'], value
766
+ yield
767
+ ensure
768
+ ENV['TMPDIR'] = dir
769
+ end
770
+
723
771
  def assert_browser(browser)
724
- assert_command "browse", "#{browser} http://github.com/defunkt/hub"
772
+ assert_command "browse", "#{browser} https://github.com/defunkt/hub"
725
773
  end
726
774
 
727
775
  def with_ruby_platform(value)