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