git-hub 1.3.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -166,6 +166,15 @@ Forks the original repo on GitHub and adds the new remote under your
166
166
  username. It requires your GitHub token to be present; see "GitHub
167
167
  login" below for details.
168
168
 
169
+ ### git create
170
+
171
+ $ git create
172
+ ... hardcore creating action ...
173
+ > git remote add origin git@github.com:YOUR_USER/CURRENT_REPO.git
174
+
175
+ Creates a new public github repository and adds the remote `origin` at
176
+ "git@github.com:<USER>/<REPOSITORY>.git"
177
+
169
178
  ### git init
170
179
 
171
180
  $ git init -g
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'rake/testtask'
5
5
  #
6
6
 
7
7
  def command?(command)
8
- `type -t #{command}`
8
+ `which #{command} 2>/dev/null`
9
9
  $?.success?
10
10
  end
11
11
 
@@ -78,14 +78,6 @@ task :standalone => :load_hub do
78
78
  Hub::Standalone.save('hub')
79
79
  end
80
80
 
81
- begin
82
- require 'mg'
83
- MG.new('git-hub.gemspec')
84
- rescue LoadError
85
- warn "mg not available."
86
- warn "Install it with: gem install mg"
87
- end
88
-
89
81
  desc "Install standalone script and man pages"
90
82
  task :install => :standalone do
91
83
  prefix = ENV['PREFIX'] || ENV['prefix'] || '/usr/local'
@@ -97,16 +89,6 @@ task :install => :standalone do
97
89
  FileUtils.cp "man/hub.1", "#{prefix}/share/man/man1"
98
90
  end
99
91
 
100
- desc "Push a new version."
101
- task :publish => "gem:publish" do
102
- require 'hub/version'
103
- system "git tag v#{Hub::Version}"
104
- sh "git push origin v#{Hub::Version}"
105
- sh "git push origin master"
106
- sh "git clean -fd"
107
- exec "rake pages"
108
- end
109
-
110
92
  desc "Publish to GitHub Pages"
111
93
  task :pages => [ "man:build", :check_dirty, :standalone ] do
112
94
  cp "man/hub.1.html", "html"
@@ -35,6 +35,16 @@ module Hub
35
35
  @after ||= block ? block : command
36
36
  end
37
37
 
38
+ # Skip running this command.
39
+ def skip!
40
+ @skip ||= true
41
+ end
42
+
43
+ # Boolean indicating whether this command will run.
44
+ def skip?
45
+ @skip
46
+ end
47
+
38
48
  # Boolean indicating whether an `after` callback has been set.
39
49
  def after?
40
50
  !!@after
@@ -37,8 +37,9 @@ module Hub
37
37
  # Provides `github_url` and various inspection methods
38
38
  extend Context
39
39
 
40
- API_REPO = 'http://github.com/api/v2/yaml/repos/show/%s/%s'
41
- API_FORK = 'http://github.com/api/v2/yaml/repos/fork/%s/%s'
40
+ API_REPO = 'http://github.com/api/v2/yaml/repos/show/%s/%s'
41
+ API_FORK = 'http://github.com/api/v2/yaml/repos/fork/%s/%s'
42
+ API_CREATE = 'http://github.com/api/v2/yaml/repos/create'
42
43
 
43
44
  # $ hub clone rtomayko/tilt
44
45
  # > git clone git://github.com/rtomayko/tilt.
@@ -109,7 +110,7 @@ module Hub
109
110
  # $ hub remote add origin
110
111
  # > git remote add origin git://github.com/YOUR_LOGIN/THIS_REPO.git
111
112
  def remote(args)
