git-hub 1.0.3 → 1.1.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/HISTORY.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.1.0 (2010-04-07)
2
+
3
+ * `hub fork` command - Thanks Mislav!
4
+
1
5
  ## 1.0.3 (2010-03-10)
2
6
 
3
7
  * Bugfix: `hub remote` for repos with -, /, etc
data/README.md CHANGED
@@ -125,6 +125,16 @@ superpowers:
125
125
  $ git remote add origin
126
126
  > git remote add origin git://github.com/YOUR_USER/CURRENT_REPO.git
127
127
 
128
+ ### git fork
129
+
130
+ $ git fork
131
+ ... hardcore forking action ...
132
+ > git remote add -f YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
133
+
134
+ Forks the original repo on GitHub and adds the new remote under your
135
+ username. It requires your GitHub token to be present; see "GitHub
136
+ login" below for details.
137
+
128
138
  ### git init
129
139
 
130
140
  $ git init -g
@@ -177,7 +187,8 @@ If you see nothing, you need to set the config setting:
177
187
 
178
188
  $ git config --global github.user YOUR_USER
179
189
 
180
- See <http://github.com/guides/local-github-config> for more information.
190
+ For commands that require write access to GitHub (such as `fork`), you'll want to
191
+ setup "github.token" as well. See [local GitHub config guide][2] for more information.
181
192
 
182
193
 
183
194
  Configuration
@@ -243,3 +254,4 @@ Chris Wanstrath :: chris@ozmm.org :: @defunkt
243
254
  [0]: http://help.github.com/forking/
244
255
  [1]: http://github.com/defunkt/hub/issues
245
256
  [speed]: http://gist.github.com/284823
257
+ [2]: http://github.com/guides/local-github-config
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ task :default => :test
4
4
 
5
5
  Rake::TestTask.new do |t|
6
6
  t.libs << 'lib'
7
+ t.ruby_opts << '-rubygems'
7
8
  t.pattern = 'test/**/*_test.rb'
8
9
  t.verbose = false
9
10
  end
data/lib/hub/commands.rb CHANGED
@@ -33,11 +33,14 @@ module Hub
33
33
 
34
34
  # Templates and useful information.
35
35
  USER = `git config --global github.user`.chomp
36
+ TOKEN = `git config --global github.token`.chomp
36
37
  ORIGIN = `git config remote.origin.url`.chomp
37
38
  HTTP_CLONE = `git config --global hub.http-clone`.chomp == 'yes'
38
39
  PUBLIC = (HTTP_CLONE ? 'http' : 'git') + '://github.com/%s/%s.git'
39
40
  PRIVATE = 'git@github.com:%s/%s.git'
40
41
  LGHCONF = "http://github.com/guides/local-github-config"
42
+ API_REPO = 'http://github.com/api/v2/yaml/repos/show/%s/%s'
43
+ API_FORK = 'http://github.com/api/v2/yaml/repos/fork/%s/%s'
41
44
 
42
45
  # Set the repo name based on the current origin or, as a fallback,
43
46
  # the cwd.
@@ -112,7 +115,7 @@ module Hub
112
115
 
113
116
  ssh = args.delete('-p')
114
117
  url = ssh ? PRIVATE : PUBLIC
115
-
118
+
116
119
  # user/repo
117
120
  args.last =~ /\b(.+?)(?:\/(.+))?$/
118
121
  user, repo = $1, $2 || REPO
@@ -147,6 +150,30 @@ module Hub
147
150
  end
148
151
  end
149
152
 
153
+ # $ hub fork
154
+ # ... hardcore forking action ...
155
+ # > git remote add -f YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
156
+ def fork(args)
157
+ require 'net/http'
158
+
159
+ # can't do anything without token and original owner name
160
+ if github_user && github_token && !OWNER.empty?
161
+ if own_repo_exists?
162
+ puts "#{github_user}/#{REPO} already exists on GitHub"
163
+ else
164
+ fork_repo
165
+ end
166
+
167
+ if args.include?('--no-remote')
168
+ exit
169
+ else
170
+ url = PRIVATE % [ github_user, REPO ]
171
+ args.replace %W"remote add -f #{github_user} #{url}"
172
+ args.after { puts "new remote: #{github_user}" }
173
+ end
174
+ end
175
+ end
176
+
150
177
  # $ hub push origin,staging cool-feature
151
178
  # > git push origin cool-feature
152
179
  # > git push staging cool-feature
@@ -350,6 +377,14 @@ help
350
377
  end
351
378
  end
352
379
 
380
+ def github_token
381
+ if TOKEN.empty?
382
+ abort "** No GitHub token set. See #{LGHCONF}"
383
+ else
384
+ TOKEN
385
+ end
386
+ end
387
+
353
388
  # Returns the terminal-formatted manpage, ready to be printed to
