hub 1.6.1 → 1.7.0
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/README.md +94 -60
- data/Rakefile +74 -38
- data/lib/hub/args.rb +16 -3
- data/lib/hub/commands.rb +340 -101
- data/lib/hub/context.rb +270 -112
- data/lib/hub/runner.rb +4 -2
- data/lib/hub/standalone.rb +13 -7
- data/lib/hub/version.rb +1 -1
- data/man/hub.1 +162 -80
- data/man/hub.1.html +163 -96
- data/man/hub.1.ronn +84 -167
- data/test/alias_test.rb +0 -1
- data/test/helper.rb +8 -8
- data/test/hub_test.rb +395 -71
- data/test/standalone_test.rb +0 -1
- metadata +8 -6
data/README.md
CHANGED
@@ -114,7 +114,7 @@ The alias command can also be eval'd directly using the `-s` flag:
|
|
114
114
|
Commands
|
115
115
|
--------
|
116
116
|
|
117
|
-
Assuming you've aliased `hub` to `git
|
117
|
+
Assuming you've aliased `hub` to `git`, the following commands now have
|
118
118
|
superpowers:
|
119
119
|
|
120
120
|
### git clone
|
@@ -126,10 +126,7 @@ superpowers:
|
|
126
126
|
> git clone git@github.com:schacon/ticgit.git
|
127
127
|
|
128
128
|
$ git clone resque
|
129
|
-
> git clone git
|
130
|
-
|
131
|
-
$ git clone -p resque
|
132
|
-
> git clone git@github.com:YOUR_USER/resque.git
|
129
|
+
> git clone git@github.com/YOUR_USER/resque.git
|
133
130
|
|
134
131
|
### git remote add
|
135
132
|
|
@@ -167,24 +164,63 @@ superpowers:
|
|
167
164
|
> git fetch mislav
|
168
165
|
> git cherry-pick SHA
|
169
166
|
|
167
|
+
### git am, git apply
|
168
|
+
|
169
|
+
$ git am https://github.com/defunkt/hub/pull/55
|
170
|
+
> curl https://github.com/defunkt/hub/pull/55.patch -o /tmp/55.patch
|
171
|
+
> git am /tmp/55.patch
|
172
|
+
|
173
|
+
$ git am --ignore-whitespace https://github.com/davidbalbert/hub/commit/fdb9921
|
174
|
+
> curl https://github.com/davidbalbert/hub/commit/fdb9921.patch -o /tmp/fdb9921.patch
|
175
|
+
> git am --ignore-whitespace /tmp/fdb9921.patch
|
176
|
+
|
177
|
+
$ git apply https://gist.github.com/8da7fb575debd88c54cf
|
178
|
+
> curl https://gist.github.com/8da7fb575debd88c54cf.txt -o /tmp/gist-8da7fb575debd88c54cf.txt
|
179
|
+
> git apply /tmp/gist-8da7fb575debd88c54cf.txt
|
180
|
+
|
170
181
|
### git fork
|
171
182
|
|
172
183
|
$ git fork
|
173
|
-
|
184
|
+
[ repo forked on GitHub ]
|
174
185
|
> git remote add -f YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
|
175
186
|
|
176
|
-
|
177
|
-
|
178
|
-
|
187
|
+
### git pull-request
|
188
|
+
|
189
|
+
# while on a topic branch called "feature":
|
190
|
+
$ git pull-request
|
191
|
+
[ opens text editor to edit title & body for the request ]
|
192
|
+
[ opened pull request on GitHub for "YOUR_USER:feature" ]
|
193
|
+
|
194
|
+
# explicit title, pull base & head:
|
195
|
+
$ git pull-request "I've implemented feature X" -b defunkt:master -h mislav:feature
|
196
|
+
|
197
|
+
$ git pull-request -i 123
|
198
|
+
[ attached pull request to issue #123 ]
|
199
|
+
|
200
|
+
### git checkout
|
201
|
+
|
202
|
+
# $ git checkout https://github.com/defunkt/hub/pull/73
|
203
|
+
# > git remote add -f -t feature git://github:com/mislav/hub.git
|
204
|
+
# > git checkout -b mislav-feature mislav/feature
|
205
|
+
|
206
|
+
# $ git checkout https://github.com/defunkt/hub/pull/73 custom-branch-name
|
179
207
|
|
180
208
|
### git create
|
181
209
|
|
182
210
|
$ git create
|
183
|
-
|
211
|
+
[ repo created on GitHub ]
|
184
212
|
> git remote add origin git@github.com:YOUR_USER/CURRENT_REPO.git
|
185
213
|
|
186
|
-
|
187
|
-
|
214
|
+
# with description:
|
215
|
+
$ git create -d 'It shall be mine, all mine!'
|
216
|
+
|
217
|
+
$ git create recipes
|
218
|
+
[ repo created on GitHub ]
|
219
|
+
> git remote add origin git@github.com:YOUR_USER/recipes.git
|
220
|
+
|
221
|
+
$ git create sinatra/recipes
|
222
|
+
[ repo created in GitHub organization ]
|
223
|
+
> git remote add origin git@github.com:sinatra/recipes.git
|
188
224
|
|
189
225
|
### git init
|
190
226
|
|
@@ -204,12 +240,18 @@ Creates a new public github repository and adds the remote `origin` at
|
|
204
240
|
$ git browse
|
205
241
|
> open https://github.com/YOUR_USER/CURRENT_REPO
|
206
242
|
|
243
|
+
$ git browse -- commit/SHA
|
244
|
+
> open https://github.com/YOUR_USER/CURRENT_REPO/commit/SHA
|
245
|
+
|
207
246
|
$ git browse -- issues
|
208
247
|
> open https://github.com/YOUR_USER/CURRENT_REPO/issues
|
209
248
|
|
210
249
|
$ git browse schacon/ticgit
|
211
250
|
> open https://github.com/schacon/ticgit
|
212
251
|
|
252
|
+
$ git browse schacon/ticgit commit/SHA
|
253
|
+
> open https://github.com/schacon/ticgit/commit/SHA
|
254
|
+
|
213
255
|
$ git browse resque
|
214
256
|
> open https://github.com/YOUR_USER/resque
|
215
257
|
|
@@ -221,7 +263,7 @@ Creates a new public github repository and adds the remote `origin` at
|
|
221
263
|
$ git compare refactor
|
222
264
|
> open https://github.com/CURRENT_REPO/compare/refactor
|
223
265
|
|
224
|
-
$ git compare 1.0
|
266
|
+
$ git compare 1.0..1.1
|
225
267
|
> open https://github.com/CURRENT_REPO/compare/1.0...1.1
|
226
268
|
|
227
269
|
$ git compare -u fix
|
@@ -265,35 +307,25 @@ If you see nothing, you need to set the config setting:
|
|
265
307
|
$ git config --global github.user YOUR_USER
|
266
308
|
|
267
309
|
For commands that require write access to GitHub (such as `fork`), you'll want to
|
268
|
-
setup "github.token" as well. See [
|
269
|
-
|
270
|
-
Want to use environment variables instead of a local gitconfig?
|
310
|
+
setup "github.token" as well. See [GitHub config guide][2] for more information.
|
271
311
|
|
272
|
-
|
273
|
-
|
274
|
-
* `GITHUB_TOKEN` - If set, this will be used instead of the `github.token` config
|
275
|
-
value to determine your GitHub API token.
|
312
|
+
If present, environment variables `GITHUB_USER` and `GITHUB_TOKEN` override the
|
313
|
+
values of "github.user" and "github.token".
|
276
314
|
|
277
315
|
Configuration
|
278
316
|
-------------
|
279
317
|
|
280
|
-
If you prefer
|
281
|
-
|
318
|
+
If you prefer using the HTTPS protocol for GitHub repositories instead of the git
|
319
|
+
protocol for read and ssh for write, you can set "hub.protocol" to "https".
|
282
320
|
|
283
321
|
For example:
|
284
322
|
|
285
323
|
$ git clone defunkt/repl
|
286
324
|
< git clone >
|
287
|
-
|
325
|
+
|
326
|
+
$ git config --global hub.protocol https
|
288
327
|
$ git clone defunkt/repl
|
289
|
-
<
|
290
|
-
|
291
|
-
Or you can enter this manually into your `~/.gitconfig` file:
|
292
|
-
|
293
|
-
$ cat ~/.gitconfig
|
294
|
-
[hub]
|
295
|
-
http-clone = yes
|
296
|
-
|
328
|
+
< https clone >
|
297
329
|
|
298
330
|
Prior Art
|
299
331
|
---------
|
@@ -302,41 +334,45 @@ These projects also aim to either improve git or make interacting with
|
|
302
334
|
GitHub simpler:
|
303
335
|
|
304
336
|
* [eg](http://www.gnome.org/~newren/eg/)
|
305
|
-
* [github-gem](
|
306
|
-
* [gh](http://github.com/visionmedia/gh)
|
337
|
+
* [github-gem](https://github.com/defunkt/github-gem)
|
307
338
|
|
308
339
|
|
309
340
|
Contributing
|
310
341
|
------------
|
311
342
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
343
|
+
These instructions assume that you already have `hub` installed and that
|
344
|
+
you've set it up so it wraps `git` (see "Aliasing").
|
345
|
+
|
346
|
+
1. Clone hub:
|
347
|
+
`git clone defunkt/hub`
|
348
|
+
2. Verify that existing tests pass (see "Development dependencies"):
|
349
|
+
`rake test`
|
350
|
+
3. Create a topic branch:
|
351
|
+
`git checkout -b my_branch`
|
352
|
+
4. Make your changes – it helps a lot if you write tests first
|
353
|
+
5. Verify that tests still pass:
|
354
|
+
`rake test`
|
355
|
+
6. Fork hub on GitHub (adds a remote named "YOUR_USER"):
|
356
|
+
`git fork`
|
357
|
+
7. Push to your fork:
|
358
|
+
`git push -u YOUR_USER my_branch`
|
359
|
+
8. Open a pull request describing your changes:
|
360
|
+
`git pull-request`
|
361
|
+
|
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
|
+
* [json](http://flori.github.com/json/) (ruby 1.8 only)
|
330
369
|
|
331
370
|
Meta
|
332
371
|
----
|
333
372
|
|
334
|
-
*
|
335
|
-
*
|
336
|
-
*
|
337
|
-
* List: <http://groups.google.com/group/github>
|
338
|
-
* Test: <http://runcoderun.com/defunkt/hub>
|
339
|
-
* Gems: <http://gemcutter.org/gems/hub>
|
373
|
+
* Home: <https://github.com/defunkt/hub>
|
374
|
+
* Bugs: <https://github.com/defunkt/hub/issues>
|
375
|
+
* Gem: <https://rubygems.org/gems/hub>
|
340
376
|
|
341
377
|
|
342
378
|
Authors
|
@@ -344,8 +380,6 @@ Authors
|
|
344
380
|
|
345
381
|
<https://github.com/defunkt/hub/contributors>
|
346
382
|
|
347
|
-
[0]: http://help.github.com/forking/
|
348
|
-
[1]: http://github.com/defunkt/hub/issues
|
349
383
|
[speed]: http://gist.github.com/284823
|
350
|
-
[2]: http://github.com/
|
384
|
+
[2]: http://help.github.com/set-your-user-name-email-and-github-token/
|
351
385
|
[gc]: https://twitter.com/brynary/status/49560668994674688
|
data/Rakefile
CHANGED
@@ -4,19 +4,21 @@ require 'rake/testtask'
|
|
4
4
|
# Helpers
|
5
5
|
#
|
6
6
|
|
7
|
-
def command?(
|
8
|
-
|
9
|
-
|
7
|
+
def command?(util)
|
8
|
+
Rake::Task[:load_path].invoke
|
9
|
+
context = Object.new
|
10
|
+
require 'hub/context'
|
11
|
+
context.extend Hub::Context
|
12
|
+
context.send(:command?, util)
|
10
13
|
end
|
11
14
|
|
12
|
-
task :
|
13
|
-
$LOAD_PATH.unshift 'lib'
|
14
|
-
require 'hub'
|
15
|
+
task :load_path do
|
16
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
15
17
|
end
|
16
18
|
|
17
19
|
task :check_dirty do
|
18
|
-
|
19
|
-
abort "
|
20
|
+
unless system 'git', 'diff', '--quiet', 'HEAD'
|
21
|
+
abort "Aborted: you have uncommitted changes"
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -27,19 +29,11 @@ end
|
|
27
29
|
|
28
30
|
task :default => :test
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
else
|
37
|
-
Rake::TestTask.new do |t|
|
38
|
-
t.libs << 'lib'
|
39
|
-
t.ruby_opts << '-rubygems'
|
40
|
-
t.pattern = 'test/**/*_test.rb'
|
41
|
-
t.verbose = false
|
42
|
-
end
|
32
|
+
Rake::TestTask.new do |t|
|
33
|
+
t.libs << 'test'
|
34
|
+
t.ruby_opts << '-rubygems'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
43
37
|
end
|
44
38
|
|
45
39
|
if command? :kicker
|
@@ -52,34 +46,71 @@ end
|
|
52
46
|
|
53
47
|
|
54
48
|
#
|
55
|
-
#
|
49
|
+
# Manual
|
56
50
|
#
|
57
51
|
|
58
52
|
if command? :ronn
|
59
|
-
desc "Show
|
53
|
+
desc "Show man page"
|
60
54
|
task :man => "man:build" do
|
61
55
|
exec "man man/hub.1"
|
62
56
|
end
|
63
57
|
|
64
|
-
desc "Build
|
65
|
-
task "man:build"
|
66
|
-
|
58
|
+
desc "Build man pages"
|
59
|
+
task "man:build" => ["man/hub.1", "man/hub.1.html"]
|
60
|
+
|
61
|
+
extract_examples = lambda { |readme_file|
|
62
|
+
# split readme in sections
|
63
|
+
examples = File.read(readme_file).split(/^-{4,}$/)[3].strip
|
64
|
+
examples.sub!(/^.+?(###)/m, '\1') # strip intro paragraph
|
65
|
+
examples.sub!(/\n+.+\Z/, '') # remove last line
|
66
|
+
examples
|
67
|
+
}
|
68
|
+
|
69
|
+
# inject examples from README file to .ronn source
|
70
|
+
source_with_examples = lambda { |source, readme|
|
71
|
+
examples = extract_examples.call(readme)
|
72
|
+
compiled = File.read(source)
|
73
|
+
compiled.sub!('{{README}}', examples)
|
74
|
+
compiled
|
75
|
+
}
|
76
|
+
|
77
|
+
# generate man page with ronn
|
78
|
+
compile_ronn = lambda { |destination, type, contents|
|
79
|
+
File.popen("ronn --pipe --#{type} --organization=DEFUNKT --manual='Git Manual'", 'w+') { |io|
|
80
|
+
io.write contents
|
81
|
+
io.close_write
|
82
|
+
File.open(destination, 'w') { |f| f << io.read }
|
83
|
+
}
|
84
|
+
abort "ronn --#{type} conversion failed" unless $?.success?
|
85
|
+
}
|
86
|
+
|
87
|
+
file "man/hub.1" => ["man/hub.1.ronn", "README.md"] do |task|
|
88
|
+
contents = source_with_examples.call(*task.prerequisites)
|
89
|
+
compile_ronn.call(task.name, 'roff', contents)
|
90
|
+
compile_ronn.call("#{task.name}.html", 'html', contents)
|
91
|
+
end
|
92
|
+
|
93
|
+
file "man/hub.1.html" => ["man/hub.1.ronn", "README.md"] do |task|
|
94
|
+
Rake::Task["man/hub.1"].invoke
|
67
95
|
end
|
68
96
|
end
|
69
97
|
|
70
98
|
|
71
99
|
#
|
72
|
-
#
|
100
|
+
# Build
|
73
101
|
#
|
74
102
|
|
75
|
-
|
76
|
-
|
103
|
+
file "hub" => FileList.new("lib/hub/*.rb", "man/hub.1") do |task|
|
104
|
+
Rake::Task[:load_path].invoke
|
77
105
|
require 'hub/standalone'
|
78
|
-
Hub::Standalone.save(
|
106
|
+
Hub::Standalone.save(task.name)
|
79
107
|
end
|
80
108
|
|
109
|
+
desc "Build standalone script"
|
110
|
+
task :standalone => "hub"
|
111
|
+
|
81
112
|
desc "Install standalone script and man pages"
|
82
|
-
task :install =>
|
113
|
+
task :install => "hub" do
|
83
114
|
prefix = ENV['PREFIX'] || ENV['prefix'] || '/usr/local'
|
84
115
|
|
85
116
|
FileUtils.mkdir_p "#{prefix}/bin"
|
@@ -89,16 +120,21 @@ task :install => :standalone do
|
|
89
120
|
FileUtils.cp "man/hub.1", "#{prefix}/share/man/man1"
|
90
121
|
end
|
91
122
|
|
92
|
-
desc "
|
93
|
-
task :
|
123
|
+
desc "Copy files to gh-pages branch, but don't publish"
|
124
|
+
task :gh_pages => [:check_dirty, "hub", "man/hub.1.html"] do
|
94
125
|
cp "man/hub.1.html", "html"
|
95
126
|
sh "git checkout gh-pages"
|
96
|
-
|
97
|
-
sh "
|
98
|
-
sh "
|
99
|
-
|
127
|
+
# replace the specific shebang with a generic ruby one
|
128
|
+
sh "echo '#!/usr/bin/env' ruby > standalone"
|
129
|
+
sh "sed 1d hub >> standalone"
|
130
|
+
mv "html", "hub.1.html"
|
131
|
+
sh "git add standalone hub.1.html"
|
100
132
|
sh "git commit -m 'update standalone'"
|
133
|
+
end
|
134
|
+
|
135
|
+
desc "Publish to GitHub Pages"
|
136
|
+
task :pages => :gh_pages do
|
101
137
|
sh "git push origin gh-pages"
|
102
138
|
sh "git checkout master"
|
103
|
-
puts
|
139
|
+
puts "Done."
|
104
140
|
end
|
data/lib/hub/args.rb
CHANGED
@@ -12,7 +12,7 @@ module Hub
|
|
12
12
|
super
|
13
13
|
@executable = ENV["GIT"] || "git"
|
14
14
|
@after = nil
|
15
|
-
@skip = false
|
15
|
+
@skip = @noop = false
|
16
16
|
@original_args = args.first
|
17
17
|
@chain = [nil]
|
18
18
|
end
|
@@ -43,20 +43,33 @@ module Hub
|
|
43
43
|
|
44
44
|
# Skip running this command.
|
45
45
|
def skip!
|
46
|
-
@skip
|
46
|
+
@skip = true
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
# Boolean indicating whether this command will run.
|
50
50
|
def skip?
|
51
51
|
@skip
|
52
52
|
end
|
53
53
|
|
54
|
+
# Mark that this command shouldn't really run.
|
55
|
+
def noop!
|
56
|
+
@noop = true
|
57
|
+
end
|
58
|
+
|
59
|
+
def noop?
|
60
|
+
@noop
|
61
|
+
end
|
62
|
+
|
54
63
|
# Array of `executable` followed by all args suitable as arguments
|
55
64
|
# for `exec` or `system` calls.
|
56
65
|
def to_exec(args = self)
|
57
66
|
Array(executable) + args
|
58
67
|
end
|
59
68
|
|
69
|
+
def add_exec_flags(flags)
|
70
|
+
self.executable = Array(executable).concat(flags)
|
71
|
+
end
|
72
|
+
|
60
73
|
# All the words (as opposed to flags) contained in this argument
|
61
74
|
# list.
|
62
75
|
#
|