112
- return if args[1] != 'add' || args.last =~ %r{.+?://|.+?@|^[./]}
113
+ return unless ['add','set-url'].include?(args[1]) && args.last !~ %r{.+?://|.+?@|^[./]}
113
114
 
114
115
  ssh = args.delete('-p')
115
116
 
@@ -251,6 +252,50 @@ module Hub
251
252
  end
252
253
  end
253
254
 
255
+ # $ hub create
256
+ # ... create repo on github ...
257
+ # > git remote add -f origin git@github.com:YOUR_USER/CURRENT_REPO.git
258
+ def create(args)
259
+ if !is_repo?
260
+ puts "'create' must be run from inside a git repository"
261
+ args.skip!
262
+ elsif github_user && github_token
263
+ args.shift
264
+ options = {}
265
+ options[:private] = true if args.delete('-p')
266
+
267
+ until args.empty?
268
+ case arg = args.shift
269
+ when '-d'
270
+ options[:description] = args.shift
271
+ when '-h'
272
+ options[:homepage] = args.shift
273
+ else
274
+ puts "unexpected argument: #{arg}"
275
+ return
276
+ end
277
+ end
278
+
279
+ if repo_exists?(github_user)
280
+ puts "#{github_user}/#{repo_name} already exists on GitHub"
281
+ action = "set remote origin"
282
+ else
283
+ action = "created repository"
284
+ create_repo(options)
285
+ end
286
+
287
+ url = github_url(:private => true)
288
+
289
+ if remotes.first != 'origin'
290
+ args.replace %W"remote add -f origin #{url}"
291
+ else
292
+ args.replace %W"remote -v"
293
+ end
294
+
295
+ args.after { puts "#{action}: #{github_user}/#{repo_name}" }
296
+ end
297
+ end
298
+
254
299
  # $ hub push origin,staging cool-feature
255
300
  # > git push origin cool-feature
256
301
  # > git push staging cool-feature
@@ -433,7 +478,7 @@ module Hub
433
478
  if command == 'hub'
434
479
  puts hub_manpage
435
480
  exit
436
- elsif command.nil?
481
+ elsif command.nil? && args.grep(/^--?a/).empty?
437
482
  ENV['GIT_PAGER'] = '' if args.grep(/^-{1,2}p/).empty? # Use `cat`.
438
483
  puts improved_help_text
439
484
  exit
@@ -497,7 +542,7 @@ help
497
542
  #
498
543
  # Returns a Boolean.
499
544
  def command?(name)
500
- `type -t #{name}`
545
+ `which #{name} 2>/dev/null`
501
546
  $?.success?
502
547
  end
503
548
 
@@ -624,5 +669,19 @@ help
624
669
  url = API_FORK % [repo_owner, repo_name]
625
670
  Net::HTTP.post_form(URI(url), 'login' => github_user, 'token' => github_token)
626
671
  end
672
+
673
+ # Creates a new repo using the GitHub API.
674
+ #
675
+ # Returns nothing.
676
+ def create_repo(options = {})
677
+ url = API_CREATE
678
+ params = {'login' => github_user, 'token' => github_token, 'name' => repo_name}
679
+ params['public'] = '0' if options[:private]
680
+ params['description'] = options[:description] if options[:description]
681
+ params['homepage'] = options[:homepage] if options[:homepage]
682
+
683
+ Net::HTTP.post_form(URI(url), params)
684
+ end
685
+
627
686
  end
628
687
  end
@@ -10,10 +10,14 @@ module Hub
10
10
 
11
11
  # Parses URLs for git remotes and stores info
12
12
  REMOTES = Hash.new do |cache, remote|
13
- url = GIT_CONFIG["config remote.#{remote}.url"]
13
+ if remote
14
+ url = GIT_CONFIG["config remote.#{remote}.url"]
14
15
 
15
- if url && url.to_s =~ %r{\bgithub\.com[:/](.+)/(.+).git$}
16
- cache[remote] = { :user => $1, :repo => $2 }
16
+ if url && url.to_s =~ %r{\bgithub\.com[:/](.+)/(.+).git$}
17
+ cache[remote] = { :user => $1, :repo => $2 }
18
+ else
19
+ cache[remote] = { }
20
+ end
17
21
  else
18
22
  cache[remote] = { }
19
23
  end
@@ -61,7 +65,7 @@ module Hub
61
65
  end
62
66
 
63
67
  def remotes
64
- list = GIT_CONFIG['remote'].split("\n")
68
+ list = GIT_CONFIG['remote'].to_s.split("\n")
65
69
  main = list.delete('origin') and list.unshift(main)
66
70
  list
67
71
  end
@@ -71,7 +75,13 @@ module Hub
71
75
  end
72
76
 
73
77
  def current_remote
74
- (current_branch && remote_for(current_branch)) || default_remote
78
+ return if remotes.empty?
79
+
80
+ if current_branch
81
+ remote_for(current_branch)
82
+ else
83
+ default_remote
84
+ end
75
85
  end
76
86
 
77
87
  def default_remote
@@ -94,6 +104,14 @@ module Hub
94
104
  GIT_CONFIG['config --bool hub.http-clone'] == 'true'
95
105
  end
96
106
 
107
+ # Core.repositoryformatversion should exist for all git
108
+ # repositories, and be blank for all non-git repositories. If
109
+ # there's a better config setting to check here, this can be
110
+ # changed without breaking anything.
111
+ def is_repo?
112
+ GIT_CONFIG['config core.repositoryformatversion']
113
+ end
114
+
97
115
  def github_url(options = {})
98
116
  repo = options[:repo]
99
117
  user, repo = repo.split('/') if repo && repo.index('/')
@@ -35,16 +35,26 @@ module Hub
35
35
  # A string representation of the git command we would run if
36
36
  # #execute were called.
37
37
  def command
38
- args.to_exec.join(' ')
38
+ if args.skip?
39
+ ''
40
+ else
41
+ args.to_exec.join(' ')
42
+ end
39
43
  end
40
44
 
41
45
  # Runs the target git command with an optional callback. Replaces
42
- # the current process.
46
+ # the current process.
47
+ #
48
+ # If `args` is empty, this will skip calling the git command. This
49
+ # allows commands to print an error message and cancel their own
50
+ # execution if they don't make sense.
43
51
  def execute
44
- if args.after?
45
- execute_with_after_callback
46
- else
47
- exec(*args.to_exec)
52
+ unless args.skip?
53
+ if args.after?
54
+ execute_with_after_callback
55
+ else
56
+ exec(*args.to_exec)
57
+ end
48
58
  end
49
59
  end
50
60
 
@@ -1,3 +1,3 @@
1
1
  module Hub
2
- Version = VERSION = '1.3.2'
2
+ Version = VERSION = '1.4.0'
3
3
  end
data/man/hub.1 CHANGED
@@ -1,10 +1,10 @@
1
1
  .\" generated with Ronn/v0.5
2
2
  .\" http://github.com/rtomayko/ronn/
3
3
  .
4
- .TH "HUB" "1" "April 2010" "DEFUNKT" "Git Manual"
4
+ .TH "HUB" "1" "June 2010" "DEFUNKT" "Git Manual"
5
5
  .
6
6
  .SH "NAME"
7
- \fBhub\fR \-\- git + hub = github
7
+ \fBhub\fR \- git + hub = github
8
8
  .
9
9
  .SH "SYNOPSIS"
10
10
  \fBhub\fR \fICOMMAND\fR \fIOPTIONS\fR
@@ -2,70 +2,149 @@
2
2
  <html>
3
3
  <head>
4
4
  <meta http-equiv='content-type' value='text/html;charset=utf8'>
5
- <meta name='generator' value='Ronn/v0.5'>
6
- <title>hub(1) -- git + hub = github</title>
7
- <style type='text/css'>
8
- body {margin:0}
9
- #man, #man code, #man pre, #man tt, #man kbd, #man samp {
10
- font-family:consolas,monospace;
11
- font-size:16px;
12
- line-height:1.3;
13
- color:#343331;
14
- background:#fff; }
15
- #man { max-width:89ex; text-align:justify; margin:0 25px 25px 25px }
16
- #man h1, #man h2, #man h3 { color:#232221;clear:left }
17
- #man h1 { font-size:28px; margin:15px 0 30px 0; text-align:center }
18
- #man h2 { font-size:18px; margin-bottom:0; margin-top:10px; line-height:1.3; }
19
- #man h3 { font-size:16px; margin:0 0 0 4ex; }
20
- #man p, #man ul, #man ol, #man dl, #man pre { margin:0 0 18px 0; }
21
- #man pre {
22
- color:#333231;
5
+ <meta name='generator' value='Ronn/v0.5 (http://github.com/rtomayko/ronn)'>
6
+ <title>hub(1) - git + hub = github</title>
7
+ <style type='text/css' media='all'>
8
+ /* STRUCTURE, INDENT, MARGINS */
9
+
10
+ body { margin:0}
11
+ #man { max-width:92ex; padding:0 2ex 1ex 2ex}
12
+
13
+ #man p, #man pre,
14
+ #man ul, #man ol, #man dl { margin:0 0 20px 0}
15
+ #man h2 { margin:10px 0 0 0}
16
+
17
+ #man > p, #man > pre,
18
+ #man > ul, #man > ol, #man > dl { margin-left:8ex}
19
+ #man h3 { margin:0 0 0 4ex}
20
+
21
+ #man dt { margin:0; clear:left}
22
+ #man dt.flush { float:left; width:8ex}
23
+ #man dd { margin:0 0 0 9ex}
24
+ #man h1, #man h2, #man h3, #man h4 { clear:left}
25
+
26
+ #man pre { margin-bottom:20px}
27
+ #man pre+h2, #man pre+h3 { margin-top:22px}
28
+ #man h2+pre, #man h3+pre { margin-top:5px}
29
+
30
+ #man img { display:block;margin:auto}
31
+ #man h1.man-title { display:none}
32
+
33
+ /* FONTS */
34
+
35
+ #man, #man code, #man pre,
36
+ #man tt, #man kbd, #man samp,
37
+ #man h3, #man h4 {
38
+ font-family:monospace;
39
+ font-size:14px;
40
+ line-height:1.42857142857143;
41
+ }
42
+ #man h2, #man ol.man, #man .man-navigation a {
43
+ font-size:16px;
44
+ line-height:1.25
45
+ }
46
+ #man h1 {
47
+ font-size:20px;
48
+ line-height:2;
49
+ }
50
+
51
+ /* TEXT STYLES */
52
+
53
+ #man {
54
+ text-align:justify;
55
+ background:#fff;
56
+ }
57
+ #man, #man code, #man pre, #man pre code,
58
+ #man tt, #man kbd, #man samp { color:#131211}
59
+ #man h1, #man h2, #man h3, #man h4 { color:#030201}
60
+ #man ol.man, #man ol.man li { color:#636261}
61
+
62
+ #man code, #man strong, #man b {
63
+ font-weight:bold;
64
+ color:#131211;
65
+ }
66
+
67
+ #man em, #man var, #man u {
68
+ font-style:italic;
69
+ color:#434241;
70
+ text-decoration:none;
71
+ }
72
+
73
+ #man pre {
23
74
  background:#edeceb;