354
389
  # the screen.
355
390
  def hub_manpage
@@ -433,5 +468,22 @@ help
433
468
  write.close
434
469
  end
435
470
  end
471
+
472
+ # Determines whether the current user (you) has a fork of the
473
+ # current repo on GitHub.
474
+ #
475
+ # Returns a Boolean.
476
+ def own_repo_exists?
477
+ url = API_REPO % [USER, REPO]
478
+ Net::HTTPSuccess === Net::HTTP.get_response(URI(url))
479
+ end
480
+
481
+ # Forks the current repo using the GitHub API.
482
+ #
483
+ # Returns nothing.
484
+ def fork_repo
485
+ url = API_FORK % [OWNER, REPO]
486
+ Net::HTTP.post_form(URI(url), 'login' => USER, 'token' => TOKEN)
487
+ end
436
488
  end
437
489
  end
data/lib/hub/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Hub
2
- Version = '1.0.3'
2
+ Version = '1.1.0'
3
3
  end
data/man/hub.1 CHANGED
@@ -1,30 +1,31 @@
1
1
  .\" generated with Ron/v0.3
2
2
  .\" http://github.com/rtomayko/ron/
3
3
  .
4
- .TH "HUB" "1" "March 2010" "DEFUNKT" "Git Manual"
4
+ .TH "HUB" "1" "April 2010" "DEFUNKT" "Git Manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBhub\fR \-\- git + hub = github
8
8
  .
9
9
  .SH "SYNOPSIS"
10
- \fBhub\fR \fICOMMAND\fR \fIOPTIONS\fR
10
+ \fBhub\fR \fICOMMAND\fR \fIOPTIONS\fR \fBhub alias\fR [\fB-s\fR] \fISHELL\fR
11
11
  .
12
- .br
13
- \fBhub alias\fR [\fB-s\fR] \fISHELL\fR
12
+ .P
13
+ \fBgit init -g\fR \fIOPTIONS\fR
14
14
  .
15
15
  .br
16
+ \fBgit clone\fR [\fB-p\fR] \fIOPTIONS\fR [\fIUSER\fR/]\fIREPOSITORY\fR \fIDIRECTORY\fR
16
17
  .
17
- .P
18
- \fBgit init -g\fR \fIOPTIONS\fR
18
+ .br
19
+ \fBgit remote add\fR [\fB-p\fR] \fIOPTIONS\fR \fIUSER\fR[/\fIREPOSITORY\fR]
19
20
  .
20
21
  .br
21
- \fBgit clone\fR [\fB-p\fR] \fIOPTIONS\fR [\fIUSER\fR/]\fIREPOSITORY\fR \fIDIRECTORY\fR
22
+ \fBgit push\fR \fIREMOTE\-1\fR,\fIREMOTE\-2\fR,...,\fIREMOTE\-N\fR \fIREF\fR
22
23
  .
23
24
  .br
24
- \fBgit remote add\fR [\fB-p\fR] \fIOPTIONS\fR \fIUSER\fR[/\fIREPOSITORY\fR]
25
+ \fBgit fork\fR
25
26
  .
26
27
  .br
27
- \fBgit browse\fR [\fB-p\fR] [\fIUSER\fR/]\fIREPOSITORY\fR
28
+ \fBgit browse\fR [\fB-p\fR] [\fIUSER\fR/]\fIREPOSITORY\fR
28
29
  .
29
30
  .br
30
31
  \fBgit submodule add\fR [\fB-p\fR] \fIOPTIONS\fR [\fIUSER\fR/]\fIREPOSITORY\fR \fIDIRECTORY\fR
@@ -34,53 +35,93 @@
34
35
  alias command displays information on configuring your environment:
35
36
  .
36
37
  .TP
37
- \fBhub alias\fR [\fB-s\fR] \fISHELL\fR
38
- Writes shell aliasing code for \fISHELL\fR (\fBbash\fR, \fBsh\fR, \fBzsh\fR, \fBcsh\fR) to standard output. With the \fB-s\fR option, the output of
39
- this command can be evaluated directly within the shell: \fBeval $(hub alias -s bash)\fR
38
+ \fBhub alias\fR [\fB-s\fR] \fISHELL\fR:
40
39
  .
41
- .P
42
- After configuring the alias, the following commands have superpowers:
40
+ .br
41
+ Writes shell aliasing code for \fISHELL\fR (\fBbash\fR, \fBsh\fR, \fBzsh\fR, \fBcsh\fR) to standard output. With the \fB-s\fR option, the output of
42
+ this command can be evaluated directly within the shell
43
+ \fBeval $(hub alias -s bash)\fR
43
44
  .
44
45
  .TP
