git-hub 1.3.2 → 1.4.0

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