hub 1.8.1 → 1.8.2
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 +1 -1
- data/lib/hub/commands.rb +36 -13
- data/lib/hub/context.rb +4 -0
- data/lib/hub/version.rb +1 -1
- data/test/helper.rb +7 -1
- data/test/hub_test.rb +21 -11
- metadata +2 -2
data/README.md
CHANGED
@@ -201,7 +201,7 @@ superpowers:
|
|
201
201
|
|
202
202
|
# $ git checkout https://github.com/defunkt/hub/pull/73
|
203
203
|
# > git remote add -f -t feature git://github:com/mislav/hub.git
|
204
|
-
# > git checkout -
|
204
|
+
# > git checkout --track -B mislav-feature mislav/feature
|
205
205
|
|
206
206
|
# $ git checkout https://github.com/defunkt/hub/pull/73 custom-branch-name
|
207
207
|
|
data/lib/hub/commands.rb
CHANGED
@@ -34,7 +34,7 @@ module Hub
|
|
34
34
|
# provides git interrogation methods
|
35
35
|
extend Context
|
36
36
|
|
37
|
-
NAME_RE =
|
37
|
+
NAME_RE = /\w[\w.-]*/
|
38
38
|
OWNER_RE = /[a-zA-Z0-9-]+/
|
39
39
|
NAME_WITH_OWNER_RE = /^(?:#{NAME_RE}|#{OWNER_RE}\/#{NAME_RE})$/
|
40
40
|
|
@@ -125,7 +125,7 @@ module Hub
|
|
125
125
|
remote_branch = "#{head_project.remote}/#{options[:head]}"
|
126
126
|
options[:head] = "#{head_project.owner}:#{options[:head]}"
|
127
127
|
|
128
|
-
if !force and tracked_branch and local_commits =
|
128
|
+
if !force and tracked_branch and local_commits = rev_list(remote_branch, nil)
|
129
129
|
$stderr.puts "Aborted: #{local_commits.split("\n").size} commits are not yet pushed to #{remote_branch}"
|
130
130
|
warn "(use `-f` to force submit a pull request anyway)"
|
131
131
|
abort
|
@@ -138,10 +138,25 @@ module Hub
|
|
138
138
|
|
139
139
|
unless options[:title] or options[:issue]
|
140
140
|
base_branch = "#{base_project.remote}/#{options[:base]}"
|
141
|
-
|
142
|
-
|
141
|
+
commits = rev_list(base_branch, remote_branch).to_s.split("\n")
|
142
|
+
|
143
|
+
case commits.size
|
144
|
+
when 0
|
145
|
+
default_message = commit_summary = nil
|
146
|
+
when 1
|
147
|
+
format = '%w(78,0,0)%s%n%+b'
|
148
|
+
default_message = git_command "show -s --format='#{format}' #{commits.first}"
|
149
|
+
commit_summary = nil
|
150
|
+
else
|
151
|
+
format = '%h (%aN, %ar)%n%w(78,3,3)%s%n%+b'
|
152
|
+
default_message = nil
|
153
|
+
commit_summary = git_command "log --no-color --format='%s' --cherry %s...%s" %
|
154
|
+
[format, base_branch, remote_branch]
|
155
|
+
end
|
143
156
|
|
144
|
-
options[:title], options[:body] = pullrequest_editmsg(
|
157
|
+
options[:title], options[:body] = pullrequest_editmsg(commit_summary) { |msg|
|
158
|
+
msg.puts default_message if default_message
|
159
|
+
msg.puts ""
|
145
160
|
msg.puts "# Requesting a pull to #{base_project.owner}:#{options[:base]} from #{options[:head]}"
|
146
161
|
msg.puts "#"
|
147
162
|
msg.puts "# Write a message for this pull request. The first block"
|
@@ -181,7 +196,7 @@ module Hub
|
|
181
196
|
else
|
182
197
|
# $ hub clone rtomayko/tilt
|
183
198
|
# $ hub clone tilt
|
184
|
-
if arg =~ NAME_WITH_OWNER_RE
|
199
|
+
if arg =~ NAME_WITH_OWNER_RE and !File.directory?(arg)
|
185
200
|
# FIXME: this logic shouldn't be duplicated here!
|
186
201
|
name, owner = arg, nil
|
187
202
|
owner, name = name.split('/', 2) if name.index('/')
|
@@ -303,17 +318,20 @@ module Hub
|
|
303
318
|
|
304
319
|
# $ git checkout https://github.com/defunkt/hub/pull/73
|
305
320
|
# > git remote add -f -t feature git://github:com/mislav/hub.git
|
306
|
-
# > git checkout -
|
321
|
+
# > git checkout --track -B mislav-feature mislav/feature
|
307
322
|
def checkout(args)
|
308
|
-
|
323
|
+
_, url_arg, new_branch_name = args.words
|
324
|
+
if url = resolve_github_url(url_arg) and url.project_path =~ /^pull\/(\d+)/
|
309
325
|
pull_id = $1
|
310
326
|
|
311
327
|
load_net_http
|
312
328
|
response = http_request(url.project.api_pullrequest_url(pull_id, 'json'))
|
313
329
|
pull_data = JSON.parse(response.body)['pull']
|
314
330
|
|
331
|
+
args.delete new_branch_name
|
315
332
|
user, branch = pull_data['head']['label'].split(':', 2)
|
316
|
-
|
333
|
+
abort "Error: #{user}'s fork is not available anymore" unless pull_data['head']['repository']
|
334
|
+
new_branch_name ||= "#{user}-#{branch}"
|
317
335
|
|
318
336
|
if remotes.include? user
|
319
337
|
args.before ['remote', 'set-branches', '--add', user, branch]
|
@@ -323,7 +341,9 @@ module Hub
|
|
323
341
|
:https => https_protocol?)
|
324
342
|
args.before ['remote', 'add', '-f', '-t', branch, user, url]
|
325
343
|
end
|
326
|
-
|
344
|
+
idx = args.index url_arg
|
345
|
+
args.delete_at idx
|
346
|
+
args.insert idx, '--track', '-B', new_branch_name, "#{user}/#{branch}"
|
327
347
|
end
|
328
348
|
end
|
329
349
|
|
@@ -353,7 +373,7 @@ module Hub
|
|
353
373
|
args[args.index(ref)] = sha
|
354
374
|
|
355
375
|
if remote = project.remote and remotes.include? remote
|
356
|
-
args.before ['fetch', remote]
|
376
|
+
args.before ['fetch', remote.to_s]
|
357
377
|
else
|
358
378
|
args.before ['remote', 'add', '-f', project.owner, project.git_url(:https => https_protocol?)]
|
359
379
|
end
|
@@ -368,6 +388,8 @@ module Hub
|
|
368
388
|
if url = args.find { |a| a =~ %r{^https?://(gist\.)?github\.com/} }
|
369
389
|
idx = args.index(url)
|
370
390
|
gist = $1 == 'gist.'
|
391
|
+
# strip the fragment part of the url
|
392
|
+
url = url.sub(/#.+/, '')
|
371
393
|
# strip extra path from "pull/42/files", "pull/42/commits"
|
372
394
|
url = url.sub(%r{(/pull/\d+)/\w*$}, '\1') unless gist
|
373
395
|
ext = gist ? '.txt' : '.patch'
|
@@ -891,14 +913,15 @@ help
|
|
891
913
|
def pullrequest_editmsg(changes)
|
892
914
|
message_file = File.join(git_dir, 'PULLREQ_EDITMSG')
|
893
915
|
File.open(message_file, 'w') { |msg|
|
894
|
-
msg.puts
|
895
916
|
yield msg
|
896
917
|
if changes
|
897
918
|
msg.puts "#\n# Changes:\n#"
|
898
919
|
msg.puts changes.gsub(/^/, '# ').gsub(/ +$/, '')
|
899
920
|
end
|
900
921
|
}
|
901
|
-
edit_cmd = Array(git_editor).dup
|
922
|
+
edit_cmd = Array(git_editor).dup
|
923
|
+
edit_cmd << '-c' << 'set ft=gitcommit' if edit_cmd[0] =~ /^[mg]?vim$/
|
924
|
+
edit_cmd << message_file
|
902
925
|
system(*edit_cmd)
|
903
926
|
abort "can't open text editor for pull request message" unless $?.success?
|
904
927
|
title, body = read_editmsg(message_file)
|
data/lib/hub/context.rb
CHANGED
data/lib/hub/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -16,7 +16,13 @@ class Test::Unit::TestCase
|
|
16
16
|
# shell: hub clone rtomayko/tilt
|
17
17
|
# test: Hub("clone rtomayko/tilt")
|
18
18
|
def Hub(args)
|
19
|
-
Hub::Runner.new(*args.split(' '))
|
19
|
+
runner = Hub::Runner.new(*args.split(' ').map {|a| a.freeze })
|
20
|
+
runner.args.commands.each do |cmd|
|
21
|
+
if Array === cmd and invalid = cmd.find {|c| !c.respond_to? :to_str }
|
22
|
+
raise "#{invalid.inspect} is not a string (in #{cmd.join(' ').inspect})"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
runner
|
20
26
|
end
|
21
27
|
|
22
28
|
# Shortcut for running the `hub` command in a subprocess. Returns
|
data/test/hub_test.rb
CHANGED
@@ -160,6 +160,16 @@ class HubTest < Test::Unit::TestCase
|
|
160
160
|
assert_forwarded "clone ./test"
|
161
161
|
end
|
162
162
|
|
163
|
+
def test_unchanged_clone_from_existing_directory
|
164
|
+
stub_no_git_repo
|
165
|
+
assert_forwarded "clone test"
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_local_clone_with_destination
|
169
|
+
stub_no_git_repo
|
170
|
+
assert_forwarded "clone -l . ../copy"
|
171
|
+
end
|
172
|
+
|
163
173
|
def test_clone_with_host_alias
|
164
174
|
stub_no_git_repo
|
165
175
|
assert_forwarded "clone server:git/repo.git"
|
@@ -461,7 +471,7 @@ class HubTest < Test::Unit::TestCase
|
|
461
471
|
with_tmpdir('/tmp/') do
|
462
472
|
assert_commands "curl -#LA 'hub #{Hub::Version}' https://github.com/defunkt/hub/pull/55.patch -o /tmp/55.patch",
|
463
473
|
"git am --signoff /tmp/55.patch -p2",
|
464
|
-
"am --signoff https://github.com/defunkt/hub/pull/55 -p2"
|
474
|
+
"am --signoff https://github.com/defunkt/hub/pull/55#comment_123 -p2"
|
465
475
|
|
466
476
|
cmd = Hub("am https://github.com/defunkt/hub/pull/55/files").command
|
467
477
|
assert_includes '/pull/55.patch', cmd
|
@@ -806,7 +816,7 @@ class HubTest < Test::Unit::TestCase
|
|
806
816
|
|
807
817
|
def test_pullrequest_with_unpushed_commits
|
808
818
|
stub_tracking('master', 'mislav', 'master')
|
809
|
-
stub_command_output "rev-list --cherry mislav/master...", "+abcd1234\n+bcde2345"
|
819
|
+
stub_command_output "rev-list --cherry-pick --right-only --no-merges mislav/master...", "+abcd1234\n+bcde2345"
|
810
820
|
|
811
821
|
expected = "Aborted: 2 commits are not yet pushed to mislav/master\n" <<
|
812
822
|
"(use `-f` to force submit a pull request anyway)\n"
|
@@ -829,7 +839,7 @@ class HubTest < Test::Unit::TestCase
|
|
829
839
|
def test_pullrequest_from_tracking_branch
|
830
840
|
stub_branch('refs/heads/feature')
|
831
841
|
stub_tracking('feature', 'mislav', 'yay-feature')
|
832
|
-
stub_command_output "rev-list --cherry mislav/master...", nil
|
842
|
+
stub_command_output "rev-list --cherry-pick --right-only --no-merges mislav/master...", nil
|
833
843
|
|
834
844
|
stub_request(:post, "https://#{auth}github.com/api/v2/json/pulls/defunkt/hub").
|
835
845
|
with(:body => { 'pull' => {'base' => "master", 'head' => "mislav:yay-feature", 'title' => "hereyougo"} }).
|
@@ -846,7 +856,7 @@ class HubTest < Test::Unit::TestCase
|
|
846
856
|
stub_github_token('789xyz', 'git.my.org')
|
847
857
|
stub_branch('refs/heads/feature')
|
848
858
|
stub_tracking_nothing('feature')
|
849
|
-
stub_command_output "rev-list --cherry origin/feature...", nil
|
859
|
+
stub_command_output "rev-list --cherry-pick --right-only --no-merges origin/feature...", nil
|
850
860
|
|
851
861
|
stub_request(:post, "https://#{auth('myfiname', '789xyz')}git.my.org/api/v2/json/pulls/defunkt/hub").
|
852
862
|
with(:body => { 'pull' => {'base' => "master", 'head' => "myfiname:feature", 'title' => "hereyougo"} }).
|
@@ -904,7 +914,7 @@ class HubTest < Test::Unit::TestCase
|
|
904
914
|
def test_pullrequest_existing_issue
|
905
915
|
stub_branch('refs/heads/myfix')
|
906
916
|
stub_tracking('myfix', 'mislav', 'awesomefix')
|
907
|
-
stub_command_output "rev-list --cherry mislav/awesomefix...", nil
|
917
|
+
stub_command_output "rev-list --cherry-pick --right-only --no-merges mislav/awesomefix...", nil
|
908
918
|
|
909
919
|
stub_request(:post, "https://#{auth}github.com/api/v2/json/pulls/defunkt/hub").
|
910
920
|
with(:body => { 'pull' => {'base' => "master", 'head' => "mislav:awesomefix", 'issue' => '92'} }).
|
@@ -917,7 +927,7 @@ class HubTest < Test::Unit::TestCase
|
|
917
927
|
def test_pullrequest_existing_issue_url
|
918
928
|
stub_branch('refs/heads/myfix')
|
919
929
|
stub_tracking('myfix', 'mislav', 'awesomefix')
|
920
|
-
stub_command_output "rev-list --cherry mislav/awesomefix...", nil
|
930
|
+
stub_command_output "rev-list --cherry-pick --right-only --no-merges mislav/awesomefix...", nil
|
921
931
|
|
922
932
|
stub_request(:post, "https://#{auth}github.com/api/v2/json/pulls/mojombo/hub").
|
923
933
|
with(:body => { 'pull' => {'base' => "master", 'head' => "mislav:awesomefix", 'issue' => '92'} }).
|
@@ -947,8 +957,8 @@ class HubTest < Test::Unit::TestCase
|
|
947
957
|
to_return(:body => mock_pull_response('blueyed:feature'))
|
948
958
|
|
949
959
|
assert_commands 'git remote add -f -t feature blueyed git://github.com/blueyed/hub.git',
|
950
|
-
'git checkout -
|
951
|
-
"checkout https://github.com/defunkt/hub/pull/73/files"
|
960
|
+
'git checkout -f --track -B blueyed-feature blueyed/feature -q',
|
961
|
+
"checkout -f https://github.com/defunkt/hub/pull/73/files -q"
|
952
962
|
end
|
953
963
|
|
954
964
|
def test_checkout_private_pullrequest
|
@@ -956,7 +966,7 @@ class HubTest < Test::Unit::TestCase
|
|
956
966
|
to_return(:body => mock_pull_response('blueyed:feature', :private))
|
957
967
|
|
958
968
|
assert_commands 'git remote add -f -t feature blueyed git@github.com:blueyed/hub.git',
|
959
|
-
'git checkout -
|
969
|
+
'git checkout --track -B blueyed-feature blueyed/feature',
|
960
970
|
"checkout https://github.com/defunkt/hub/pull/73/files"
|
961
971
|
end
|
962
972
|
|
@@ -965,7 +975,7 @@ class HubTest < Test::Unit::TestCase
|
|
965
975
|
to_return(:body => mock_pull_response('blueyed:feature'))
|
966
976
|
|
967
977
|
assert_commands 'git remote add -f -t feature blueyed git://github.com/blueyed/hub.git',
|
968
|
-
'git checkout -
|
978
|
+
'git checkout --track -B review blueyed/feature',
|
969
979
|
"checkout https://github.com/defunkt/hub/pull/73/files review"
|
970
980
|
end
|
971
981
|
|
@@ -977,7 +987,7 @@ class HubTest < Test::Unit::TestCase
|
|
977
987
|
|
978
988
|
assert_commands 'git remote set-branches --add blueyed feature',
|
979
989
|
'git fetch blueyed +refs/heads/feature:refs/remotes/blueyed/feature',
|
980
|
-
'git checkout -
|
990
|
+
'git checkout --track -B blueyed-feature blueyed/feature',
|
981
991
|
"checkout https://github.com/defunkt/hub/pull/73/files"
|
982
992
|
end
|
983
993
|
|
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.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-02-07 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: ! " `hub` is a command line utility which adds GitHub knowledge to `git`.\n\n
|
16
16
|
\ It can used on its own or as a `git` wrapper.\n\n Normal:\n\n $ hub clone
|