24
- padding:5px 7px;
25
- margin:0px 0 20px 0;
26
- border-left:2ex solid #ddd}
27
- #man pre + h2, #man pre + h3 {
28
- margin-top:22px;
29
- }
30
- #man h2 + pre, #man h3 + pre {
31
- margin-top:5px;
32
- }
33
- #man > p, #man > ul, #man > ol, #man > dl, #man > pre { margin-left:8ex; }
34
- #man dt { margin:0; clear:left }
35
- #man dt.flush { float:left; width:8ex }
36
- #man dd { margin:0 0 0 9ex }
37
- #man code, #man strong, #man b { font-weight:bold; color:#131211; }
38
- #man pre code { font-weight:normal; color:#232221; background:inherit }
39
- #man em, var, u {
40
- font-style:normal; color:#333231; border-bottom:1px solid #999; }
41
- #man h1.man-title { display:none; }
42
- #man ol.man, #man ol.man li { margin:2px 0 10px 0; padding:0;
43
- float:left; width:33%; list-style-type:none;
44
- text-transform:uppercase; font-size:18px; color:#999;
45
- letter-spacing:1px;}
46
- #man ol.man { width:100%; }
47
- #man ol.man li.tl { text-align:left }
48
- #man ol.man li.tc { text-align:center;letter-spacing:4px }
49
- #man ol.man li.tr { text-align:right }
50
- #man ol.man a { color:#999 }
51
- #man ol.man a:hover { color:#333231 }
75
+ padding:5px 1ex;
76
+ border-left:1ex solid #ddd;
77
+ }
78
+ #man pre code {
79
+ font-weight:normal;
80
+ background:inherit;
81
+ }
82
+
83
+ /* DOCUMENT HEADER AND FOOTER AREAS */
84
+
85
+ #man ol.man, #man ol.man li {
86
+ margin:3px 0 10px 0;
87
+ padding:0;
88
+ float:left;
89
+ width:33%;
90
+ list-style-type:none;
91
+ text-transform:uppercase;
92
+ color:#999;
93
+ letter-spacing:1px;
94
+ }
95
+ #man ol.man { width:100%}
96
+ #man ol.man li.tl { text-align:left}
97
+ #man ol.man li.tc { text-align:center; letter-spacing:4px}
98
+ #man ol.man li.tr { text-align:right; float:right}
99
+
100
+ /* SECTION TOC NAVIGATION */
101
+
102
+ #man div.man-navigation {
103
+ position:fixed;
104
+ top:0;
105
+ left:106ex;
106
+ height:100%;
107
+ width:100%;
108
+ padding:1ex 0 0 2ex;
109
+ border-left:0.25ex solid #DCDCDC;
110
+ background-color: #F5F5F5;
111
+ }
112
+ #man div.man-navigation a { display:block; margin-bottom:1.5ex}
113
+ </style>
114
+ <style type='text/css' media='print'>
115
+ #man { max-width:none}
116
+ #man div.man-navigation { display:none}
117
+ #man a[href]:not([href^="#"]):not([data-bare-link]):after {
118
+ content:" " attr(href);
119
+ }
52
120
  </style>
