hub 1.8.3 → 1.8.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of hub might be problematic. Click here for more details.
- data/HISTORY.md +189 -0
- data/README.md +95 -94
- data/Rakefile +0 -9
- data/lib/hub/commands.rb +69 -38
- data/lib/hub/context.rb +99 -2
- data/lib/hub/version.rb +1 -1
- data/man/hub.1 +4 -7
- data/man/hub.1.html +5 -6
- data/man/hub.1.ronn +6 -7
- data/test/alias_test.rb +40 -21
- data/test/helper.rb +0 -16
- data/test/hub_test.rb +72 -22
- data/test/ssh_config +3 -0
- metadata +27 -3
data/HISTORY.md
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
## 1.8.4 (2012-03-20)
|
2
|
+
|
3
|
+
* add bash, zsh completion
|
4
|
+
* improve `hub alias` command
|
5
|
+
* change `git fork` so it fails when repo already exists under user
|
6
|
+
* teach custom commands to respect `-h` & `--help` flags
|
7
|
+
* `pull-request`: better error message for invalid remotes/URLs
|
8
|
+
* respect local SSH aliases for host names
|
9
|
+
|
10
|
+
## 1.8.3 (2012-03-02)
|
11
|
+
|
12
|
+
* fix `pull-request` from branch tracking another local branch
|
13
|
+
* fix `browse` command when not on any branch
|
14
|
+
|
15
|
+
## 1.8.2 (2012-02-07)
|
16
|
+
|
17
|
+
* if `pull-request` editor is vim, set appropriate filetype
|
18
|
+
* `pull-request` editor message defaults to single commit message
|
19
|
+
* fix cherry-picking from an existing remote
|
20
|
+
* fix `clone` from local repository
|
21
|
+
* `checkout` command forwards flags to internal checkout command,
|
22
|
+
force-resets the existing local branch by default
|
23
|
+
* fix `am` command when given URLs that include the fragment
|
24
|
+
|
25
|
+
## 1.8.1 (2012-01-24)
|
26
|
+
|
27
|
+
* fix JSON parsing error while using GitHub API
|
28
|
+
* HTTP(S) proxy support
|
29
|
+
|
30
|
+
## 1.8.0 (2012-01-03)
|
31
|
+
|
32
|
+
* fix `pull-request` on GH Enterprise project branch without upstream
|
33
|
+
* ensure Content-Length for POST requests
|
34
|
+
* handle pull requests from private repos
|
35
|
+
* support branches with slashes in their name
|
36
|
+
* display server errors when creating pullrequest fails
|
37
|
+
* support GitHub Enterprise via multiple whitelisted host names
|
38
|
+
* GitHub remote urls don't have to necessarily end in ".git"
|
39
|
+
* fix `git init -g`
|
40
|
+
* authenticate all API requests, helps dealing with private repos
|
41
|
+
* ensure periods are allowed in repository names
|
42
|
+
* fix am/apply commands if TMPDIR environment variable isn't set
|
43
|
+
|
44
|
+
## 1.7.0 (2011-11-24)
|
45
|
+
|
46
|
+
* lock down standalone script to system ruby
|
47
|
+
* don't try to use command output pager on Windows
|
48
|
+
* opt in for HTTPS: `git config hub.protocol https`
|
49
|
+
* add `hub pull-request`
|
50
|
+
* improve detecting upstream configuration ("tracking" branches)
|
51
|
+
* introduce `hub --noop`
|
52
|
+
* `hub apply` now downloads GitHub patches same as `hub am`
|
53
|
+
* `hub create <name>` to explicitly name a repository
|
54
|
+
* switch API communication to HTTPS
|
55
|
+
* better handling of API HTTP exceptions
|
56
|
+
* replace two dots (`sha1..sha2`) with three for ranges in `compare`
|
57
|
+
* avoid ugly error & stack trace when git is not found on the system
|
58
|
+
|
59
|
+
## 1.6.1 (2011-05-13)
|
60
|
+
|
61
|
+
* `git push remote1,remote2` without branch name pushes the current branch
|
62
|
+
* fix `browse` command for current repo with no tracking setup
|
63
|
+
* preserve global flags to git such as `--bare` and `--git-dir=/some/path`
|
64
|
+
* true cross-platform command detection and browser launcher
|
65
|
+
|
66
|
+
## 1.6.0 (2011-03-24)
|
67
|
+
|
68
|
+
* `am` strips extra path from pull reqs URLs such as "pull/42/files"
|
69
|
+
* Fixed permissions on `hub(1)` when installing
|
70
|
+
* gem renamed from `git-hub` to `hub`!
|
71
|
+
|
72
|
+
## 1.5.1 (2011-03-18)
|
73
|
+
|
74
|
+
* support git aliases
|
75
|
+
* Bugfix: `browse/compare` for wiki repos
|
76
|
+
* gracefully handle HTTP errors in `create` and `fork`
|
77
|
+
* `hub am` supports Gist URLs
|
78
|
+
* Bugfix: `clone` command doesn't get confused by mixed arguments
|
79
|
+
|
80
|
+
## 1.5.0 (2010-12-28)
|
81
|
+
|
82
|
+
* compensate for GitHub switch to HTTPS
|
83
|
+
* `hub am`: cherry-pick pull request and commit URLs
|
84
|
+
* support multiple URLs for a single remote
|
85
|
+
* Bugfix: ensure that internal ruby methods can't pretend to be git commands
|
86
|
+
* Bugfix: don't show help when `--exec-path` or `--html-path` flags are used
|
87
|
+
* Support for `GITHUB_USER` and `GITHUB_TOKEN` env variables
|
88
|
+
* Eliminate some ruby warnings
|
89
|
+
|
90
|
+
## 1.4.1 (2010-08-08)
|
91
|
+
## 1.4.0 (2010-08-08)
|
92
|
+
|
93
|
+
* Added new `hub create` command
|
94
|
+
* Added support for `remote set-url`
|
95
|
+
* Bugfix: Don't try multiple git commands on a non-git dir when grabbing remote
|
96
|
+
* Bugfix: Adding remotes when no remotes exist
|
97
|
+
|
98
|
+
## 1.3.2 (2010-07-24)
|
99
|
+
|
100
|
+
* bugfix: cherry picking of commit URL
|
101
|
+
* bugfix: git init -g
|
102
|
+
|
103
|
+
## 1.3.1 (2010-04-29)
|
104
|
+
## 1.3.0 (2010-04-29)
|
105
|
+
|
106
|
+
* Tracking branches awareness
|
107
|
+
* `git browse` subpages (e.g. `git browse repo issues`)
|
108
|
+
* `git fetch <fork>` adds new remotes if missing
|
109
|
+
* `cherry-pick` supports GitHub commit URLs and "user@sha" notation
|
110
|
+
|
111
|
+
## 1.2.0 (2010-04-11)
|
112
|
+
|
113
|
+
* `hub compare` command - Thanks joshthecoder!
|
114
|
+
|
115
|
+
## 1.1.0 (2010-04-07)
|
116
|
+
|
117
|
+
* `hub fork` command - Thanks Mislav!
|
118
|
+
|
119
|
+
## 1.0.3 (2010-03-10)
|
120
|
+
|
121
|
+
* Bugfix: `hub remote` for repos with -, /, etc
|
122
|
+
|
123
|
+
## 1.0.2 (2010-03-07)
|
124
|
+
|
125
|
+
* Bugfix: `hub remote -f name` (for real this time)
|
126
|
+
* Bugfix: zsh quoting [thommay]
|
127
|
+
|
128
|
+
## 1.0.1 (2010-03-05)
|
129
|
+
|
130
|
+
* Bugfix: `hub remote -f name`
|
131
|
+
|
132
|
+
## 1.0.0 (2010-03-03)
|
133
|
+
|
134
|
+
* `hub browse` with no arguments uses the current repo.
|
135
|
+
* `hub submodule add user/repo directory
|
136
|
+
* `hub remote add rtomayko/tilt`
|
137
|
+
* `remote add -p origin rtomayko/tilt`
|
138
|
+
|
139
|
+
## 0.3.2 (2010-02-17)
|
140
|
+
|
141
|
+
* Fixed zshell git completion / aliasing - `hub alias zsh`.
|
142
|
+
|
143
|
+
## 0.3.1 (2010-02-13)
|
144
|
+
|
145
|
+
* Add `hub remote origin` shortcut. Assumes your GitHub login.
|
146
|
+
|
147
|
+
## 0.3.0 (2010-01-23)
|
148
|
+
|
149
|
+
* Add `hub browse` command for opening a repo in a browser.
|
150
|
+
* Add `hub standalone` for installation of standalone via RubyGems
|
151
|
+
* Bugfix: Don't run hub standalone in standalone mode
|
152
|
+
* Bugfix: `git clone` flags are now passed through.
|
153
|
+
* Bugfix: `git clone` with url and path works.
|
154
|
+
* Bugfix: basename call
|
155
|
+
* Bugfix: Check for local directories before cloning
|
156
|
+
|
157
|
+
|
158
|
+
## 0.2.0 (2009-12-24)
|
159
|
+
|
160
|
+
* Respected GIT_PAGER and core.pager
|
161
|
+
* Aliased `--help` to `help`
|
162
|
+
* Ruby 1.9 fixes
|
163
|
+
* Respect git behavior when pager is empty string
|
164
|
+
* `git push` multi-remote support
|
165
|
+
* `hub.http-clone` configuration setting
|
166
|
+
* Use the origin url to find the repo name
|
167
|
+
|
168
|
+
## 0.1.3 (2009-12-11)
|
169
|
+
|
170
|
+
* Homebrew!
|
171
|
+
* Fix inaccuracy in man page
|
172
|
+
* Better help arrangement
|
173
|
+
* Bugfix: Path problems in standalone.rb
|
174
|
+
* Bugfix: Standalone not loaded by default
|
175
|
+
|
176
|
+
## 0.1.2 (2009-12-10)
|
177
|
+
|
178
|
+
* Fixed README typos
|
179
|
+
* Better standalone install line
|
180
|
+
* Added man page
|
181
|
+
* Added `hub help hub`
|
182
|
+
|
183
|
+
## 0.1.1 (2009-12-08)
|
184
|
+
|
185
|
+
* Fixed gem problems
|
186
|
+
|
187
|
+
## 0.1.0 (2009-12-08)
|
188
|
+
|
189
|
+
* First release
|
data/README.md
CHANGED
@@ -1,76 +1,82 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
git + hub = github
|
2
|
+
==================
|
3
3
|
|
4
|
-
|
4
|
+
hub is a command line tool that wraps `git` in order to extend it with extra
|
5
|
+
features and commands that make working with GitHub easier.
|
5
6
|
|
6
|
-
|
7
|
+
~~~ sh
|
8
|
+
$ hub clone rtomayko/tilt
|
7
9
|
|
8
|
-
|
10
|
+
# expands to:
|
11
|
+
$ git clone git://github.com/rtomayko/tilt.git
|
12
|
+
~~~
|
9
13
|
|
10
|
-
|
14
|
+
hub is best aliased as `git`, so you can type `$ git <command>` in the shell and
|
15
|
+
get all the usual `hub` features. See "Aliasing" below.
|
11
16
|
|
12
|
-
Expands to:
|
13
|
-
$ git clone git://github.com/rtomayko/tilt.git
|
14
17
|
|
15
|
-
|
18
|
+
Installation
|
19
|
+
------------
|
16
20
|
|
17
|
-
|
21
|
+
Dependencies:
|
18
22
|
|
19
|
-
|
20
|
-
|
23
|
+
* **git 1.7.3** or newer
|
24
|
+
* **Ruby 1.8.6** or newer
|
21
25
|
|
22
|
-
|
23
|
-
requires Ruby 1.8.6+ or Ruby 1.9.1+. No other libraries necessary.
|
26
|
+
### Homebrew
|
24
27
|
|
28
|
+
Installing on OS X is easiest with Homebrew:
|
25
29
|
|
26
|
-
|
27
|
-
|
30
|
+
~~~ sh
|
31
|
+
$ brew install hub
|
32
|
+
~~~
|
28
33
|
|
29
34
|
### Standalone
|
30
35
|
|
31
|
-
`hub` is
|
36
|
+
`hub` is easily installed as a standalone script:
|
32
37
|
|
33
|
-
|
34
|
-
|
38
|
+
~~~ sh
|
39
|
+
$ curl http://defunkt.io/hub/standalone -sLo ~/bin/hub &&
|
40
|
+
chmod +x ~/bin/hub
|
41
|
+
~~~
|
35
42
|
|
36
|
-
Assuming
|
43
|
+
Assuming "~/bin/" is in your `$PATH`, you're ready to roll:
|
37
44
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
$ brew install hub
|
45
|
-
$ which hub
|
46
|
-
/usr/local/bin/hub
|
47
|
-
$ hub version
|
48
|
-
...
|
45
|
+
~~~ sh
|
46
|
+
$ hub version
|
47
|
+
git version 1.7.6
|
48
|
+
hub version 1.8.3
|
49
|
+
~~~
|
49
50
|
|
50
51
|
### RubyGems
|
51
52
|
|
52
|
-
Though not recommended,
|
53
|
+
Though not recommended, hub can also be installed as a RubyGem:
|
53
54
|
|
54
|
-
|
55
|
+
~~~ sh
|
56
|
+
$ gem install hub
|
57
|
+
~~~
|
55
58
|
|
56
59
|
(It's not recommended for casual use because of the RubyGems startup
|
57
60
|
time. See [this gist][speed] for information.)
|
58
61
|
|
59
|
-
|
62
|
+
#### Standalone via RubyGems
|
60
63
|
|
61
|
-
|
62
|
-
|
64
|
+
~~~ sh
|
65
|
+
$ gem install hub
|
66
|
+
$ hub hub standalone > ~/bin/hub && chmod +x ~/bin/hub
|
67
|
+
~~~
|
63
68
|
|
64
69
|
This installs a standalone version which doesn't require RubyGems to
|
65
|
-
run.
|
70
|
+
run, so it's faster.
|
66
71
|
|
67
72
|
### Source
|
68
73
|
|
69
74
|
You can also install from source:
|
70
75
|
|
71
|
-
|
72
|
-
|
73
|
-
|
76
|
+
~~~ sh
|
77
|
+
$ git clone git://github.com/defunkt/hub.git
|
78
|
+
$ cd hub && rake install prefix=/usr/local
|
79
|
+
~~~
|
74
80
|
|
75
81
|
### Help! It's Slow!
|
76
82
|
|
@@ -79,11 +85,11 @@ Is your prompt slow? It may be hub.
|
|
79
85
|
1. Check that it's **not** installed using RubyGems.
|
80
86
|
2. Check that RUBYOPT isn't loading anything shady:
|
81
87
|
|
82
|
-
|
88
|
+
$ echo $RUBYOPT
|
83
89
|
|
84
90
|
3. Check that your system Ruby is speedy:
|
85
91
|
|
86
|
-
|
92
|
+
$ time /usr/bin/env ruby -e0
|
87
93
|
|
88
94
|
If #3 is slow, it may be your [GC settings][gc].
|
89
95
|
|
@@ -91,30 +97,31 @@ If #3 is slow, it may be your [GC settings][gc].
|
|
91
97
|
Aliasing
|
92
98
|
--------
|
93
99
|
|
94
|
-
|
95
|
-
|
100
|
+
Using hub feels best when it's aliased as `git`. This is not dangerous; your
|
101
|
+
_normal git commands will all work_. hub merely adds some sugar.
|
96
102
|
|
97
|
-
|
98
|
-
|
103
|
+
`hub alias` displays instructions for the current shell. With the `-s` flag, it
|
104
|
+
outputs a script suitable for `eval`.
|
99
105
|
|
100
|
-
|
106
|
+
You should place this command in your `.bash_profile` or other startup script:
|
101
107
|
|
102
|
-
|
103
|
-
|
104
|
-
|
108
|
+
~~~ sh
|
109
|
+
eval "$(hub alias -s)"
|
110
|
+
~~~
|
105
111
|
|
106
|
-
|
107
|
-
script to ensure runs on login.
|
112
|
+
### Shell tab-completion
|
108
113
|
|
109
|
-
|
114
|
+
hub repository contains tab-completion scripts for bash and zsh. These scripts
|
115
|
+
complement existing completion scripts that ship with git.
|
110
116
|
|
111
|
-
|
117
|
+
* [hub bash completion](https://github.com/defunkt/hub/blob/master/etc/hub.bash_completion.sh)
|
118
|
+
* [hub zsh completion](https://github.com/defunkt/hub/blob/master/etc/hub.zsh_completion)
|
112
119
|
|
113
120
|
|
114
121
|
Commands
|
115
122
|
--------
|
116
123
|
|
117
|
-
Assuming you've aliased
|
124
|
+
Assuming you've aliased hub as `git`, the following commands now have
|
118
125
|
superpowers:
|
119
126
|
|
120
127
|
### git clone
|
@@ -292,10 +299,12 @@ superpowers:
|
|
292
299
|
> (hub man page)
|
293
300
|
|
294
301
|
|
295
|
-
|
296
|
-
|
302
|
+
Configuration
|
303
|
+
-------------
|
304
|
+
|
305
|
+
### GitHub username & token
|
297
306
|
|
298
|
-
To get the most out of
|
307
|
+
To get the most out of hub, you'll want to ensure your GitHub login
|
299
308
|
is stored locally in your Git config or environment variables.
|
300
309
|
|
301
310
|
To test it run this:
|
@@ -312,59 +321,47 @@ setup "github.token" as well. See [GitHub config guide][2] for more information.
|
|
312
321
|
If present, environment variables `GITHUB_USER` and `GITHUB_TOKEN` override the
|
313
322
|
values of "github.user" and "github.token".
|
314
323
|
|
315
|
-
|
316
|
-
-------------
|
324
|
+
### HTTPS insted of git protocol
|
317
325
|
|
318
326
|
If you prefer using the HTTPS protocol for GitHub repositories instead of the git
|
319
327
|
protocol for read and ssh for write, you can set "hub.protocol" to "https".
|
320
328
|
|
321
|
-
|
329
|
+
~~~ sh
|
330
|
+
# default behavior
|
331
|
+
$ git clone defunkt/repl
|
332
|
+
< git clone >
|
322
333
|
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
< https clone >
|
329
|
-
|
330
|
-
Prior Art
|
331
|
-
---------
|
332
|
-
|
333
|
-
These projects also aim to either improve git or make interacting with
|
334
|
-
GitHub simpler:
|
335
|
-
|
336
|
-
* [eg](http://www.gnome.org/~newren/eg/)
|
337
|
-
* [github-gem](https://github.com/defunkt/github-gem)
|
334
|
+
# opt into HTTPS:
|
335
|
+
$ git config --global hub.protocol https
|
336
|
+
$ git clone defunkt/repl
|
337
|
+
< https clone >
|
338
|
+
~~~
|
338
339
|
|
339
340
|
|
340
341
|
Contributing
|
341
342
|
------------
|
342
343
|
|
343
|
-
These instructions assume that you already have
|
344
|
-
|
344
|
+
These instructions assume that you already have hub installed and aliased as
|
345
|
+
`git` (see "Aliasing").
|
345
346
|
|
346
347
|
1. Clone hub:
|
347
|
-
`git clone defunkt/hub`
|
348
|
-
|
349
|
-
`
|
348
|
+
`git clone defunkt/hub && cd hub`
|
349
|
+
1. Install development dependencies:
|
350
|
+
`bundle install`
|
351
|
+
2. Verify that existing tests pass:
|
352
|
+
`bundle exec rake`
|
350
353
|
3. Create a topic branch:
|
351
|
-
`git checkout -b
|
352
|
-
4. Make your changes
|
354
|
+
`git checkout -b feature`
|
355
|
+
4. **Make your changes.** (It helps a lot if you write tests first.)
|
353
356
|
5. Verify that tests still pass:
|
354
|
-
`rake
|
357
|
+
`bundle exec rake`
|
355
358
|
6. Fork hub on GitHub (adds a remote named "YOUR_USER"):
|
356
359
|
`git fork`
|
357
360
|
7. Push to your fork:
|
358
|
-
`git push -u YOUR_USER
|
361
|
+
`git push -u YOUR_USER feature`
|
359
362
|
8. Open a pull request describing your changes:
|
360
363
|
`git pull-request`
|
361
364
|
|
362
|
-
### Development dependencies
|
363
|
-
|
364
|
-
You will need the following libraries for development:
|
365
|
-
|
366
|
-
* [ronn](https://github.com/rtomayko/ronn) (building man pages)
|
367
|
-
* [webmock](https://github.com/bblimke/webmock)
|
368
365
|
|
369
366
|
Meta
|
370
367
|
----
|
@@ -372,12 +369,16 @@ Meta
|
|
372
369
|
* Home: <https://github.com/defunkt/hub>
|
373
370
|
* Bugs: <https://github.com/defunkt/hub/issues>
|
374
371
|
* Gem: <https://rubygems.org/gems/hub>
|
372
|
+
* Authors: <https://github.com/defunkt/hub/contributors>
|
373
|
+
|
374
|
+
### Prior art
|
375
375
|
|
376
|
+
These projects also aim to either improve git or make interacting with
|
377
|
+
GitHub simpler:
|
376
378
|
|
377
|
-
|
378
|
-
|
379
|
+
* [eg](http://www.gnome.org/~newren/eg/)
|
380
|
+
* [github-gem](https://github.com/defunkt/github-gem)
|
379
381
|
|
380
|
-
<https://github.com/defunkt/hub/contributors>
|
381
382
|
|
382
383
|
[speed]: http://gist.github.com/284823
|
383
384
|
[2]: http://help.github.com/set-your-user-name-email-and-github-token/
|
data/Rakefile
CHANGED
@@ -36,15 +36,6 @@ Rake::TestTask.new do |t|
|
|
36
36
|
t.verbose = false
|
37
37
|
end
|
38
38
|
|
39
|
-
if command? :kicker
|
40
|
-
desc "Launch Kicker (like autotest)"
|
41
|
-
task :kicker do
|
42
|
-
puts "Kicking... (ctrl+c to cancel)"
|
43
|
-
exec "kicker -e rake test lib"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
39
|
#
|
49
40
|
# Manual
|
50
41
|
#
|
data/lib/hub/commands.rb
CHANGED
@@ -38,6 +38,8 @@ module Hub
|
|
38
38
|
OWNER_RE = /[a-zA-Z0-9-]+/
|
39
39
|
NAME_WITH_OWNER_RE = /^(?:#{NAME_RE}|#{OWNER_RE}\/#{NAME_RE})$/
|
40
40
|
|
41
|
+
CUSTOM_COMMANDS = %w[alias create browse compare fork pull-request]
|
42
|
+
|
41
43
|
def run(args)
|
42
44
|
slurp_global_flags(args)
|
43
45
|
|
@@ -45,13 +47,17 @@ module Hub
|
|
45
47
|
args.unshift 'help' if args.empty?
|
46
48
|
|
47
49
|
cmd = args[0]
|
48
|
-
expanded_args = expand_alias(cmd)
|
49
|
-
|
50
|
+
if expanded_args = expand_alias(cmd)
|
51
|
+
cmd = expanded_args[0]
|
52
|
+
expanded_args.concat args[1..-1]
|
53
|
+
end
|
54
|
+
|
55
|
+
respect_help_flags(expanded_args || args) if custom_command? cmd
|
50
56
|
|
51
57
|
# git commands can have dashes
|
52
58
|
cmd = cmd.sub(/(\w)-/, '\1_')
|
53
59
|
if method_defined?(cmd) and cmd != 'run'
|
54
|
-
args
|
60
|
+
args.replace expanded_args if expanded_args
|
55
61
|
send(cmd, args)
|
56
62
|
end
|
57
63
|
rescue Errno::ENOENT
|
@@ -73,6 +79,10 @@ module Hub
|
|
73
79
|
base_project = local_repo.main_project
|
74
80
|
head_project = local_repo.current_project
|
75
81
|
|
82
|
+
unless base_project
|
83
|
+
abort "Aborted: the origin remote doesn't point to a GitHub repository."
|
84
|
+
end
|
85
|
+
|
76
86
|
from_github_ref = lambda do |ref, context_project|
|
77
87
|
if ref.index(':')
|
78
88
|
owner, ref = ref.split(':', 2)
|
@@ -136,7 +146,7 @@ module Hub
|
|
136
146
|
end
|
137
147
|
|
138
148
|
if args.noop?
|
139
|
-
puts "Would
|
149
|
+
puts "Would request a pull to #{base_project.owner}:#{options[:base]} from #{options[:head]}"
|
140
150
|
exit
|
141
151
|
end
|
142
152
|
|
@@ -431,8 +441,10 @@ module Hub
|
|
431
441
|
abort "Error: repository under 'origin' remote is not a GitHub project"
|
432
442
|
end
|
433
443
|
forked_project = project.owned_by(github_user(true, project.host))
|
444
|
+
|
434
445
|
if repo_exists?(forked_project)
|
435
|
-
|
446
|
+
abort "Error creating fork: %s already exists on %s" %
|
447
|
+
[ forked_project.name_with_owner, forked_project.host ]
|
436
448
|
else
|
437
449
|
fork_repo(project) unless args.noop?
|
438
450
|
end
|
@@ -613,43 +625,38 @@ module Hub
|
|
613
625
|
end
|
614
626
|
|
615
627
|
def alias(args)
|
616
|
-
shells =
|
617
|
-
'sh' => 'alias git=hub',
|
618
|
-
'bash' => 'alias git=hub',
|
619
|
-
'zsh' => 'function git(){hub "$@"}',
|
620
|
-
'csh' => 'alias git hub',
|
621
|
-
'fish' => 'alias git hub'
|
622
|
-
}
|
628
|
+
shells = %w[bash zsh sh ksh csh fish]
|
623
629
|
|
624
|
-
|
630
|
+
script = !!args.delete('-s')
|
631
|
+
shell = args[1] || ENV['SHELL']
|
632
|
+
abort "hub alias: unknown shell" if shell.nil? or shell.empty?
|
633
|
+
shell = File.basename shell
|
625
634
|
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
end
|
631
|
-
else
|
632
|
-
puts "usage: hub alias [-s] SHELL", ""
|
633
|
-
puts "You already have hub installed and available in your PATH,"
|
634
|
-
puts "but to get the full experience you'll want to alias it to"
|
635
|
-
puts "`git`.", ""
|
636
|
-
puts "To see how to accomplish this for your shell, run the alias"
|
637
|
-
puts "command again with the name of your shell.", ""
|
638
|
-
puts "Known shells:"
|
639
|
-
shells.map { |key, _| key }.sort.each do |key|
|
640
|
-
puts " " + key
|
641
|
-
end
|
642
|
-
puts "", "Options:"
|
643
|
-
puts " -s Silent. Useful when using the output with eval, e.g."
|
644
|
-
puts " $ eval `hub alias -s bash`"
|
645
|
-
|
646
|
-
exit
|
635
|
+
unless shells.include? shell
|
636
|
+
$stderr.puts "hub alias: unsupported shell"
|
637
|
+
warn "supported shells: #{shells.join(' ')}"
|
638
|
+
abort
|
647
639
|
end
|
648
640
|
|
649
|
-
if
|
650
|
-
puts
|
641
|
+
if script
|
642
|
+
puts "alias git=hub"
|
643
|
+
if 'zsh' == shell
|
644
|
+
puts "if type compdef >/dev/null; then"
|
645
|
+
puts " compdef hub=git"
|
646
|
+
puts "fi"
|
647
|
+
end
|
651
648
|
else
|
652
|
-
|
649
|
+
profile = case shell
|
650
|
+
when 'bash' then '~/.bash_profile'
|
651
|
+
when 'zsh' then '~/.zshrc'
|
652
|
+
when 'ksh' then '~/.profile'
|
653
|
+
else
|
654
|
+
'your profile'
|
655
|
+
end
|
656
|
+
|
657
|
+
puts "# Wrap git automatically by adding the following to #{profile}:"
|
658
|
+
puts
|
659
|
+
puts 'eval "$(hub alias -s)"'
|
653
660
|
end
|
654
661
|
|
655
662
|
exit
|
@@ -685,6 +692,30 @@ module Hub
|
|
685
692
|
# from the command line.
|
686
693
|
#
|
687
694
|
|
695
|
+
def custom_command? cmd
|
696
|
+
CUSTOM_COMMANDS.include? cmd
|
697
|
+
end
|
698
|
+
|
699
|
+
# Show short usage help for `-h` flag, and open man page for `--help`
|
700
|
+
def respect_help_flags args
|
701
|
+
return if args.size > 2
|
702
|
+
case args[1]
|
703
|
+
when '-h'
|
704
|
+
pattern = /(git|hub) #{Regexp.escape args[0].gsub('-', '\-')}/
|
705
|
+
hub_raw_manpage.each_line { |line|
|
706
|
+
if line =~ pattern
|
707
|
+
$stderr.print "Usage: "
|
708
|
+
$stderr.puts line.gsub(/\\f./, '').gsub('\-', '-')
|
709
|
+
abort
|
710
|
+
end
|
711
|
+
}
|
712
|
+
abort "Error: couldn't find usage help for #{args[0]}"
|
713
|
+
when '--help'
|
714
|
+
puts hub_manpage
|
715
|
+
exit
|
716
|
+
end
|
717
|
+
end
|
718
|
+
|
688
719
|
# The text print when `hub help` is run, kept in its own method
|
689
720
|
# for the convenience of the author.
|
690
721
|
def improved_help_text
|
@@ -893,7 +924,7 @@ help
|
|
893
924
|
params['homepage'] = options[:homepage] if options[:homepage]
|
894
925
|
|
895
926
|
load_net_http
|
896
|
-
response = http_post(project.api_create_url('
|
927
|
+
response = http_post(project.api_create_url('json'), params)
|
897
928
|
response.error! unless Net::HTTPSuccess === response
|
898
929
|
end
|
899
930
|
|
data/lib/hub/context.rb
CHANGED
@@ -183,6 +183,10 @@ module Hub
|
|
183
183
|
def main_host
|
184
184
|
'github.com'
|
185
185
|
end
|
186
|
+
|
187
|
+
def ssh_config
|
188
|
+
@ssh_config ||= SshConfig.new
|
189
|
+
end
|
186
190
|
end
|
187
191
|
|
188
192
|
class GithubProject < Struct.new(:local_repo, :owner, :name, :host)
|
@@ -339,14 +343,21 @@ module Hub
|
|
339
343
|
def urls
|
340
344
|
@urls ||= local_repo.git_config("remote.#{name}.url", :all).to_s.split("\n").map { |uri|
|
341
345
|
begin
|
342
|
-
if uri =~ %r{^[\w-]+://} then
|
343
|
-
elsif uri =~ %r{^([^/]+?):} then
|
346
|
+
if uri =~ %r{^[\w-]+://} then uri_parse(uri)
|
347
|
+
elsif uri =~ %r{^([^/]+?):} then uri_parse("ssh://#{$1}/#{$'}") # scp-like syntax
|
344
348
|
end
|
345
349
|
rescue URI::InvalidURIError
|
346
350
|
nil
|
347
351
|
end
|
348
352
|
}.compact
|
349
353
|
end
|
354
|
+
|
355
|
+
def uri_parse uri
|
356
|
+
uri = URI.parse uri
|
357
|
+
uri.host = local_repo.ssh_config.get_value(uri.host, 'hostname') { uri.host }
|
358
|
+
uri.user = local_repo.ssh_config.get_value(uri.host, 'user') { uri.user }
|
359
|
+
uri
|
360
|
+
end
|
350
361
|
end
|
351
362
|
|
352
363
|
## helper methods for local repo, GH projects
|
@@ -502,5 +513,91 @@ module Hub
|
|
502
513
|
def command?(name)
|
503
514
|
!which(name).nil?
|
504
515
|
end
|
516
|
+
|
517
|
+
class SshConfig
|
518
|
+
CONFIG_FILES = %w(~/.ssh/config /etc/ssh_config /etc/ssh/ssh_config)
|
519
|
+
|
520
|
+
def initialize files = nil
|
521
|
+
@settings = Hash.new {|h,k| h[k] = {} }
|
522
|
+
Array(files || CONFIG_FILES).each do |path|
|
523
|
+
file = File.expand_path path
|
524
|
+
parse_file file if File.exist? file
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
# yields if not found
|
529
|
+
def get_value hostname, key
|
530
|
+
key = key.to_s.downcase
|
531
|
+
@settings.each do |pattern, settings|
|
532
|
+
if pattern.match? hostname and found = settings[key]
|
533
|
+
return found
|
534
|
+
end
|
535
|
+
end
|
536
|
+
yield
|
537
|
+
end
|
538
|
+
|
539
|
+
class HostPattern
|
540
|
+
def initialize pattern
|
541
|
+
@pattern = pattern.to_s.downcase
|
542
|
+
end
|
543
|
+
|
544
|
+
def to_s() @pattern end
|
545
|
+
def ==(other) other.to_s == self.to_s end
|
546
|
+
|
547
|
+
def matcher
|
548
|
+
@matcher ||=
|
549
|
+
if '*' == @pattern
|
550
|
+
Proc.new { true }
|
551
|
+
elsif @pattern !~ /[?*]/
|
552
|
+
lambda { |hostname| hostname.to_s.downcase == @pattern }
|
553
|
+
else
|
554
|
+
re = self.class.pattern_to_regexp @pattern
|
555
|
+
lambda { |hostname| re =~ hostname }
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
def match? hostname
|
560
|
+
matcher.call hostname
|
561
|
+
end
|
562
|
+
|
563
|
+
def self.pattern_to_regexp pattern
|
564
|
+
escaped = Regexp.escape(pattern)
|
565
|
+
escaped.gsub!('\*', '.*')
|
566
|
+
escaped.gsub!('\?', '.')
|
567
|
+
/^#{escaped}$/i
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
571
|
+
def parse_file file
|
572
|
+
host_patterns = [HostPattern.new('*')]
|
573
|
+
|
574
|
+
IO.foreach(file) do |line|
|
575
|
+
case line
|
576
|
+
when /^\s*(#|$)/ then next
|
577
|
+
when /^\s*(\S+)\s*=/
|
578
|
+
key, value = $1, $'
|
579
|
+
else
|
580
|
+
key, value = line.strip.split(/\s+/, 2)
|
581
|
+
end
|
582
|
+
|
583
|
+
next if value.nil?
|
584
|
+
key.downcase!
|
585
|
+
value = $1 if value =~ /^"(.*)"$/
|
586
|
+
value.chomp!
|
587
|
+
|
588
|
+
if 'host' == key
|
589
|
+
host_patterns = value.split(/\s+/).map {|p| HostPattern.new p }
|
590
|
+
else
|
591
|
+
record_setting key, value, host_patterns
|
592
|
+
end
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
def record_setting key, value, patterns
|
597
|
+
patterns.each do |pattern|
|
598
|
+
@settings[pattern][key] ||= value
|
599
|
+
end
|
600
|
+
end
|
601
|
+
end
|
505
602
|
end
|
506
603
|
end
|
data/lib/hub/version.rb
CHANGED
data/man/hub.1
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
\fBhub\fR [\fB\-\-noop\fR] \fICOMMAND\fR \fIOPTIONS\fR
|
11
11
|
.
|
12
12
|
.br
|
13
|
-
\fBhub alias\fR [\fB\-s\fR] \fISHELL\fR
|
13
|
+
\fBhub alias\fR [\fB\-s\fR] [\fISHELL\fR]
|
14
14
|
.
|
15
15
|
.SS "Expanded git commands:"
|
16
16
|
\fBgit init \-g\fR \fIOPTIONS\fR
|
@@ -58,7 +58,7 @@
|
|
58
58
|
\fBgit fork\fR [\fB\-\-no\-remote\fR]
|
59
59
|
.
|
60
60
|
.br
|
61
|
-
\fBgit pull\-request\fR [\fB\-f\fR] [\fITITLE\fR|\fB\-i\fR \fIISSUE\fR] [\fB\-b\fR \fIBASE\fR] [\fB\-h\fR \fIHEAD\fR]
|
61
|
+
\fBgit pull\-request\fR [\fB\-f\fR] [\fITITLE\fR|\fB\-i\fR \fIISSUE\fR] [\fB\-b\fR \fIBASE\fR] [\fB\-h\fR \fIHEAD\fR]
|
62
62
|
.
|
63
63
|
.SH "DESCRIPTION"
|
64
64
|
hub enhances various git commands to ease most common workflows with GitHub\.
|
@@ -68,11 +68,8 @@ hub enhances various git commands to ease most common workflows with GitHub\.
|
|
68
68
|
Shows which command(s) would be run as a result of the current command\. Doesn\'t perform anything\.
|
69
69
|
.
|
70
70
|
.TP
|
71
|
-
\fBhub alias\fR [\fB\-s\fR] \fISHELL\fR
|
72
|
-
|
73
|
-
.
|
74
|
-
.br
|
75
|
-
\fBeval $(hub alias \-s bash)\fR
|
71
|
+
\fBhub alias\fR [\fB\-s\fR] [\fISHELL\fR]
|
72
|
+
Shows shell instructions for wrapping git\. If given, \fISHELL\fR specifies the type of shell; otherwise defaults to the value of SHELL environment variable\. With \fB\-s\fR, outputs shell script suitable for \fBeval\fR\.
|
76
73
|
.
|
77
74
|
.TP
|
78
75
|
\fBgit init\fR \fB\-g\fR \fIOPTIONS\fR
|
data/man/hub.1.html
CHANGED
@@ -77,7 +77,7 @@
|
|
77
77
|
<h2 id="SYNOPSIS">SYNOPSIS</h2>
|
78
78
|
|
79
79
|
<p><code>hub</code> [<code>--noop</code>] <var>COMMAND</var> <var>OPTIONS</var><br />
|
80
|
-
<code>hub alias</code> [<code>-s</code>] <var>SHELL</var
|
80
|
+
<code>hub alias</code> [<code>-s</code>] [<var>SHELL</var>]</p>
|
81
81
|
|
82
82
|
<h3 id="Expanded-git-commands-">Expanded git commands:</h3>
|
83
83
|
|
@@ -99,7 +99,7 @@
|
|
99
99
|
<code>git browse</code> [<code>-u</code>] [[<var>USER</var><code>/</code>]<var>REPOSITORY</var>] [SUBPAGE]<br />
|
100
100
|
<code>git compare</code> [<code>-u</code>] [<var>USER</var>] [<var>START</var>...]<var>END</var><br />
|
101
101
|
<code>git fork</code> [<code>--no-remote</code>]<br />
|
102
|
-
<code>git pull-request</code> [<code>-f</code>] [<var>TITLE</var>|<code>-i</code> <var>ISSUE</var>] [<code>-b</code> <var>BASE</var>] [<code>-h</code> <var>HEAD</var>]
|
102
|
+
<code>git pull-request</code> [<code>-f</code>] [<var>TITLE</var>|<code>-i</code> <var>ISSUE</var>] [<code>-b</code> <var>BASE</var>] [<code>-h</code> <var>HEAD</var>]</p>
|
103
103
|
|
104
104
|
<h2 id="DESCRIPTION">DESCRIPTION</h2>
|
105
105
|
|
@@ -108,10 +108,9 @@
|
|
108
108
|
<dl>
|
109
109
|
<dt><code>hub --noop</code> <var>COMMAND</var></dt><dd><p>Shows which command(s) would be run as a result of the current command.
|
110
110
|
Doesn't perform anything.</p></dd>
|
111
|
-
<dt><code>hub alias</code> [<code>-s</code>] <var>SHELL</var
|
112
|
-
|
113
|
-
|
114
|
-
<code>eval $(hub alias -s bash)</code></p></dd>
|
111
|
+
<dt><code>hub alias</code> [<code>-s</code>] [<var>SHELL</var>]</dt><dd><p>Shows shell instructions for wrapping git. If given, <var>SHELL</var> specifies the
|
112
|
+
type of shell; otherwise defaults to the value of SHELL environment
|
113
|
+
variable. With <code>-s</code>, outputs shell script suitable for <code>eval</code>.</p></dd>
|
115
114
|
<dt><code>git init</code> <code>-g</code> <var>OPTIONS</var></dt><dd><p>Create a git repository as with <span class="man-ref">git-init<span class="s">(1)</span></span> and add remote <code>origin</code> at
|
116
115
|
"git@github.com:<var>USER</var>/<var>REPOSITORY</var>.git"; <var>USER</var> is your GitHub username and
|
117
116
|
<var>REPOSITORY</var> is the current working directory's basename.</p></dd>
|
data/man/hub.1.ronn
CHANGED
@@ -4,7 +4,7 @@ hub(1) -- git + hub = github
|
|
4
4
|
## SYNOPSIS
|
5
5
|
|
6
6
|
`hub` [`--noop`] <COMMAND> <OPTIONS>
|
7
|
-
`hub alias` [`-s`] <SHELL>
|
7
|
+
`hub alias` [`-s`] [<SHELL>]
|
8
8
|
|
9
9
|
### Expanded git commands:
|
10
10
|
|
@@ -26,7 +26,7 @@ hub(1) -- git + hub = github
|
|
26
26
|
`git browse` [`-u`] [[<USER>`/`]<REPOSITORY>] [SUBPAGE]
|
27
27
|
`git compare` [`-u`] [<USER>] [<START>...]<END>
|
28
28
|
`git fork` [`--no-remote`]
|
29
|
-
`git pull-request` [`-f`] [<TITLE>|`-i` <ISSUE>] [`-b` <BASE>] [`-h` <HEAD>]
|
29
|
+
`git pull-request` [`-f`] [<TITLE>|`-i` <ISSUE>] [`-b` <BASE>] [`-h` <HEAD>]
|
30
30
|
|
31
31
|
## DESCRIPTION
|
32
32
|
|
@@ -36,11 +36,10 @@ hub enhances various git commands to ease most common workflows with GitHub.
|
|
36
36
|
Shows which command(s) would be run as a result of the current command.
|
37
37
|
Doesn't perform anything.
|
38
38
|
|
39
|
-
* `hub alias` [`-s`] <SHELL
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
`eval $(hub alias -s bash)`
|
39
|
+
* `hub alias` [`-s`] [<SHELL>]:
|
40
|
+
Shows shell instructions for wrapping git. If given, <SHELL> specifies the
|
41
|
+
type of shell; otherwise defaults to the value of SHELL environment
|
42
|
+
variable. With `-s`, outputs shell script suitable for `eval`.
|
44
43
|
|
45
44
|
* `git init` `-g` <OPTIONS>:
|
46
45
|
Create a git repository as with git-init(1) and add remote `origin` at
|
data/test/alias_test.rb
CHANGED
@@ -1,40 +1,59 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
class AliasTest < Test::Unit::TestCase
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
assert_includes "zsh", instructions
|
10
|
-
assert_includes "fish", instructions
|
4
|
+
def test_alias_instructions
|
5
|
+
expected = "# Wrap git automatically by adding the following to your profile:\n"
|
6
|
+
expected << "\n"
|
7
|
+
expected << 'eval "$(hub alias -s)"' << "\n"
|
8
|
+
assert_equal expected, hub("alias sh")
|
11
9
|
end
|
12
10
|
|
13
|
-
def
|
14
|
-
|
11
|
+
def test_alias_instructions_bash
|
12
|
+
with_shell('bash') do
|
13
|
+
assert_includes '~/.bash_profile', hub("alias")
|
14
|
+
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
17
|
+
def test_alias_instructions_zsh
|
18
|
+
with_shell('zsh') do
|
19
|
+
assert_includes '~/.zshrc', hub("alias")
|
20
|
+
end
|
19
21
|
end
|
20
22
|
|
21
|
-
def
|
22
|
-
|
23
|
+
def test_alias_script_bash
|
24
|
+
with_shell('bash') do
|
25
|
+
assert_equal "alias git=hub\n", hub("alias -s")
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
|
-
def
|
26
|
-
|
29
|
+
def test_alias_script_zsh
|
30
|
+
with_shell('zsh') do
|
31
|
+
script = hub("alias -s")
|
32
|
+
assert_includes "alias git=hub\n", script
|
33
|
+
assert_includes "compdef hub=git\n", script
|
34
|
+
end
|
27
35
|
end
|
28
36
|
|
29
|
-
def
|
30
|
-
|
37
|
+
def test_unknown_shell
|
38
|
+
with_shell(nil) do
|
39
|
+
assert_equal "hub alias: unknown shell\n", hub("alias -s")
|
40
|
+
end
|
31
41
|
end
|
32
42
|
|
33
|
-
def
|
34
|
-
|
43
|
+
def test_unsupported_shell
|
44
|
+
with_shell('foosh') do
|
45
|
+
expected = "hub alias: unsupported shell\n"
|
46
|
+
expected << "supported shells: bash zsh sh ksh csh fish\n"
|
47
|
+
assert_equal expected, hub("alias -s")
|
48
|
+
end
|
35
49
|
end
|
36
50
|
|
37
|
-
|
38
|
-
|
51
|
+
private
|
52
|
+
|
53
|
+
def with_shell(shell)
|
54
|
+
old_shell, ENV['SHELL'] = ENV['SHELL'], shell
|
55
|
+
yield
|
56
|
+
ensure
|
57
|
+
ENV['SHELL'] = old_shell
|
39
58
|
end
|
40
59
|
end
|
data/test/helper.rb
CHANGED
@@ -80,22 +80,6 @@ class Test::Unit::TestCase
|
|
80
80
|
assert !cmd.args.changed?, "arguments were not supposed to change: #{cmd.args.inspect}"
|
81
81
|
end
|
82
82
|
|
83
|
-
# Asserts that `hub` will show a specific alias command for a
|
84
|
-
# specific shell.
|
85
|
-
#
|
86
|
-
# e.g.
|
87
|
-
# assert_alias_command "sh", "alias git=hub"
|
88
|
-
#
|
89
|
-
# Here we are saying that this:
|
90
|
-
# $ hub alias sh
|
91
|
-
# Should display this:
|
92
|
-
# Run this in your shell to start using `hub` as `git`:
|
93
|
-
# alias git=hub
|
94
|
-
def assert_alias_command(shell, command)
|
95
|
-
expected = "Run this in your shell to start using `hub` as `git`:\n %s\n"
|
96
|
-
assert_equal(expected % command, hub("alias #{shell}"))
|
97
|
-
end
|
98
|
-
|
99
83
|
# Asserts that `haystack` includes `needle`.
|
100
84
|
def assert_includes(needle, haystack)
|
101
85
|
assert haystack.include?(needle),
|
data/test/hub_test.rb
CHANGED
@@ -36,6 +36,7 @@ class HubTest < Test::Unit::TestCase
|
|
36
36
|
super
|
37
37
|
COMMANDS.replace %w[open groff]
|
38
38
|
Hub::Context::PWD.replace '/path/to/hub'
|
39
|
+
Hub::Context::SshConfig::CONFIG_FILES.replace []
|
39
40
|
|
40
41
|
@git_reader = Hub::Context::GitReader.new 'git' do |cache, cmd|
|
41
42
|
unless cmd.index('config --get alias.') == 0
|
@@ -588,7 +589,7 @@ class HubTest < Test::Unit::TestCase
|
|
588
589
|
def test_create
|
589
590
|
stub_no_remotes
|
590
591
|
stub_nonexisting_fork('tpw')
|
591
|
-
stub_request(:post, "https://#{auth}github.com/api/v2/
|
592
|
+
stub_request(:post, "https://#{auth}github.com/api/v2/json/repos/create").
|
592
593
|
with(:body => { 'name' => 'hub' })
|
593
594
|
|
594
595
|
expected = "remote add -f origin git@github.com:tpw/hub.git\n"
|
@@ -599,7 +600,7 @@ class HubTest < Test::Unit::TestCase
|
|
599
600
|
def test_create_custom_name
|
600
601
|
stub_no_remotes
|
601
602
|
stub_nonexisting_fork('tpw', 'hubbub')
|
602
|
-
stub_request(:post, "https://#{auth}github.com/api/v2/
|
603
|
+
stub_request(:post, "https://#{auth}github.com/api/v2/json/repos/create").
|
603
604
|
with(:body => { 'name' => 'hubbub' })
|
604
605
|
|
605
606
|
expected = "remote add -f origin git@github.com:tpw/hubbub.git\n"
|
@@ -610,7 +611,7 @@ class HubTest < Test::Unit::TestCase
|
|
610
611
|
def test_create_in_organization
|
611
612
|
stub_no_remotes
|
612
613
|
stub_nonexisting_fork('acme', 'hubbub')
|
613
|
-
stub_request(:post, "https://#{auth}github.com/api/v2/
|
614
|
+
stub_request(:post, "https://#{auth}github.com/api/v2/json/repos/create").
|
614
615
|
with(:body => { 'name' => 'acme/hubbub' })
|
615
616
|
|
616
617
|
expected = "remote add -f origin git@github.com:acme/hubbub.git\n"
|
@@ -624,7 +625,7 @@ class HubTest < Test::Unit::TestCase
|
|
624
625
|
stub_request(:get, "http://#{auth}github.com/api/v2/yaml/repos/show/tpw/hub").
|
625
626
|
to_return(:status => 404)
|
626
627
|
|
627
|
-
stub_request(:post, "http://#{auth}github.com/api/v2/
|
628
|
+
stub_request(:post, "http://#{auth}github.com/api/v2/json/repos/create").
|
628
629
|
with(:body => { 'name' => 'hub' })
|
629
630
|
|
630
631
|
expected = "remote add -f origin git@github.com:tpw/hub.git\n"
|
@@ -640,7 +641,7 @@ class HubTest < Test::Unit::TestCase
|
|
640
641
|
def test_create_failed
|
641
642
|
stub_no_remotes
|
642
643
|
stub_nonexisting_fork('tpw')
|
643
|
-
stub_request(:post, "https://#{auth}github.com/api/v2/
|
644
|
+
stub_request(:post, "https://#{auth}github.com/api/v2/json/repos/create").
|
644
645
|
to_return(:status => [401, "Your token is fail"])
|
645
646
|
|
646
647
|
expected = "Error creating repository: Your token is fail (HTTP 401)\n"
|
@@ -659,7 +660,7 @@ class HubTest < Test::Unit::TestCase
|
|
659
660
|
stub_request(:get, "https://#{auth('mojombo', '123abc')}github.com/api/v2/yaml/repos/show/mojombo/hub").
|
660
661
|
to_return(:status => 404)
|
661
662
|
|
662
|
-
stub_request(:post, "https://#{auth('mojombo', '123abc')}github.com/api/v2/
|
663
|
+
stub_request(:post, "https://#{auth('mojombo', '123abc')}github.com/api/v2/json/repos/create").
|
663
664
|
with(:body => { 'name' => 'hub' })
|
664
665
|
|
665
666
|
expected = "remote add -f origin git@github.com:mojombo/hub.git\n"
|
@@ -674,7 +675,7 @@ class HubTest < Test::Unit::TestCase
|
|
674
675
|
def test_create_private_repository
|
675
676
|
stub_no_remotes
|
676
677
|
stub_nonexisting_fork('tpw')
|
677
|
-
stub_request(:post, "https://#{auth}github.com/api/v2/
|
678
|
+
stub_request(:post, "https://#{auth}github.com/api/v2/json/repos/create").
|
678
679
|
with(:body => { 'name' => 'hub', 'public' => '0' })
|
679
680
|
|
680
681
|
expected = "remote add -f origin git@github.com:tpw/hub.git\n"
|
@@ -682,10 +683,23 @@ class HubTest < Test::Unit::TestCase
|
|
682
683
|
assert_equal expected, hub("create -p") { ENV['GIT'] = 'echo' }
|
683
684
|
end
|
684
685
|
|
686
|
+
def test_create_private_repository_fails
|
687
|
+
stub_no_remotes
|
688
|
+
stub_nonexisting_fork('tpw')
|
689
|
+
stub_request(:post, "https://#{auth}github.com/api/v2/json/repos/create").
|
690
|
+
to_return(:status => [422, "Unprocessable Entity"],
|
691
|
+
:headers => {"Content-type" => "application/json"},
|
692
|
+
:body => %({"error":"repository creation failed: You are over your quota."}))
|
693
|
+
|
694
|
+
expected = "Error creating repository: Unprocessable Entity (HTTP 422)\n"
|
695
|
+
expected << "repository creation failed: You are over your quota.\n"
|
696
|
+
assert_equal expected, hub("create -p") { ENV['GIT'] = 'echo' }
|
697
|
+
end
|
698
|
+
|
685
699
|
def test_create_with_description_and_homepage
|
686
700
|
stub_no_remotes
|
687
701
|
stub_nonexisting_fork('tpw')
|
688
|
-
stub_request(:post, "https://#{auth}github.com/api/v2/
|
702
|
+
stub_request(:post, "https://#{auth}github.com/api/v2/json/repos/create").with(:body => {
|
689
703
|
'name' => 'hub', 'description' => 'toyproject', 'homepage' => 'http://example.com'
|
690
704
|
})
|
691
705
|
|
@@ -735,7 +749,7 @@ class HubTest < Test::Unit::TestCase
|
|
735
749
|
|
736
750
|
def test_create_origin_already_exists
|
737
751
|
stub_nonexisting_fork('tpw')
|
738
|
-
stub_request(:post, "https://#{auth}github.com/api/v2/
|
752
|
+
stub_request(:post, "https://#{auth}github.com/api/v2/json/repos/create").
|
739
753
|
with(:body => { 'name' => 'hub' })
|
740
754
|
|
741
755
|
expected = "remote -v\ncreated repository: tpw/hub\n"
|
@@ -752,6 +766,16 @@ class HubTest < Test::Unit::TestCase
|
|
752
766
|
assert_output expected, "fork"
|
753
767
|
end
|
754
768
|
|
769
|
+
def test_fork_https_protocol
|
770
|
+
stub_https_is_preferred
|
771
|
+
stub_nonexisting_fork('tpw')
|
772
|
+
stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/fork/defunkt/hub")
|
773
|
+
|
774
|
+
expected = "remote add -f tpw https://github.com/tpw/hub.git\n"
|
775
|
+
expected << "new remote: tpw\n"
|
776
|
+
assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
|
777
|
+
end
|
778
|
+
|
755
779
|
def test_fork_not_in_repo
|
756
780
|
stub_no_git_repo
|
757
781
|
expected = "fatal: Not a git repository\n"
|
@@ -792,19 +816,7 @@ class HubTest < Test::Unit::TestCase
|
|
792
816
|
def test_fork_already_exists
|
793
817
|
stub_existing_fork('tpw')
|
794
818
|
|
795
|
-
expected = "tpw/hub already exists on github.com\n"
|
796
|
-
expected << "remote add -f tpw git@github.com:tpw/hub.git\n"
|
797
|
-
expected << "new remote: tpw\n"
|
798
|
-
assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
|
799
|
-
end
|
800
|
-
|
801
|
-
def test_fork_https_protocol
|
802
|
-
stub_existing_fork('tpw')
|
803
|
-
stub_https_is_preferred
|
804
|
-
|
805
|
-
expected = "tpw/hub already exists on github.com\n"
|
806
|
-
expected << "remote add -f tpw https://github.com/tpw/hub.git\n"
|
807
|
-
expected << "new remote: tpw\n"
|
819
|
+
expected = "Error creating fork: tpw/hub already exists on github.com\n"
|
808
820
|
assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
|
809
821
|
end
|
810
822
|
|
@@ -860,6 +872,15 @@ class HubTest < Test::Unit::TestCase
|
|
860
872
|
assert_output expected, "pull-request hereyougo -f"
|
861
873
|
end
|
862
874
|
|
875
|
+
def test_pullrequest_invalid_remote
|
876
|
+
stub_repo_url('gh:singingwolfboy/sekrit.git')
|
877
|
+
stub_branch('refs/heads/feature')
|
878
|
+
stub_tracking('feature', 'origin', 'feature')
|
879
|
+
|
880
|
+
expected = "Aborted: the origin remote doesn't point to a GitHub repository.\n"
|
881
|
+
assert_output expected, "pull-request hereyougo"
|
882
|
+
end
|
883
|
+
|
863
884
|
def test_pullrequest_enterprise_no_tracking
|
864
885
|
stub_hub_host('git.my.org')
|
865
886
|
stub_repo_url('git@git.my.org:defunkt/hub.git')
|
@@ -1043,6 +1064,22 @@ Use git-config(1) to display the currently configured GitHub username:
|
|
1043
1064
|
config
|
1044
1065
|
end
|
1045
1066
|
|
1067
|
+
def test_help_flag_on_command
|
1068
|
+
help_manpage = hub("browse --help")
|
1069
|
+
assert_includes "git + hub = github", help_manpage
|
1070
|
+
assert_includes "git browse", help_manpage
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def test_help_short_flag_on_command
|
1074
|
+
usage_help = hub("create -h")
|
1075
|
+
expected = "Usage: git create [NAME] [-p] [-d DESCRIPTION] [-h HOMEPAGE]\n"
|
1076
|
+
assert_equal expected, usage_help
|
1077
|
+
|
1078
|
+
usage_help = hub("pull-request -h")
|
1079
|
+
expected = "Usage: git pull-request [-f] [TITLE|-i ISSUE] [-b BASE] [-h HEAD]\n"
|
1080
|
+
assert_equal expected, usage_help
|
1081
|
+
end
|
1082
|
+
|
1046
1083
|
def test_help_hub_no_groff
|
1047
1084
|
stub_available_commands()
|
1048
1085
|
assert_equal "** Can't find groff(1)\n", hub("help hub")
|
@@ -1224,6 +1261,13 @@ config
|
|
1224
1261
|
assert_equal "Usage: hub browse [<USER>/]<REPOSITORY>\n", hub("browse")
|
1225
1262
|
end
|
1226
1263
|
|
1264
|
+
def test_hub_browse_ssh_alias
|
1265
|
+
with_ssh_config do
|
1266
|
+
stub_repo_url "gh:singingwolfboy/sekrit.git"
|
1267
|
+
assert_command "browse", "open https://github.com/singingwolfboy/sekrit"
|
1268
|
+
end
|
1269
|
+
end
|
1270
|
+
|
1227
1271
|
def test_custom_browser
|
1228
1272
|
with_browser_env("custom") do
|
1229
1273
|
assert_browser("custom")
|
@@ -1399,4 +1443,10 @@ config
|
|
1399
1443
|
Hub::Commands.send :improved_help_text
|
1400
1444
|
end
|
1401
1445
|
|
1446
|
+
def with_ssh_config
|
1447
|
+
config_file = File.expand_path '../ssh_config', __FILE__
|
1448
|
+
Hub::Context::SshConfig::CONFIG_FILES.replace [config_file]
|
1449
|
+
yield
|
1450
|
+
end
|
1451
|
+
|
1402
1452
|
end
|
data/test/ssh_config
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.8.
|
4
|
+
version: 1.8.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,8 +10,30 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-03-
|
14
|
-
dependencies:
|
13
|
+
date: 2012-03-20 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rake
|
17
|
+
requirement: &70214684711760 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *70214684711760
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: webmock
|
28
|
+
requirement: &70214684711100 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *70214684711100
|
15
37
|
description: ! " `hub` is a command line utility which adds GitHub knowledge to `git`.\n\n
|
16
38
|
\ It can used on its own or as a `git` wrapper.\n\n Normal:\n\n $ hub clone
|
17
39
|
rtomayko/tilt\n\n Expands to:\n $ git clone git://github.com/rtomayko/tilt.git\n\n
|
@@ -26,6 +48,7 @@ files:
|
|
26
48
|
- README.md
|
27
49
|
- Rakefile
|
28
50
|
- LICENSE
|
51
|
+
- HISTORY.md
|
29
52
|
- lib/hub/args.rb
|
30
53
|
- lib/hub/commands.rb
|
31
54
|
- lib/hub/context.rb
|
@@ -44,6 +67,7 @@ files:
|
|
44
67
|
- test/fakebin/open
|
45
68
|
- test/helper.rb
|
46
69
|
- test/hub_test.rb
|
70
|
+
- test/ssh_config
|
47
71
|
- test/standalone_test.rb
|
48
72
|
homepage: https://github.com/defunkt/hub
|
49
73
|
licenses: []
|