45
- \fBgit init\fR \fB-g\fR \fIOPTIONS\fR
46
- Create a git repository as with git\-init(1) and add remote \fBorigin\fR at
47
- "git@github.com:\fIUSER\fR/\fIREPOSITORY\fR.git"; \fIUSER\fR is your GitHub username and \fIREPOSITORY\fR is the current working directory's basename.
46
+ \fBgit init\fR \fB-g\fR \fIOPTIONS\fR:
47
+ .
48
+ .br
49
+ Create a git repository as with git\-init(1) and add remote \fBorigin\fR at
50
+ "git@github.com:\fIUSER\fR/\fIREPOSITORY\fR.git"; \fIUSER\fR is your GitHub username and
51
+ \fIREPOSITORY\fR is the current working directory's basename.
52
+
48
53
  .
49
54
  .TP
50
- \fBgit clone\fR [\fB-p\fR] \fIOPTIONS\fR [\fIUSER\fR\fB/\fR]\fIREPOSITORY\fR \fIDIRECTORY\fR
55
+ \fBgit clone\fR [\fB-p\fR] \fIOPTIONS\fR [\fIUSER\fR\fB/\fR]\fIREPOSITORY\fR \fIDIRECTORY\fR:
56
+ .
57
+ .br
51
58
  Clone repository "git://github.com/\fIUSER\fR/\fIREPOSITORY\fR.git" into \fIDIRECTORY\fR as with git\-clone(1). When \fIUSER\fR/ is omitted, assumes
52
59
  your GitHub login. With \fB-p\fR, use private remote
53
60
  "git@github.com:\fIUSER\fR/\fIREPOSITORY\fR.git".
61
+
54
62
  .
55
63
  .TP
56
- \fBgit remote add\fR [\fB-p\fR] \fIOPTIONS\fR \fIUSER\fR[\fB/\fR\fIREPOSITORY\fR]
64
+ \fBgit remote add\fR [\fB-p\fR] \fIOPTIONS\fR \fIUSER\fR[\fB/\fR\fIREPOSITORY\fR]:
65
+ .
66
+ .br
57
67
  Add remote "git://github.com/\fIUSER\fR/\fIREPOSITORY\fR.git" as with
58
68
  git\-remote(1). When /\fIREPOSITORY\fR is omitted, the basename of the
59
69
  current working directory is used. With \fB-p\fR, use private remote
60
70
  "git@github.com:\fIUSER\fR/\fIREPOSITORY\fR.git". If \fIUSER\fR is "origin"
61
71
  then uses your GitHub login.
72
+
62
73
  .
63
74
  .TP
64
- \fBgit push\fR \fIREMOTE\-1\fR,\fIREMOTE\-2\fR,...,\fIREMOTE\-N\fR \fIREF\fR
75
+ \fBgit push\fR \fIREMOTE\-1\fR,\fIREMOTE\-2\fR,...,\fIREMOTE\-N\fR \fIREF\fR:
76
+ .
77
+ .br
65
78
  Push \fIREF\fR to each of \fIREMOTE\-1\fR through \fIREMOTE\-N\fR by executing
66
79
  multiple \fBgit push\fR commands.
80
+
67
81
  .
68
82
  .TP
69
- \fBgit browse\fR [\fB-p\fR] [[\fIUSER\fR\fB/\fR]\fIREPOSITORY\fR]
83
+ \fBgit fork\fR:
84
+ .
85
+ .br
86
+ Forks the original repo on GitHub and adds the new remote under your
87
+ username. It requires your GitHub login and token to be present. See
88
+ CONFIGURATION below.
89
+
90
+ .
91
+ .TP
92
+ \fBgit browse\fR [\fB-p\fR] [[\fIUSER\fR\fB/\fR]\fIREPOSITORY\fR]:
93
+ .
94
+ .br
70
95
  Open repository's GitHub page in the system's default web browser
71
96
  using \fBopen(1)\fR or the \fBBROWSER\fR env variable. Use \fB-p\fR to open a
72
97
  page with https. If the repository isn't specified, \fBbrowse\fR opens
73
98
  the page of the repository found in the current directory.
99
+
74
100
  .
75
101
  .TP
76
- \fBgit submodule add\fR [\fB-p\fR] \fIOPTIONS\fR [\fIUSER\fR/]\fIREPOSITORY\fR \fIDIRECTORY\fR
102
+ \fBgit submodule add\fR [\fB-p\fR] \fIOPTIONS\fR [\fIUSER\fR/]\fIREPOSITORY\fR \fIDIRECTORY\fR:
103
+ .
104
+ .br
77
105
  Submodule repository "git://github.com/\fIUSER\fR/\fIREPOSITORY\fR.git" into \fIDIRECTORY\fR as with git\-submodule(1). When \fIUSER\fR/ is omitted, assumes