53
121
  </head>
54
- <body>
55
- <div id='man'>
122
+ <body id='manpage'>
123
+ <div id='man'>
124
+
125
+ <div class='man-navigation'>
126
+ <a href="#NAME">NAME</a>
127
+ <a href="#SYNOPSIS">SYNOPSIS</a>
128
+ <a href="#DESCRIPTION">DESCRIPTION</a>
129
+ <a href="#CONFIGURATION">CONFIGURATION</a>
130
+ <a href="#EXAMPLES">EXAMPLES</a>
131
+ <a href="#BUGS">BUGS</a>
132
+ <a href="#AUTHOR">AUTHOR</a>
133
+ <a href="#SEE-ALSO">SEE ALSO</a>
134
+ </div>
56
135
 
57
- <h1 class='man-title'>hub(1)</h1>
136
+ <h1 class='man-title'>hub(1)</h1>
58
137
 
59
- <ol class='head man'>
60
- <li class='tl'>hub(1)</li>
61
- <li class='tc'>Git Manual</li>
62
- <li class='tr'>hub(1)</li>
63
- </ol>
138
+ <ol class='man head'>
139
+ <li class='tl'>hub(1)</li>
140
+ <li class='tc'>Git Manual</li>
141
+ <li class='tr'>hub(1)</li>
142
+ </ol>
64
143
 
