git-hub 1.4.1 → 1.5.0

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