78
106
  your GitHub login. With \fB-p\fR, use private remote
79
107
  "git@github.com:\fIUSER\fR/\fIREPOSITORY\fR.git".
108
+
109
+ .
110
+ .TP
111
+ \fBgit fork\fR [\fB--no-remote\fR]:
112
+ .
113
+ .br
114
+ Forks the original project (as specified in "origin" remote) on GitHub
115
+ and adds a new remote named \fIUSER\fR referencing the newly created repo.
116
+ Requires \fBgithub.token\fR to be set (see CONFIGURATION).
117
+
80
118
  .
81
119
  .TP
82
- \fBgit help\fR
120
+ \fBgit help\fR:
121
+ .
122
+ .br
83
123
  Display enhanced git\-help(1).
124
+
84
125
  .
85
126
  .SH "CONFIGURATION"
86
127
  Use git\-config(1) to display the currently configured GitHub username:
@@ -96,13 +137,14 @@ Use git\-config(1) to display the currently configured GitHub username:
96
137
  .IP "" 0
97
138
  .
98
139
  .P
99
- Or, set the GitHub username with:
140
+ Or, set the GitHub username and token with:
100
141
  .
101
142
  .IP "" 4
102
143
  .
103
144
  .nf
104
145
 
105
- \fB$ git config --global github.user <username> \fR
146
+ \fB$ git config --global github.user <username>
147
+ $ git config --global github.token <token> \fR
106
148
  .
107
149
  .fi
108
150
  .
@@ -161,6 +203,16 @@ $ git remote add origin
161
203
  .
162
204
  .fi
163
205
  .
206
+ .SS "git fork"
207
+ .
208
+ .nf
209
+
210
+ \fB$ git fork
211
+ ... hardcore forking action ...
212
+ > git remote add YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git \fR
213
+ .
214
+ .fi
215
+ .
164
216
  .SS "git init"
165
217
  .
166
218
  .nf
data/man/hub.1.html CHANGED
@@ -66,14 +66,15 @@
66
66
  <p><code>hub</code> -- git + hub = github</p>
67
67
  <h2>SYNOPSIS</h2>
68
68
 
69
- <p><code>hub</code> <var>COMMAND</var> <var>OPTIONS</var> <br>
70
- <code>hub alias</code> [<code>-s</code>] <var>SHELL</var> <br>
71
- </p>
72
-
73
- <p><code>git init -g</code> <var>OPTIONS</var> <br>
74
- <code>git clone</code> [<code>-p</code>] <var>OPTIONS</var> [<var>USER</var>/]<var>REPOSITORY</var> <var>DIRECTORY</var> <br>
75
- <code>git remote add</code> [<code>-p</code>] <var>OPTIONS</var> <var>USER</var>[/<var>REPOSITORY</var>] <br>
76
- <code>git browse</code> [<code>-p</code>] [<var>USER</var>/]<var>REPOSITORY</var> <br>
69
+ <p><code>hub</code> <var>COMMAND</var> <var>OPTIONS</var>
70
+ <code>hub alias</code> [<code>-s</code>] <var>SHELL</var></p>
71
+
72
+ <p><code>git init -g</code> <var>OPTIONS</var><br>
73
+ <code>git clone</code> [<code>-p</code>] <var>OPTIONS</var> [<var>USER</var>/]<var>REPOSITORY</var> <var>DIRECTORY</var><br>
74
+ <code>git remote add</code> [<code>-p</code>] <var>OPTIONS</var> <var>USER</var>[/<var>REPOSITORY</var>]<br>
75
+ <code>git push</code> <var>REMOTE-1</var>,<var>REMOTE-2</var>,...,<var>REMOTE-N</var> <var>REF</var><br>
76
+ <code>git fork</code><br>
77
+ <code>git browse</code> [<code>-p</code>] [<var>USER</var>/]<var>REPOSITORY</var><br>
77
78
  <code>git submodule add</code> [<code>-p</code>] <var>OPTIONS</var> [<var>USER</var>/]<var>REPOSITORY</var> <var>DIRECTORY</var></p>
78
79
 
79
80
  <h2>DESCRIPTION</h2>
@@ -83,59 +84,67 @@ alias command displays information on configuring your environment:</p>
83
84
 
84
85
  <dl>
85
86
  <dt>