65
- <h2 id='NAME'>NAME</h2>
66
- <p><code>hub</code> -- git + hub = github</p>
144
+ <h2 id='NAME'>NAME</h2>
145
+ <p><code>hub</code> - git + hub = github</p>
67
146
 
68
- <h2>SYNOPSIS</h2>
147
+ <h2 id="SYNOPSIS">SYNOPSIS</h2>
69
148
 
70
149
  <p><code>hub</code> <var>COMMAND</var> <var>OPTIONS</var><br />
71
150
  <code>hub alias</code> [<code>-s</code>] <var>SHELL</var></p>
@@ -81,7 +160,7 @@
81
160
  <code>git submodule add</code> [<code>-p</code>] <var>OPTIONS</var> [<var>USER</var>/]<var>REPOSITORY</var> <var>DIRECTORY</var><br />
82
161
  <code>git fork</code> [<code>--no-remote</code>]</p>
83
162
 
84
- <h2>DESCRIPTION</h2>
163
+ <h2 id="DESCRIPTION">DESCRIPTION</h2>
85
164
 
86
165
  <p><code>hub</code> enhances various <code>git</code> commands with GitHub remote expansion. The
87
166
  alias command displays information on configuring your environment:</p>
@@ -132,7 +211,7 @@ be set (see CONFIGURATION).</p></dd>
132
211
  </dl>
133
212
 
134
213
 
135
- <h2>CONFIGURATION</h2>
214
+ <h2 id="CONFIGURATION">CONFIGURATION</h2>
136
215
 
137
216
  <p>Use git-config(1) to display the currently configured GitHub username:</p>
138
217
 
@@ -145,7 +224,7 @@ be set (see CONFIGURATION).</p></dd>
145
224
  $ git config --global github.token &lt;token>
146
225
  </code></pre>
147
226
 
148
- <p>See <a href="http://github.com/guides/local-github-config">http://github.com/guides/local-github-config</a> for more
227
+ <p>See <a href="http://github.com/guides/local-github-config" data-bare-link="true">http://github.com/guides/local-github-config</a> for more
149
228
  information.</p>
