diff --git a/README.md b/README.md
index feb43bd2da7160c046a8f148d031fa1009774fb0..21af655e4e06580d3839741eca3419681a4c9793 100644
--- a/README.md
+++ b/README.md
@@ -170,7 +170,7 @@ superpowers:
### git fork
$ git fork
- ... hardcore forking action ...
+ [ repo forked on GitHub ]
> git remote add -f YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
Forks the original repo on GitHub and adds the new remote under your
@@ -180,9 +180,20 @@ login" below for details.
### git create
$ git create
- ... hardcore creating action ...
+ [ repo created on GitHub ]
> git remote add origin git@github.com:YOUR_USER/CURRENT_REPO.git
+ # with description:
+ $ git create -d 'It shall be mine, all mine!'
+
+ $ git create recipes
+ [ repo created on GitHub ]
+ > git remote add origin git@github.com:YOUR_USER/recipes.git
+
+ $ git create sinatra/recipes
+ [ repo created in GitHub organization ]
+ > git remote add origin git@github.com:sinatra/recipes.git
+
Creates a new public github repository and adds the remote `origin` at
"git@github.com:/.git"
diff --git a/lib/hub/commands.rb b/lib/hub/commands.rb
index bb1977dfb664627c82f61497669ad8a5ff74cc43..59773f77ec761b97231241f1642db002bca0f70e 100644
--- a/lib/hub/commands.rb
+++ b/lib/hub/commands.rb
@@ -296,10 +296,11 @@ module Hub
if !is_repo?
puts "'create' must be run from inside a git repository"
args.skip!
- elsif github_user && github_token
+ elsif owner = github_user and github_token
args.shift
options = {}
options[:private] = true if args.delete('-p')
+ new_repo_name = nil
until args.empty?
case arg = args.shift
@@ -308,20 +309,26 @@ module Hub
when '-h'
options[:homepage] = args.shift
else
- puts "unexpected argument: #{arg}"
- return
+ if arg =~ /^[^-]/ and new_repo_name.nil?
+ new_repo_name = arg
+ owner, new_repo_name = new_repo_name.split('/', 2) if new_repo_name.index('/')
+ else
+ abort "invalid argument: #{arg}"
+ end
end
end
+ new_repo_name ||= repo_name
+ repo_with_owner = "#{owner}/#{new_repo_name}"
- if repo_exists?(github_user)
- puts "#{github_user}/#{repo_name} already exists on GitHub"
+ if repo_exists?(owner, new_repo_name)
+ puts "#{repo_with_owner} already exists on GitHub"
action = "set remote origin"
else
action = "created repository"
- create_repo(options)
+ create_repo(repo_with_owner, options)
end
- url = github_url(:private => true)
+ url = github_url(:repo => new_repo_name, :user => owner, :private => true)
if remotes.first != 'origin'
args.replace %W"remote add -f origin #{url}"
@@ -329,7 +336,7 @@ module Hub
args.replace %W"remote -v"
end
- args.after { puts "#{action}: #{github_user}/#{repo_name}" }
+ args.after { puts "#{action}: #{repo_with_owner}" }
end
rescue HTTPExceptions
display_http_exception("creating repository", $!.response)
@@ -698,9 +705,9 @@ help
end
# Determines whether a user has a fork of the current repo on GitHub.
- def repo_exists?(user)
+ def repo_exists?(user, repo = repo_name)
load_net_http
- url = API_REPO % [user, repo_name]
+ url = API_REPO % [user, repo]
Net::HTTPSuccess === Net::HTTP.get_response(URI(url))
end
@@ -716,8 +723,8 @@ help
# Creates a new repo using the GitHub API.
#
# Returns nothing.
- def create_repo(options = {})
- params = {'name' => repo_name}
+ def create_repo(name, options = {})
+ params = {'name' => name.sub(/^#{github_user}\//, '')}
params['public'] = '0' if options[:private]
params['description'] = options[:description] if options[:description]
params['homepage'] = options[:homepage] if options[:homepage]
diff --git a/man/hub.1 b/man/hub.1
index a9bdd6aaf0858f7d04a974689bb773d042245835..7fdadfef03599bf1f69db49870505b729fabdf7e 100644
--- a/man/hub.1
+++ b/man/hub.1
@@ -16,7 +16,7 @@
\fBgit init \-g\fR \fIOPTIONS\fR
.
.br
-\fBgit create\fR [\fB\-p\fR] [\fB\-d \fR] [\fB\-h \fR]
+\fBgit create\fR [\fINAME\fR] [\fB\-p\fR] [\fB\-d\fR \fIDESCRIPTION\fR] [\fB\-h\fR \fIHOMEPAGE\fR]
.
.br
\fBgit clone\fR [\fB\-p\fR] \fIOPTIONS\fR [\fIUSER\fR/]\fIREPOSITORY\fR \fIDIRECTORY\fR
@@ -64,10 +64,10 @@
\fBgit init\fR \fB\-g\fR \fIOPTIONS\fR: Create a git repository as with git\-init(1) and add remote \fBorigin\fR at "git@github\.com:\fIUSER\fR/\fIREPOSITORY\fR\.git"; \fIUSER\fR is your GitHub username and \fIREPOSITORY\fR is the current working directory\'s basename\.
.
.IP "\(bu" 4
-\fBgit create\fR [\fB\-p\fR] [\fB\-d \fR] [\fB\-h \fR]:
+\fBgit create\fR [\fINAME\fR] [\fB\-p\fR] [\fB\-d\fR \fIDESCRIPTION\fR] [\fB\-h\fR \fIHOMEPAGE\fR]:
.
.br
-Create a new public github repository from the current git repository and add remote \fBorigin\fR at "git@github\.com:\fIUSER\fR/\fIREPOSITORY\fR\.git"; \fIUSER\fR is your GitHub username and \fIREPOSITORY\fR is the current working directory\'s basename\. With \fB\-p\fR, create a private repository\. \fB\-d\fR and \fB\-h\fR set the repository\'s description and homepage, respectively\.
+Create a new public GitHub repository from the current git repository and add remote \fBorigin\fR at "git@github\.com:\fIUSER\fR/\fIREPOSITORY\fR\.git"; \fIUSER\fR is your GitHub username and \fIREPOSITORY\fR is the current working directory name\. To explicitly name the new repository, pass in \fINAME\fR, optionally in \fIORGANIZATION\fR/\fINAME\fR form to create under an organization you\'re a member of\. With \fB\-p\fR, create a private repository, and with \fB\-d\fR and \fB\-h\fR set the repository\'s description and homepage URL, respectively\.
.
.IP "\(bu" 4
\fBgit clone\fR [\fB\-p\fR] \fIOPTIONS\fR [\fIUSER\fR\fB/\fR]\fIREPOSITORY\fR \fIDIRECTORY\fR:
@@ -260,7 +260,7 @@ $ git am \-\-ignore\-whitespace https://github\.com/davidbalbert/hub/commit/fdb9
.nf
$ git fork
-\.\.\. hardcore forking action \.\.\.
+[ repo forked on GitHub ]
> git remote add YOUR_USER git@github\.com:YOUR_USER/CURRENT_REPO\.git
.
.fi
@@ -280,8 +280,19 @@ $ git init \-g
.nf
$ git create
-\.\.\. hardcore creating action \.\.\.
+[ repo created on GitHub ]
> git remote add origin git@github\.com:YOUR_USER/CURRENT_REPO\.git
+
+# with description:
+$ git create \-d \'It shall be mine, all mine!\'
+
+$ git create recipes
+[ repo created on GitHub ]
+> git remote add origin git@github\.com:YOUR_USER/recipes\.git
+
+$ git create sinatra/recipes
+[ repo created in GitHub organization ]
+> git remote add origin git@github\.com:sinatra/recipes\.git
.
.fi
.
diff --git a/man/hub.1.html b/man/hub.1.html
index 5c7152c09d8b41c645771194c2a6ee4dc0290afb..4e84a55a9931d8ce8d23280af821990763b5cc2d 100644
--- a/man/hub.1.html
+++ b/man/hub.1.html
@@ -80,7 +80,7 @@
hub alias
[-s
] SHELL
git init -g
OPTIONS
-git create
[-p
] [-d <DESCRIPTION>
] [-h <HOMEPAGE>
]
+git create
[NAME] [-p
] [-d
DESCRIPTION] [-h
HOMEPAGE]
git clone
[-p
] OPTIONS [USER/]REPOSITORY DIRECTORY
git remote add
[-p
] OPTIONS USER[/REPOSITORY]
git remote set-url
[-p
] OPTIONS REMOTE-NAME USER[/REPOSITORY]
@@ -108,13 +108,15 @@ this command can be evaluated directly within the shell:
Create a git repository as with git-init(1) and add remote origin
at
"git@github.com:USER/REPOSITORY.git"; USER is your GitHub username and
REPOSITORY is the current working directory's basename.
-git create
[-p
] [-d <DESCRIPTION>
] [-h <HOMEPAGE>
]:
-Create a new public github repository from the current git
+
git create
[NAME] [-p
] [-d
DESCRIPTION] [-h
HOMEPAGE]:
+Create a new public GitHub repository from the current git
repository and add remote origin
at
"git@github.com:USER/REPOSITORY.git"; USER is your GitHub
-username and REPOSITORY is the current working directory's
-basename. With -p
, create a private repository. -d
and -h
-set the repository's description and homepage, respectively.
+username and REPOSITORY is the current working directory name.
+To explicitly name the new repository, pass in NAME, optionally in
+ORGANIZATION/NAME form to create under an organization you're a
+member of. With -p
, create a private repository, and with -d
and -h
+set the repository's description and homepage URL, respectively.
git clone
[-p
] OPTIONS [USER/
]REPOSITORY DIRECTORY:
Clone repository "git://github.com/USER/REPOSITORY.git" into
DIRECTORY as with git-clone(1). When USER/ is omitted, assumes
@@ -278,7 +280,7 @@ $ git am --ignore-whitespace https://github.com/davidbalbert/hub/commit/fdb9921
git fork
$ git fork
-... hardcore forking action ...
+[ repo forked on GitHub ]
> git remote add YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
@@ -292,8 +294,19 @@ $ git am --ignore-whitespace https://github.com/davidbalbert/hub/commit/fdb9921
git create
$ git create
-... hardcore creating action ...
+[ repo created on GitHub ]
> git remote add origin git@github.com:YOUR_USER/CURRENT_REPO.git
+
+# with description:
+$ git create -d 'It shall be mine, all mine!'
+
+$ git create recipes
+[ repo created on GitHub ]
+> git remote add origin git@github.com:YOUR_USER/recipes.git
+
+$ git create sinatra/recipes
+[ repo created in GitHub organization ]
+> git remote add origin git@github.com:sinatra/recipes.git
git push
diff --git a/man/hub.1.ronn b/man/hub.1.ronn
index 6dff67216bf97ffbf4c8bcfe7a49a5ee50e487e9..b2d460d9bc39ff06ef9b341bc31f333716ab7141 100644
--- a/man/hub.1.ronn
+++ b/man/hub.1.ronn
@@ -7,7 +7,7 @@ hub(1) -- git + hub = github
`hub alias` [`-s`]
`git init -g`
-`git create` [`-p`] [`-d `] [`-h `]
+`git create` [] [`-p`] [`-d` ] [`-h` ]
`git clone` [`-p`] [/]
`git remote add` [`-p`] [/]
`git remote set-url` [`-p`] [/]
@@ -36,13 +36,15 @@ alias command displays information on configuring your environment:
"git@github.com:/.git"; is your GitHub username and
is the current working directory's basename.
- * `git create` [`-p`] [`-d `] [`-h `]:
- Create a new public github repository from the current git
+ * `git create` [] [`-p`] [`-d` ] [`-h` ]:
+ Create a new public GitHub repository from the current git
repository and add remote `origin` at
"git@github.com:/.git"; is your GitHub
- username and is the current working directory's
- basename. With `-p`, create a private repository. `-d` and `-h`
- set the repository's description and homepage, respectively.
+ username and is the current working directory name.
+ To explicitly name the new repository, pass in , optionally in
+ / form to create under an organization you're a
+ member of. With `-p`, create a private repository, and with `-d` and `-h`
+ set the repository's description and homepage URL, respectively.
* `git clone` [`-p`] [`/`] :
Clone repository "git://github.com//.git" into
@@ -201,7 +203,7 @@ authentication?
### git fork
$ git fork
- ... hardcore forking action ...
+ [ repo forked on GitHub ]
> git remote add YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git
### git init
@@ -213,9 +215,20 @@ authentication?
### git create
$ git create
- ... hardcore creating action ...
+ [ repo created on GitHub ]
> git remote add origin git@github.com:YOUR_USER/CURRENT_REPO.git
+ # with description:
+ $ git create -d 'It shall be mine, all mine!'
+
+ $ git create recipes
+ [ repo created on GitHub ]
+ > git remote add origin git@github.com:YOUR_USER/recipes.git
+
+ $ git create sinatra/recipes
+ [ repo created in GitHub organization ]
+ > git remote add origin git@github.com:sinatra/recipes.git
+
### git push
$ git push origin,staging,qa bert_timeout
diff --git a/test/hub_test.rb b/test/hub_test.rb
index 560dd9683f77c9bfe94cb0aefde6066b85331026..0e847d1afe1813c12ff1a36e1eccdfdab6c63e0f 100644
--- a/test/hub_test.rb
+++ b/test/hub_test.rb
@@ -432,6 +432,28 @@ class HubTest < Test::Unit::TestCase
assert_equal expected, hub("create") { ENV['GIT'] = 'echo' }
end
+ def test_create_custom_name
+ stub_no_remotes
+ stub_nonexisting_fork('tpw', 'hubbub')
+ stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/create").
+ with(:body => { 'name' => 'hubbub' })
+
+ expected = "remote add -f origin git@github.com:tpw/hubbub.git\n"
+ expected << "created repository: tpw/hubbub\n"
+ assert_equal expected, hub("create hubbub") { ENV['GIT'] = 'echo' }
+ end
+
+ def test_create_in_organization
+ stub_no_remotes
+ stub_nonexisting_fork('acme', 'hubbub')
+ stub_request(:post, "https://#{auth}github.com/api/v2/yaml/repos/create").
+ with(:body => { 'name' => 'acme/hubbub' })
+
+ expected = "remote add -f origin git@github.com:acme/hubbub.git\n"
+ expected << "created repository: acme/hubbub\n"
+ assert_equal expected, hub("create acme/hubbub") { ENV['GIT'] = 'echo' }
+ end
+
def test_create_no_openssl
stub_no_remotes
stub_nonexisting_fork('tpw')
@@ -503,6 +525,11 @@ class HubTest < Test::Unit::TestCase
assert_equal expected, hub("create -d toyproject -h http://example.com") { ENV['GIT'] = 'echo' }
end
+ def test_create_with_invalid_arguments
+ assert_equal "invalid argument: -a\n", hub("create -a blah") { ENV['GIT'] = 'echo' }
+ assert_equal "invalid argument: bleh\n", hub("create blah bleh") { ENV['GIT'] = 'echo' }
+ end
+
def test_create_with_existing_repository
stub_no_remotes
stub_existing_fork('tpw')
@@ -871,16 +898,16 @@ config
@git["config alias.#{name}"] = value
end
- def stub_existing_fork(user)
- stub_fork(user, 200)
+ def stub_existing_fork(user, repo = 'hub')
+ stub_fork(user, repo, 200)
end
- def stub_nonexisting_fork(user)
- stub_fork(user, 404)
+ def stub_nonexisting_fork(user, repo = 'hub')
+ stub_fork(user, repo, 404)
end
- def stub_fork(user, status)
- stub_request(:get, "github.com/api/v2/yaml/repos/show/#{user}/hub").
+ def stub_fork(user, repo, status)
+ stub_request(:get, "github.com/api/v2/yaml/repos/show/#{user}/#{repo}").
to_return(:status => status)
end