86
- <code>hub alias</code> [<code>-s</code>] <var>SHELL</var>
87
- </dt>
88
- <dd>Writes shell aliasing code for <var>SHELL</var> (<code>bash</code>, <code>sh</code>, <code>zsh</code>,
87
+ <code>hub alias</code> [<code>-s</code>] <var>SHELL</var>:<br>
88
+ Writes shell aliasing code for <var>SHELL</var> (<code>bash</code>, <code>sh</code>, <code>zsh</code>,
89
89
  <code>csh</code>) to standard output. With the <code>-s</code> option, the output of
90
- this command can be evaluated directly within the shell:
91
- <code>eval $(hub alias -s bash)</code>
92
- </dd>
93
- </dl>
94
-
95
-
96
- <p>After configuring the alias, the following commands have superpowers:</p>
97
-
98
- <dl>
90
+ this command can be evaluated directly within the shell</dt>
91
+ <dd><p><code>eval $(hub alias -s bash)</code></p></dd>
99
92
  <dt>
100
- <code>git init</code> <code>-g</code> <var>OPTIONS</var>
101
- </dt>
102
- <dd><p>Create a git repository as with git-init(1) and add remote <code>origin</code> at
103
- "git@github.com:<var>USER</var>/<var>REPOSITORY</var>.git"; <var>USER</var> is your GitHub username and
104
- <var>REPOSITORY</var> is the current working directory's basename.</p></dd>
93
+ <code>git init</code> <code>-g</code> <var>OPTIONS</var>:<br>
94
+ Create a git repository as with git-init(1) and add remote <code>origin</code> at
95
+ "git@github.com:<var>USER</var>/<var>REPOSITORY</var>.git"; <var>USER</var> is your GitHub username and
96
+ <var>REPOSITORY</var> is the current working directory's basename.</dt>
97
+ <dd><p></p></dd>
105
98
  <dt>
106
- <code>git clone</code> [<code>-p</code>] <var>OPTIONS</var> [<var>USER</var><code>/</code>]<var>REPOSITORY</var> <var>DIRECTORY</var>
107
- </dt>
108
- <dd><p>Clone repository "git://github.com/<var>USER</var>/<var>REPOSITORY</var>.git" into
99
+ <code>git clone</code> [<code>-p</code>] <var>OPTIONS</var> [<var>USER</var><code>/</code>]<var>REPOSITORY</var> <var>DIRECTORY</var>:<br>
100
+ Clone repository "git://github.com/<var>USER</var>/<var>REPOSITORY</var>.git" into
109
101
  <var>DIRECTORY</var> as with git-clone(1). When <var>USER</var>/ is omitted, assumes
110
102
  your GitHub login. With <code>-p</code>, use private remote
111
- "git@github.com:<var>USER</var>/<var>REPOSITORY</var>.git".</p></dd>
103
+ "git@github.com:<var>USER</var>/<var>REPOSITORY</var>.git".</dt>
104
+ <dd><p></p></dd>
112
105
  <dt>
113
- <code>git remote add</code> [<code>-p</code>] <var>OPTIONS</var> <var>USER</var>[<code>/</code><var>REPOSITORY</var>]</dt>
114
- <dd><p>Add remote "git://github.com/<var>USER</var>/<var>REPOSITORY</var>.git" as with
106
+ <code>git remote add</code> [<code>-p</code>] <var>OPTIONS</var> <var>USER</var>[<code>/</code><var>REPOSITORY</var>]:<br>
107
+ Add remote "git://github.com/<var>USER</var>/<var>REPOSITORY</var>.git" as with
115
108
  git-remote(1). When /<var>REPOSITORY</var> is omitted, the basename of the
116
109
  current working directory is used. With <code>-p</code>, use private remote
117
110
  "git@github.com:<var>USER</var>/<var>REPOSITORY</var>.git". If <var>USER</var> is "origin"
118
- then uses your GitHub login.</p></dd>
111
+ then uses your GitHub login.</dt>
112
+ <dd><p></p></dd>
113
+ <dt>
114
+ <code>git push</code> <var>REMOTE-1</var>,<var>REMOTE-2</var>,...,<var>REMOTE-N</var> <var>REF</var>:<br>
115
+ Push <var>REF</var> to each of <var>REMOTE-1</var> through <var>REMOTE-N</var> by executing
116
+ multiple <code>git push</code> commands.</dt>
117
+ <dd><p></p></dd>
119
118
  <dt>
120
- <code>git push</code> <var>REMOTE-1</var>,<var>REMOTE-2</var>,...,<var>REMOTE-N</var> <var>REF</var>
121
- </dt>
122
- <dd><p>Push <var>REF</var> to each of <var>REMOTE-1</var> through <var>REMOTE-N</var> by executing
123
- multiple <code>git push</code> commands.</p></dd>
119
+ <code>git fork</code>:<br>
120
+ Forks the original repo on GitHub and adds the new remote under your
121
+ username. It requires your GitHub login and token to be present. See
122
+ CONFIGURATION below.</dt>
123
+ <dd><p></p></dd>
124
124
  <dt>
125
- <code>git browse</code> [<code>-p</code>] [[<var>USER</var><code>/</code>]<var>REPOSITORY</var>]</dt>
126
- <dd><p>Open repository's GitHub page in the system's default web browser
125
+ <code>git browse</code> [<code>-p</code>] [[<var>USER</var><code>/</code>]<var>REPOSITORY</var>]:<br>
126
+ Open repository's GitHub page in the system's default web browser
127
127
  using <code>open(1)</code> or the <code>BROWSER</code> env variable. Use <code>-p</code> to open a
128
128
  page with https. If the repository isn't specified, <code>browse</code> opens
129
- the page of the repository found in the current directory.</p></dd>
129
+ the page of the repository found in the current directory.</dt>
130
+ <dd><p></p></dd>
130
131
  <dt>
131
- <code>git submodule add</code> [<code>-p</code>] <var>OPTIONS</var> [<var>USER</var>/]<var>REPOSITORY</var> <var>DIRECTORY</var>
132
- </dt>
133
- <dd><p>Submodule repository "git://github.com/<var>USER</var>/<var>REPOSITORY</var>.git" into
132
+ <code>git submodule add</code> [<code>-p</code>] <var>OPTIONS</var> [<var>USER</var>/]<var>REPOSITORY</var> <var>DIRECTORY</var>:<br>
133
+ Submodule repository "git://github.com/<var>USER</var>/<var>REPOSITORY</var>.git" into
134
134
  <var>DIRECTORY</var> as with git-submodule(1). When <var>USER</var>/ is omitted, assumes
135
135
  your GitHub login. With <code>-p</code>, use private remote
136
- "git@github.com:<var>USER</var>/<var>REPOSITORY</var>.git".</p></dd>
137
- <dt><code>git help</code></dt>
138
- <dd><p>Display enhanced git-help(1).</p></dd>
136
+ "git@github.com:<var>USER</var>/<var>REPOSITORY</var>.git".</dt>
137
+ <dd><p></p></dd>
138
+ <dt>
139
+ <code>git fork</code> [<code>--no-remote</code>]:<br>
140
+ Forks the original project (as specified in "origin" remote) on GitHub
141
+ and adds a new remote named <var>USER</var> referencing the newly created repo.
142
+ Requires <code>github.token</code> to be set (see CONFIGURATION).</dt>
143
+ <dd><p></p></dd>
144
+ <dt>
145
+ <code>git help</code>:<br>
146
+ Display enhanced git-help(1).</dt>
147
+ <dd><p></p></dd>
139
148
  </dl>
140
149
 
141
150
 
@@ -146,9 +155,10 @@ your GitHub login. With <code>-p</code>, use private remote
146
155
  <pre><code>$ git config --global github.user
147
156
  </code></pre>
148
157
 
149
- <p>Or, set the GitHub username with:</p>
158
+ <p>Or, set the GitHub username and token with:</p>
150
159
 
151
160
  <pre><code>$ git config --global github.user &lt;username&gt;
161
+ $ git config --global github.token &lt;token&gt;
152
162
  </code></pre>
153
163
 
154
164
  <p>See <a href="http://github.com/guides/local-github-config">http://github.com/guides/local-github-config</a> for more
@@ -189,6 +199,13 @@ $ git remote add origin
189
199
  &gt; git remote add origin git://github.com/YOUR_USER/CURRENT_REPO.git
190
200
  </code></pre>
191
201
 
202
+ <h3>git fork</h3>
203
+
204
+ <pre><code>$ git fork
205
+ ... hardcore forking action ...
206
+ &gt; git remote add YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
207
+ </code></pre>
208
+
192
209
  <h3>git init</h3>
193
210
 
194
211
  <pre><code>$ git init -g
@@ -243,7 +260,7 @@ $ git help hub
243
260
 
244
261
  <ol class='foot man'>
245
262
  <li class='tl'>DEFUNKT</li>
246
- <li class='tc'>March 2010</li>
263
+ <li class='tc'>April 2010</li>
247
264
  <li class='tr'>hub(1)</li>
248
265
  </ol>
249
266
 
data/man/hub.1.ron CHANGED
@@ -3,63 +3,73 @@ hub(1) -- git + hub = github
3
3
 
4
4
  ## SYNOPSIS
5
5
 
6
- `hub` <COMMAND> <OPTIONS>
7
- `hub alias` [`-s`] <SHELL>
6
+ `hub` <COMMAND> <OPTIONS>
7
+ `hub alias` [`-s`] <SHELL>
8
8
 
9
- `git init -g` <OPTIONS>
10
- `git clone` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>
11
- `git remote add` [`-p`] <OPTIONS> <USER>[/<REPOSITORY>]
12
- `git browse` [`-p`] [<USER>/]<REPOSITORY>
13
- `git submodule add` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>
9
+ `git init -g` <OPTIONS>
10
+ `git clone` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>
11
+ `git remote add` [`-p`] <OPTIONS> <USER>[/<REPOSITORY>]
12
+ `git push` <REMOTE-1>,<REMOTE-2>,...,<REMOTE-N> <REF>
13
+ `git fork`
14
+ `git browse` [`-p`] [<USER>/]<REPOSITORY>
15
+ `git submodule add` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>
14
16
 
15
17
  ## DESCRIPTION
16
18
 
17
19
  `hub` enhances various `git` commands with GitHub remote expansion. The
18
20
  alias command displays information on configuring your environment:
19
21
 
20
- * `hub alias` [`-s`] <SHELL>:
22
+ * `hub alias` [`-s`] <SHELL>:
21
23
  Writes shell aliasing code for <SHELL> (`bash`, `sh`, `zsh`,
22
24
  `csh`) to standard output. With the `-s` option, the output of
23
25
  this command can be evaluated directly within the shell:
24
26
  `eval $(hub alias -s bash)`
25
27
 
26
- After configuring the alias, the following commands have superpowers:
27
-
28
- * `git init` `-g` <OPTIONS>:
28
+ * `git init` `-g` <OPTIONS>:
29
29
  Create a git repository as with git-init(1) and add remote `origin` at
30
30
  "git@github.com:<USER>/<REPOSITORY>.git"; <USER> is your GitHub username and
31
31
  <REPOSITORY> is the current working directory's basename.
32
32
 
33
- * `git clone` [`-p`] <OPTIONS> [<USER>`/`]<REPOSITORY> <DIRECTORY>:
33
+ * `git clone` [`-p`] <OPTIONS> [<USER>`/`]<REPOSITORY> <DIRECTORY>:
34
34
  Clone repository "git://github.com/<USER>/<REPOSITORY>.git" into
35
35
  <DIRECTORY> as with git-clone(1). When <USER>/ is omitted, assumes
36
36
  your GitHub login. With `-p`, use private remote
37
37
  "git@github.com:<USER>/<REPOSITORY>.git".
38
38
 
39
- * `git remote add` [`-p`] <OPTIONS> <USER>[`/`<REPOSITORY>]:
39
+ * `git remote add` [`-p`] <OPTIONS> <USER>[`/`<REPOSITORY>]:
40
40
  Add remote "git://github.com/<USER>/<REPOSITORY>.git" as with
41
41
  git-remote(1). When /<REPOSITORY> is omitted, the basename of the
42
42
  current working directory is used. With `-p`, use private remote
43
43
  "git@github.com:<USER>/<REPOSITORY>.git". If <USER> is "origin"
44
44
  then uses your GitHub login.
45
45
 
46
- * `git push` <REMOTE-1>,<REMOTE-2>,...,<REMOTE-N> <REF>:
46
+ * `git push` <REMOTE-1>,<REMOTE-2>,...,<REMOTE-N> <REF>:
47
47
  Push <REF> to each of <REMOTE-1> through <REMOTE-N> by executing
48
48
  multiple `git push` commands.
49
49
 
50
- * `git browse` [`-p`] [[<USER>`/`]<REPOSITORY>]:
50
+ * `git fork`:
51
+ Forks the original repo on GitHub and adds the new remote under your
52
+ username. It requires your GitHub login and token to be present. See
53
+ CONFIGURATION below.
54
+
55
+ * `git browse` [`-p`] [[<USER>`/`]<REPOSITORY>]:
51
56
  Open repository's GitHub page in the system's default web browser
52
57
  using `open(1)` or the `BROWSER` env variable. Use `-p` to open a
53
58
  page with https. If the repository isn't specified, `browse` opens
54
59
  the page of the repository found in the current directory.
55
60
 
56
- * `git submodule add` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>:
61
+ * `git submodule add` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>:
57
62
  Submodule repository "git://github.com/<USER>/<REPOSITORY>.git" into
58
63
  <DIRECTORY> as with git-submodule(1). When <USER>/ is omitted, assumes
59
64
  your GitHub login. With `-p`, use private remote
60
65
  "git@github.com:<USER>/<REPOSITORY>.git".
61
66
 
62
- * `git help`:
67
+ * `git fork` [`--no-remote`]:
68
+ Forks the original project (as specified in "origin" remote) on GitHub
69
+ and adds a new remote named <USER> referencing the newly created repo.
70
+ Requires `github.token` to be set (see CONFIGURATION).
71
+
72
+ * `git help`:
63
73
  Display enhanced git-help(1).
64
74
 
65
75
  ## CONFIGURATION
@@ -68,9 +78,10 @@ Use git-config(1) to display the currently configured GitHub username:
68
78
 
69
79
  $ git config --global github.user
70
80
 
71
- Or, set the GitHub username with:
81
+ Or, set the GitHub username and token with:
72
82
 
73
83
  $ git config --global github.user <username>
84
+ $ git config --global github.token <token>
74
85
 
75
86
  See <http://github.com/guides/local-github-config> for more
76
87
  information.
@@ -107,6 +118,12 @@ cloning:
107
118
  $ git remote add origin
108
119
  > git remote add origin git://github.com/YOUR_USER/CURRENT_REPO.git
109
120
 
121
+ ### git fork
122
+
123
+ $ git fork
124
+ ... hardcore forking action ...
125
+ > git remote add YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
126
+
110
127
  ### git init
111
128
 
112
129
  $ git init -g
data/test/helper.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  require 'test/unit'
2
+
3
+ begin
4
+ require 'redgreen'
5
+ rescue LoadError
6
+ end
7
+
2
8
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
9
  require 'hub'
4
10
  require 'hub/standalone'
@@ -26,16 +32,22 @@ class Test::Unit::TestCase
26
32
  # If a block is given it will be run in the child process before
27
33
  # execution begins. You can use this to monkeypatch or fudge the
28
34
  # environment before running hub.
29
- def hub(args)
35
+ def hub(args, input = nil)
30
36
  parent_read, child_write = IO.pipe
37
+ child_read, parent_write = IO.pipe if input
31
38
 
32
39
  fork do
33
40
  yield if block_given?
41
+ $stdin.reopen(child_read) if input
34
42
  $stdout.reopen(child_write)
35
43
  $stderr.reopen(child_write)
36
44
  Hub(args).execute
37
45
  end
38
-
46
+
47
+ if input
48
+ parent_write.write input
49
+ parent_write.close
50
+ end
39
51
  child_write.close
40
52
  parent_read.read
41
53
  end
data/test/hub_test.rb CHANGED
@@ -1,10 +1,14 @@
1
1
  $LOAD_PATH.unshift File.dirname(__FILE__)
2
2
  require 'helper'
3
+ require 'webmock/test_unit'
3
4
 
4
5
  class HubTest < Test::Unit::TestCase
6
+ include WebMock
7
+
5
8
  def setup
6
9
  Hub::Commands::REPO.replace("hub")
7
10
  Hub::Commands::USER.replace("tpw")
11
+ Hub::Commands::TOKEN.replace("abc123")
8
12
  Hub::Commands::OWNER.replace("defunkt")
9
13
  end
10
14
 
@@ -197,6 +201,37 @@ class HubTest < Test::Unit::TestCase
197
201
  assert_equal "git push staging cool-feature; git push qa cool-feature", h.after
198
202
  end
199
203
 
204
+ def test_fork
205
+ stub_request(:get, "github.com/api/v2/yaml/repos/show/tpw/hub").
206
+ to_return(:status => 404)
207
+ stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub").with { |req|
208
+ params = Hash[*req.body.split(/[&=]/)]
209
+ params == { 'login'=>'tpw', 'token'=>'abc123' }
210
+ }
211
+
212
+ expected = "remote add -f tpw git@github.com:tpw/hub.git\n"
213
+ expected << "new remote: tpw\n"
214
+ assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
215
+ end
216
+
217
+ def test_fork_no_remote
218
+ stub_request(:get, "github.com/api/v2/yaml/repos/show/tpw/hub").
219
+ to_return(:status => 404)
220
+ stub_request(:post, "github.com/api/v2/yaml/repos/fork/defunkt/hub")
221
+
222
+ assert_equal "", hub("fork --no-remote") { ENV['GIT'] = 'echo' }
223
+ end
224
+
225
+ def test_fork_already_exists
226
+ stub_request(:get, "github.com/api/v2/yaml/repos/show/tpw/hub").
227
+ to_return(:status => 200)
228
+
229
+ expected = "tpw/hub already exists on GitHub\n"
230
+ expected << "remote add -f tpw git@github.com:tpw/hub.git\n"
231
+ expected << "new remote: tpw\n"
232
+ assert_equal expected, hub("fork") { ENV['GIT'] = 'echo' }
233
+ end
234
+
200
235
  def test_version
201
236
  out = hub('--version')
202
237
  assert_includes "git version", out
@@ -244,7 +279,8 @@ config
244
279
  end
245
280
 
246
281
  def test_hub_open_private
247
- assert_command "browse -p bmizerany/sinatra", "open https://github.com/bmizerany/sinatra"
282
+ assert_command "browse -p bmizerany/sinatra",
283
+ "open https://github.com/bmizerany/sinatra"
248
284
  end
249
285
 
250
286
  def test_hub_open_self
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-hub
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-10 00:00:00 -08:00
12
+ date: 2010-04-07 00:00:00 -07:00
13
13
  default_executable: hub
14
14
  dependencies: []
15
15