150
229
 
151
230
  <p>You can also tell <code>hub</code> to use <code>http://</code> rather than <code>git://</code> when
@@ -154,9 +233,9 @@ cloning:</p>
154
233
  <pre><code>$ git config --global --bool hub.http-clone true
155
234
  </code></pre>
156
235
 
157
- <h2>EXAMPLES</h2>
236
+ <h2 id="EXAMPLES">EXAMPLES</h2>
158
237
 
159
- <h3>git clone</h3>
238
+ <h3 id="git-clone">git clone</h3>
160
239
 
161
240
  <pre><code>$ git clone schacon/ticgit
162
241
  &gt; git clone git://github.com/schacon/ticgit.git
@@ -171,7 +250,7 @@ $ git clone -p resque
171
250
  &gt; git clone git@github.com:YOUR_USER/resque.git
172
251
  </code></pre>
173
252
 
174
- <h3>git remote add</h3>
253
+ <h3 id="git-remote-add">git remote add</h3>
175
254
 
176
255
  <pre><code>$ git remote add rtomayko
177
256
  &gt; git remote add rtomayko git://github.com/rtomayko/CURRENT_REPO.git
@@ -183,7 +262,7 @@ $ git remote add origin
183
262
  &gt; git remote add origin git://github.com/YOUR_USER/CURRENT_REPO.git
184
263
  </code></pre>
185
264
 
186
- <h3>git fetch</h3>
265
+ <h3 id="git-fetch">git fetch</h3>
187
266
 
188
267
  <pre><code>$ git fetch mislav
189
268
  &gt; git remote add mislav git://github.com/mislav/REPO.git
@@ -195,7 +274,7 @@ $ git fetch mislav,xoebus
195
274
  &gt; git fetch --multiple mislav xoebus
196
275
  </code></pre>
197
276
 
198
- <h3>git cherry-pick</h3>
277
+ <h3 id="git-cherry-pick">git cherry-pick</h3>
199
278
 
200
279
  <pre><code>$ git cherry-pick http://github.com/mislav/REPO/commit/SHA
201
280
  &gt; git remote add -f mislav git://github.com/mislav/REPO.git
@@ -210,21 +289,21 @@ $ git cherry-pick mislav@SHA
210
289
  &gt; git cherry-pick SHA
211
290
  </code></pre>
212
291
 
213
- <h3>git fork</h3>
292
+ <h3 id="git-fork">git fork</h3>
214
293
 
215
294
  <pre><code>$ git fork
216
295
  ... hardcore forking action ...
217
296
  &gt; git remote add YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
218
297
  </code></pre>
219
298
 
220
- <h3>git init</h3>
299
+ <h3 id="git-init">git init</h3>
221
300
 
222
301
  <pre><code>$ git init -g
223
302
  &gt; git init
224
303
  &gt; git remote add origin git@github.com:YOUR_USER/REPO.git
225
304
  </code></pre>
226
305
 
227
- <h3>git push</h3>
306
+ <h3 id="git-push">git push</h3>
228
307
 
229
308
  <pre><code>$ git push origin,staging,qa bert_timeout
230
309
  &gt; git push origin bert_timeout
@@ -232,7 +311,7 @@ $ git cherry-pick mislav@SHA
232
311
  &gt; git push qa bert_timeout
233
312
  </code></pre>
234
313
 
235
- <h3>git browse</h3>
314
+ <h3 id="git-browse">git browse</h3>
236
315
 
237
316
  <pre><code>$ git browse
238
317
  &gt; open http://github.com/CURRENT_REPO
@@ -256,7 +335,7 @@ $ git browse -p resque
256
335
  &gt; open https://github.com/YOUR_USER/resque
257
336
  </code></pre>
258
337
 
259
- <h3>git compare</h3>
338
+ <h3 id="git-compare">git compare</h3>
260
339
 
261
340
  <pre><code>$ git compare refactor
262
341
  &gt; open http://github.com/CURRENT_REPO/compare/refactor
@@ -271,7 +350,7 @@ $ git compare other-user patch
271
350
  &gt; open http://github.com/other-user/REPO/compare/patch
272
351
  </code></pre>
273
352
 
