提交 231366d1 编写于 作者: M Mislav Marohnić

tracking branches awarness; `git browse` subpages (e.g. `git browse repo issues`)

New abilities:

  $ hub compare
  -> When on a branch that tracks "remotebranch", for example,
     this opens "github.com/user/repo/compare/remotebranch".
     In effect if the tracked branch is not "master".

  $ hub browse reque issues
  -> open http://github.com/user/resque/issues

  $ hub browse
  -> When on a branch that tracks "remotebranch", for example,
     this opens "github.com/user/repo/tree/remotebranch".
     In effect if the tracked branch is not "master".

  $ hub browse -- commits
  -> open http://github.com/user/repo/commits/master

  If this branch is tracking a remote branch:
  -> open http://github.com/user/repo/commits/remotebranch

Supported subpages:

  - "tree" (default)
  - "wiki"
  - "commits"
  - "issues", "network", "downloads" or any other arbitrary
    string is simply appended to URL path
上级 26af67ab
......@@ -153,6 +153,9 @@ login" below for details.
$ git browse
> open http://github.com/CURRENT_REPO
$ git browse -- issues
> open http://github.com/CURRENT_REPO/issues
$ git browse schacon/ticgit
> open http://github.com/schacon/ticgit
......@@ -162,6 +165,9 @@ login" below for details.
$ git browse resque
> open http://github.com/YOUR_USER/resque
$ git browse resque network
> open http://github.com/YOUR_USER/resque/network
$ git browse -p resque
> open https://github.com:YOUR_USER/resque
......
......@@ -193,6 +193,9 @@ module Hub
# $ hub browse
# > open http://github.com/CURRENT_REPO
#
# $ hub browse -- issues
# > open http://github.com/CURRENT_REPO/issues
#
# $ hub browse pjhyett/github-services
# > open http://github.com/pjhyett/github-services
#
......@@ -202,13 +205,17 @@ module Hub
# $ hub browse github-services
# > open http://github.com/YOUR_LOGIN/github-services
#
# $ hub browse github-services wiki
# > open http://wiki.github.com/YOUR_LOGIN/github-services
#
# $ hub browse -p github-fi
# > open https://github.com/YOUR_LOGIN/github-fi
def browse(args)
args.shift
browse_command(args) do
user = repo = nil
dest = args.pop
dest = args.shift
dest = nil if dest == '--'
if dest
# $ hub browse pjhyett/github-services
......@@ -222,7 +229,23 @@ module Hub
exit(1)
end
{ :user => user, :repo => repo }
params = { :user => user, :repo => repo }
# $ hub browse -- wiki
case subpage = args.shift
when 'wiki'
params[:web] = 'wiki'
when 'commits'
branch = (!dest && tracked_branch) || 'master'
params[:web] = "/commits/#{branch}"
when 'tree', NilClass
branch = !dest && tracked_branch
params[:web] = "/tree/#{branch}" if branch and branch != 'master'
else
params[:web] = "/#{subpage}"
end
params
end
end
......@@ -235,17 +258,21 @@ module Hub
# $ hub compare -p myfork topsecret
# > open https://github.com/myfork/REPO/compare/topsecret
# $ hub compare -u 1.0...2.0
# (Prints the URL for the compare view)
# prints "http://github.com/CURRENT_REPO/compare/1.0...2.0"
def compare(args)
args.shift
browse_command(args) do
if args.empty?
warn "Usage: hub compare [USER] [<START>...]<END>"
exit(1)
if branch = tracked_branch and branch != 'master'
range, user = branch, repo_user
else
warn "Usage: hub compare [USER] [<START>...]<END>"
exit(1)
end
else
range = args.pop
user = args.pop || repo_user
end
range = args.pop
user = args.pop || repo_user
{ :user => user, :web => "/compare/#{range}" }
end
end
......
......@@ -24,12 +24,15 @@ module Hub
private
def repo_owner
REMOTES['origin'][:user]
REMOTES[default_remote][:user]
end
def repo_user
REMOTES[current_remote][:user]
end
alias repo_user repo_owner
def repo_name
REMOTES['origin'][:repo] || File.basename(Dir.pwd)
REMOTES[default_remote][:repo] || File.basename(Dir.pwd)
end
# Either returns the GitHub user as set by git-config(1) or aborts
......@@ -44,18 +47,50 @@ module Hub
fatal ? abort("** No GitHub token set. See #{LGHCONF}") : nil
end
def current_branch
GIT_CONFIG['symbolic-ref -q HEAD']
end
def tracked_branch
branch = current_branch && tracked_for(current_branch)
normalize_branch(branch) if branch
end
def current_remote
(current_branch && remote_for(current_branch)) || default_remote
end
def default_remote
'origin'
end
def normalize_branch(branch)
branch.sub('refs/heads/', '')
end
def remote_for(branch)
GIT_CONFIG['config branch.%s.remote' % normalize_branch(branch)]
end
def tracked_for(branch)
GIT_CONFIG['config branch.%s.merge' % normalize_branch(branch)]
end
def http_clone?
GIT_CONFIG['config --bool hub.http-clone'] == 'true'
end
def github_url(options = {})
user, repo = options[:user], options[:repo]
user, repo = repo.split('/') if user.nil? and repo and repo.index('/')
user ||= github_user
repo = options[:repo]
user, repo = repo.split('/') if repo and repo.index('/')
user ||= options[:user] || github_user
repo ||= repo_name
secure = options[:private]
if options[:web]
if options[:web] == 'wiki'
scheme = secure ? 'https:' : 'http:'
'%s//wiki.github.com/%s/%s/' % [scheme, user, repo]
elsif options[:web]
scheme = secure ? 'https:' : 'http:'
path = options[:web] == true ? '' : options[:web].to_s
'%s//github.com/%s/%s%s' % [scheme, user, repo, path]
......
......@@ -7,7 +7,10 @@
\fBhub\fR \-\- git + hub = github
.
.SH "SYNOPSIS"
\fBhub\fR \fICOMMAND\fR \fIOPTIONS\fR \fBhub alias\fR [\fB\-s\fR] \fISHELL\fR
\fBhub\fR \fICOMMAND\fR \fIOPTIONS\fR
.
.br
\fBhub alias\fR [\fB\-s\fR] \fISHELL\fR
.
.P
\fBgit init \-g\fR \fIOPTIONS\fR
......@@ -37,7 +40,10 @@ alias command displays information on configuring your environment:
.TP
\fBhub alias\fR [\fB\-s\fR] \fISHELL\fR
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
this command can be evaluated directly within the shell: \fBeval $(hub alias \-s bash)\fR
this command can be evaluated directly within the shell:
.
.br
\fBeval $(hub alias \-s bash)\fR
.
.TP
\fBgit init\fR \fB\-g\fR \fIOPTIONS\fR
......@@ -70,17 +76,19 @@ username. It requires your GitHub login and token to be present. See
CONFIGURATION below.
.
.TP
\fBgit browse\fR [\fB\-p\fR] [[\fIUSER\fR\fB/\fR]\fIREPOSITORY\fR]
\fBgit browse\fR [\fB\-p\fR] [\fB\-u\fR] [[\fIUSER\fR\fB/\fR]\fIREPOSITORY\fR] [SUBPAGE]
Open repository's GitHub page in the system's default web browser
using \fBopen(1)\fR or the \fBBROWSER\fR env variable. Use \fB\-p\fR to open a
page with https. If the repository isn't specified, \fBbrowse\fR opens
the page of the repository found in the current directory.
the page of the repository found in the current directory. If SUBPAGE
is specified, the browser will open on the specified subpage: one of
"wiki", "commits", "issues" or other (the default is "tree").
.
.TP
\fBgit compare\fR [\fB\-u\fR] [\fIUSER\fR] [\fISTART\fR...]\fIEND\fR
\fBgit compare\fR [\fB\-p\fR] [\fB\-u\fR] [\fIUSER\fR] [\fISTART\fR...]\fIEND\fR
Open a GitHub compare view page in the system's default web browser. \fISTART\fR to \fIEND\fR are branch names, tag names, or commit SHA1s specifying
the range of history to compare. If \fISTART\fR is omitted,
the repository's default branch is assumed.
the range of history to compare. If \fISTART\fR is omitted, GitHub will
compare against the base branch (the default is "master").
.
.TP
\fBgit submodule add\fR [\fB\-p\fR] \fIOPTIONS\fR [\fIUSER\fR/]\fIREPOSITORY\fR \fIDIRECTORY\fR
......@@ -137,7 +145,7 @@ cloning:
.
.nf
$ git config \-\-global \-\-add hub.http\-clone yes
$ git config \-\-global \-\-bool hub.http\-clone true
.
.fi
.
......@@ -213,6 +221,12 @@ $ git push origin,staging,qa bert_timeout
.
.nf
$ git browse
> open http://github.com/CURRENT_REPO
$ git browse \-\- issues
> open http://github.com/CURRENT_REPO/issues
$ git browse schacon/ticgit
> open http://github.com/schacon/ticgit
......@@ -222,8 +236,11 @@ $ git browse \-p schacon/ticgit
$ git browse resque
> open http://github.com/YOUR_USER/resque
$ git browse resque network
> open http://github.com/YOUR_USER/resque/network
$ git browse \-p resque
> open https://github.com:YOUR_USER/resque
> open https://github.com/YOUR_USER/resque
.
.fi
.
......
......@@ -67,7 +67,7 @@
<h2>SYNOPSIS</h2>
<p><code>hub</code> <var>COMMAND</var> <var>OPTIONS</var>
<p><code>hub</code> <var>COMMAND</var> <var>OPTIONS</var><br />
<code>hub alias</code> [<code>-s</code>] <var>SHELL</var></p>
<p><code>git init -g</code> <var>OPTIONS</var><br />
......@@ -86,7 +86,7 @@ alias command displays information on configuring your environment:</p>
<dl>
<dt><code>hub alias</code> [<code>-s</code>] <var>SHELL</var></dt><dd><p>Writes shell aliasing code for <var>SHELL</var> (<code>bash</code>, <code>sh</code>, <code>zsh</code>,
<code>csh</code>) to standard output. With the <code>-s</code> option, the output of
this command can be evaluated directly within the shell:
this command can be evaluated directly within the shell:<br />
<code>eval $(hub alias -s bash)</code></p></dd>
<dt><code>git init</code> <code>-g</code> <var>OPTIONS</var></dt><dd><p>Create a git repository as with git-init(1) and add remote <code>origin</code> at
"git@github.com:<var>USER</var>/<var>REPOSITORY</var>.git"; <var>USER</var> is your GitHub username and
......@@ -105,14 +105,16 @@ multiple <code>git push</code> commands.</p></dd>
<dt><code>git fork</code></dt><dd><p>Forks the original repo on GitHub and adds the new remote under your
username. It requires your GitHub login and token to be present. See
CONFIGURATION below.</p></dd>
<dt><code>git browse</code> [<code>-p</code>] [[<var>USER</var><code>/</code>]<var>REPOSITORY</var>]</dt><dd><p>Open repository's GitHub page in the system's default web browser
<dt><code>git browse</code> [<code>-p</code>] [<code>-u</code>] [[<var>USER</var><code>/</code>]<var>REPOSITORY</var>] [SUBPAGE]</dt><dd><p>Open repository's GitHub page in the system's default web browser
using <code>open(1)</code> or the <code>BROWSER</code> env variable. Use <code>-p</code> to open a
page with https. If the repository isn't specified, <code>browse</code> opens
the page of the repository found in the current directory.</p></dd>
<dt><code>git compare</code> [<code>-u</code>] [<var>USER</var>] [<var>START</var>...]<var>END</var></dt><dd><p>Open a GitHub compare view page in the system's default web browser.
the page of the repository found in the current directory. If SUBPAGE
is specified, the browser will open on the specified subpage: one of
"wiki", "commits", "issues" or other (the default is "tree").</p></dd>
<dt><code>git compare</code> [<code>-p</code>] [<code>-u</code>] [<var>USER</var>] [<var>START</var>...]<var>END</var></dt><dd><p>Open a GitHub compare view page in the system's default web browser.
<var>START</var> to <var>END</var> are branch names, tag names, or commit SHA1s specifying
the range of history to compare. If <var>START</var> is omitted,
the repository's default branch is assumed.</p></dd>
the range of history to compare. If <var>START</var> is omitted, GitHub will
compare against the base branch (the default is "master").</p></dd>
<dt><code>git submodule add</code> [<code>-p</code>] <var>OPTIONS</var> [<var>USER</var>/]<var>REPOSITORY</var> <var>DIRECTORY</var></dt><dd><p>Submodule repository "git://github.com/<var>USER</var>/<var>REPOSITORY</var>.git" into
<var>DIRECTORY</var> as with git-submodule(1). When <var>USER</var>/ is omitted, assumes
your GitHub login. With <code>-p</code>, use private remote
......@@ -143,7 +145,7 @@ information.</p>
<p>You can also tell <code>hub</code> to use <code>http://</code> rather than <code>git://</code> when
cloning:</p>
<pre><code>$ git config --global --add hub.http-clone yes
<pre><code>$ git config --global --bool hub.http-clone true
</code></pre>
<h2>EXAMPLES</h2>
......@@ -199,7 +201,13 @@ $ git remote add origin
<h3>git browse</h3>
<pre><code>$ git browse schacon/ticgit
<pre><code>$ git browse
&gt; open http://github.com/CURRENT_REPO
$ git browse -- issues
&gt; open http://github.com/CURRENT_REPO/issues
$ git browse schacon/ticgit
&gt; open http://github.com/schacon/ticgit
$ git browse -p schacon/ticgit
......@@ -208,8 +216,11 @@ $ git browse -p schacon/ticgit
$ git browse resque
&gt; open http://github.com/YOUR_USER/resque
$ git browse resque network
&gt; open http://github.com/YOUR_USER/resque/network
$ git browse -p resque
&gt; open https://github.com:YOUR_USER/resque
&gt; open https://github.com/YOUR_USER/resque
</code></pre>
<h3>git compare</h3>
......
......@@ -3,7 +3,7 @@ hub(1) -- git + hub = github
## SYNOPSIS
`hub` <COMMAND> <OPTIONS>
`hub` <COMMAND> <OPTIONS>
`hub alias` [`-s`] <SHELL>
`git init -g` <OPTIONS>
......@@ -22,7 +22,7 @@ alias command displays information on configuring your environment:
* `hub alias` [`-s`] <SHELL>:
Writes shell aliasing code for <SHELL> (`bash`, `sh`, `zsh`,
`csh`) to standard output. With the `-s` option, the output of
this command can be evaluated directly within the shell:
this command can be evaluated directly within the shell:
`eval $(hub alias -s bash)`
* `git init` `-g` <OPTIONS>:
......@@ -52,17 +52,19 @@ alias command displays information on configuring your environment:
username. It requires your GitHub login and token to be present. See
CONFIGURATION below.
* `git browse` [`-p`] [[<USER>`/`]<REPOSITORY>]:
* `git browse` [`-p`] [`-u`] [[<USER>`/`]<REPOSITORY>] [SUBPAGE]:
Open repository's GitHub page in the system's default web browser
using `open(1)` or the `BROWSER` env variable. Use `-p` to open a
page with https. If the repository isn't specified, `browse` opens
the page of the repository found in the current directory.
the page of the repository found in the current directory. If SUBPAGE
is specified, the browser will open on the specified subpage: one of
"wiki", "commits", "issues" or other (the default is "tree").
* `git compare` [`-u`] [<USER>] [<START>...]<END>:
* `git compare` [`-p`] [`-u`] [<USER>] [<START>...]<END>:
Open a GitHub compare view page in the system's default web browser.
<START> to <END> are branch names, tag names, or commit SHA1s specifying
the range of history to compare. If <START> is omitted,
the repository's default branch is assumed.
the range of history to compare. If <START> is omitted, GitHub will
compare against the base branch (the default is "master").
* `git submodule add` [`-p`] <OPTIONS> [<USER>/]<REPOSITORY> <DIRECTORY>:
Submodule repository "git://github.com/<USER>/<REPOSITORY>.git" into
......@@ -145,6 +147,12 @@ cloning:
### git browse
$ git browse
> open http://github.com/CURRENT_REPO
$ git browse -- issues
> open http://github.com/CURRENT_REPO/issues
$ git browse schacon/ticgit
> open http://github.com/schacon/ticgit
......@@ -154,8 +162,11 @@ cloning:
$ git browse resque
> open http://github.com/YOUR_USER/resque
$ git browse resque network
> open http://github.com/YOUR_USER/resque/network
$ git browse -p resque
> open https://github.com:YOUR_USER/resque
> open https://github.com/YOUR_USER/resque
### git compare
......
......@@ -20,22 +20,19 @@ class HubTest < Test::Unit::TestCase
@git = Hub::Context::GIT_CONFIG.replace(Hash.new { |h, k|
raise ArgumentError, "`git #{k}` not stubbed"
}).update(
'config github.user' => 'tpw',
'config github.token' => 'abc123',
'config remote.origin.url' => 'git://github.com/defunkt/hub.git',
'symbolic-ref -q HEAD' => 'refs/heads/master',
'config github.user' => 'tpw',
'config github.token' => 'abc123',
'config remote.origin.url' => 'git://github.com/defunkt/hub.git',
'config remote.mislav.url' => 'git://github.com/mislav/hub.git',
'config branch.master.remote' => 'origin',
'config branch.master.merge' => 'refs/heads/master',
'config branch.feature.remote' => 'mislav',
'config branch.feature.merge' => 'refs/heads/experimental',
'config --bool hub.http-clone' => 'false'
)
end
def stub_github_user(name)
@git['config github.user'] = name
end
def stub_repo_url(value)
@git['config remote.origin.url'] = value
Hub::Context::REMOTES.clear
end
def test_private_clone
input = "clone -p rtomayko/ronn"
command = "git clone git@github.com:rtomayko/ronn.git"
......@@ -307,6 +304,24 @@ config
"open http://github.com/defunkt/hub/compare/refactor"
end
def test_hub_compare_nothing
expected = "Usage: hub compare [USER] [<START>...]<END>\n"
assert_equal expected, hub("compare")
end
def test_hub_compare_tracking_nothing
stub_tracking_nothing
expected = "Usage: hub compare [USER] [<START>...]<END>\n"
assert_equal expected, hub("compare")
end
def test_hub_compare_tracking_branch
stub_branch('refs/heads/feature')
assert_command "compare",
"open http://github.com/mislav/hub/compare/experimental"
end
def test_hub_compare_range
assert_command "compare 1.0...fix",
"open http://github.com/defunkt/hub/compare/1.0...fix"
......@@ -331,6 +346,11 @@ config
assert_command "browse mojombo/bert", "open http://github.com/mojombo/bert"
end
def test_hub_browse_tracking_nothing
stub_tracking_nothing
assert_command "browse mojombo/bert", "open http://github.com/mojombo/bert"
end
def test_hub_browse_url
assert_command "browse -u mojombo/bert", "echo http://github.com/mojombo/bert"
end
......@@ -344,12 +364,44 @@ config
assert_command "browse resque", "open http://github.com/tpw/resque"
end
def test_hub_browse_subpage
assert_command "browse resque commits",
"open http://github.com/tpw/resque/commits/master"
assert_command "browse resque issues",
"open http://github.com/tpw/resque/issues"
assert_command "browse resque wiki",
"open http://wiki.github.com/tpw/resque/"
end
def test_hub_browse_on_branch
stub_branch('refs/heads/feature')
assert_command "browse resque", "open http://github.com/tpw/resque"
assert_command "browse resque commits",
"open http://github.com/tpw/resque/commits/master"
assert_command "browse",
"open http://github.com/mislav/hub/tree/experimental"
assert_command "browse -- tree",
"open http://github.com/mislav/hub/tree/experimental"
assert_command "browse -- commits",
"open http://github.com/mislav/hub/commits/experimental"
end
def test_hub_browse_self_private
assert_command "browse -p github", "open https://github.com/tpw/github"
end
def test_hub_browse_current
assert_command "browse", "open http://github.com/defunkt/hub"
assert_command "browse --", "open http://github.com/defunkt/hub"
end
def test_hub_browse_current_subpage
assert_command "browse -- network",
"open http://github.com/defunkt/hub/network"
assert_command "browse -- anything/everything",
"open http://github.com/defunkt/hub/anything/everything"
end
def test_hub_browse_current_private
......@@ -397,6 +449,24 @@ config
protected
def stub_github_user(name)
@git['config github.user'] = name
end
def stub_repo_url(value)
@git['config remote.origin.url'] = value
Hub::Context::REMOTES.clear
end
def stub_branch(value)
@git['symbolic-ref -q HEAD'] = value
end
def stub_tracking_nothing
@git['config branch.master.remote'] = nil
@git['config branch.master.merge'] = nil
end
def stub_available_commands(*names)
COMMANDS.replace names
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册