274
- <h3>git help</h3>
353
+ <h3 id="git-help">git help</h3>
275
354
 
276
355
  <pre><code>$ git help
277
356
  &gt; (improved git help)
@@ -279,27 +358,27 @@ $ git help hub
279
358
  &gt; (hub man page)
280
359
  </code></pre>
281
360
 
282
- <h2>BUGS</h2>
361
+ <h2 id="BUGS">BUGS</h2>
283
362
 
284
- <p><a href="http://github.com/defunkt/hub/issues">http://github.com/defunkt/hub/issues</a></p>
363
+ <p><a href="http://github.com/defunkt/hub/issues" data-bare-link="true">http://github.com/defunkt/hub/issues</a></p>
285
364
 
286
- <h2>AUTHOR</h2>
365
+ <h2 id="AUTHOR">AUTHOR</h2>
287
366
 
288
367
  <p>Chris Wanstrath :: chris@ozmm.org :: @defunkt</p>
289
368
 
290
- <h2>SEE ALSO</h2>
369
+ <h2 id="SEE-ALSO">SEE ALSO</h2>
291
370
 
292
371
  <p>git(1), git-clone(1), git-remote(1), git-init(1),
293
- <a href="http://github.com">http://github.com</a>,
294
- <a href="http://github.com/defunkt/hub">http://github.com/defunkt/hub</a></p>
372
+ <a href="http://github.com" data-bare-link="true">http://github.com</a>,
373
+ <a href="http://github.com/defunkt/hub" data-bare-link="true">http://github.com/defunkt/hub</a></p>
295
374
 
296
375
 
297
- <ol class='foot man'>
298
- <li class='tl'>DEFUNKT</li>
299
- <li class='tc'>April 2010</li>
300
- <li class='tr'>hub(1)</li>
301
- </ol>
376
+ <ol class='man foot'>
377
+ <li class='tl'>DEFUNKT</li>
378
+ <li class='tc'>June 2010</li>
379
+ <li class='tr'>hub(1)</li>
380
+ </ol>
302
381
 
303
- </div>
382
+ </div>
304
383
  </body>
305
384
  </html>
@@ -7,8 +7,10 @@ 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
11
  `git clone` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>
11
12
  `git remote add` [`-p`] <OPTIONS> <USER>[/<REPOSITORY>]
13
+ `git remote set-url` [`-p`] <OPTIONS> <REMOTE-NAME> <USER>[/<REPOSITORY>]
12
14
  `git fetch` <USER-1>,[<USER-2>,...]
13
15
  `git cherry-pick` <GITHUB-REF>
14
16
  `git push` <REMOTE-1>,<REMOTE-2>,...,<REMOTE-N> <REF>
@@ -33,6 +35,14 @@ alias command displays information on configuring your environment:
33
35
  "git@github.com:<USER>/<REPOSITORY>.git"; <USER> is your GitHub username and
34
36
  <REPOSITORY> is the current working directory's basename.
35
37
 
38
+ * `git create` [`-p`] [`-d <DESCRIPTION>`] [`-h <HOMEPAGE>`]:
39
+ Create a new public github repository from the current git
40
+ repository and add remote `origin` at
41
+ "git@github.com:<USER>/<REPOSITORY>.git"; <USER> is your GitHub
42
+ username and <REPOSITORY> is the current working directory's
43
+ basename. With `-p`, create a private repository. `-d` and `-h`
44
+ set the repository's description and homepage, respectively.
45
+
36
46
  * `git clone` [`-p`] <OPTIONS> [<USER>`/`]<REPOSITORY> <DIRECTORY>:
37
47
  Clone repository "git://github.com/<USER>/<REPOSITORY>.git" into
38
48
  <DIRECTORY> as with git-clone(1). When <USER>/ is omitted, assumes
@@ -46,6 +56,10 @@ alias command displays information on configuring your environment:
46
56
  "git@github.com:<USER>/<REPOSITORY>.git". If <USER> is "origin"
47
57
  then uses your GitHub login.
48
58
 
59
+ * `git remote set-url` [`-p`] <OPTIONS> <REMOTE-NAME> <USER>[/<REPOSITORY>]
60
+ Sets the url of remote <REMOTE-NAME> using the same rules as
61
+ `git remote add`.
62
+
49
63
  * `git fetch` <USER-1>,[<USER-2>,...]:
50
64
  Adds missing remote(s) with `git remote add` prior to fetching. New
51
65
  remotes are only added if they correspond to valid forks on GitHub.
@@ -171,6 +185,12 @@ cloning:
171
185
  > git init
172
186
  > git remote add origin git@github.com:YOUR_USER/REPO.git
173
187
 
188
+ ### git create
189
+
190
+ $ git create
191
+ ... hardcore creating action ...
192
+ > git remote add origin git@github.com:YOUR_USER/CURRENT_REPO.git
193
+
174
194
  ### git push
175
195
 
176
196
  $ git push origin,staging,qa bert_timeout
@@ -30,8 +30,10 @@ class HubTest < Test::Unit::TestCase
30
30
  'config branch.master.merge' => 'refs/heads/master',
31
31
  'config branch.feature.remote' => 'mislav',
32
32
  'config branch.feature.merge' => 'refs/heads/experimental',
33
- 'config --bool hub.http-clone' => 'false'
33
+ 'config --bool hub.http-clone' => 'false',
34
+ 'config core.repositoryformatversion' => '0'
34
35
  )
36
+ super
35
37
  end
36
38
 
37
39
  def test_private_clone
@@ -380,6 +382,79 @@ class HubTest < Test::Unit::TestCase
380
382
  assert_equal "git push staging cool-feature; git push qa cool-feature", h.after
381
383
  end
382
384
 
385
+ def test_create
386
+ Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
387
+ 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
+ expected = "remote add -f origin git@github.com:tpw/hub.git\n"
393
+ expected << "created repository: tpw/hub\n"
394
+ assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
395
+ end
396
+
397
+ def test_create_private_repository
398
+ Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
399
+ 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
+ }
404
+ expected = "remote add -f origin git@github.com:tpw/hub.git\n"
405
+ expected << "created repository: tpw/hub\n"
406
+ assert_equal expected, hub("create -p") { ENV['GIT'] = 'echo' }
407
+ end
408
+
409
+ def test_create_with_description_and_homepage
410
+ Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
411
+ 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
+ }
416
+ expected = "remote add -f origin git@github.com:tpw/hub.git\n"
417
+ expected << "created repository: tpw/hub\n"
418
+ assert_equal expected, hub("create -d description -h http://github.com/tpw/hub.git") { ENV['GIT'] = 'echo' }
419
+ end
420
+
421
+ def test_create_with_existing_repository
422
+ Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
423
+ stub_existing_fork('tpw')
424
+
425
+ expected = "tpw/hub already exists on GitHub\n"
426
+ expected << "remote add -f origin git@github.com:tpw/hub.git\n"
427
+ expected << "set remote origin: tpw/hub\n"
428
+ assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
429
+ end
430
+
431
+ def test_create_no_user
432
+ Hub::Context::GIT_CONFIG['remote'] = nil # new repositories don't have remotes
433
+ out = hub("create") do
434
+ stub_github_token(nil)
435
+ end
436
+ assert_equal "** No GitHub token set. See http://github.com/guides/local-github-config\n", out
437
+ end
438
+
439
+ def test_create_outside_git_repo
440
+ @git = Hub::Context::GIT_CONFIG.replace(Hash.new { |h, k|
441
+ nil
442
+ })
443
+
444
+ assert_equal "'create' must be run from inside a git repository\n", hub("create")
445
+ end
446
+
447
+ def test_create_origin_already_exists
448
+ 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
+ }
453
+
454
+ expected = "remote -v\ncreated repository: tpw/hub\n"
455
+ assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
456
+ end
457
+
383
458
  def test_fork
384
459
  stub_nonexisting_fork('tpw')
385
460
  stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub").with { |req|
@@ -599,6 +674,10 @@ config
599
674
  @git['config github.user'] = name
600
675
  end
601
676
 
677
+ def stub_github_token(token)
678
+ @git['config github.token'] = token
679
+ end
680
+
602
681
  def stub_repo_url(value)
603
682
  @git['config remote.origin.url'] = value
604
683
  Hub::Context::REMOTES.clear
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 3
8
- - 2
9
- version: 1.3.2
7
+ - 4
8
+ - 0
9
+ version: 1.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Chris Wanstrath
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-07-24 00:00:00 -07:00
17
+ date: 2010-08-08 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies: []
20
20