Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get permalinks for the local HEAD not the HEAD of the remote branch #119

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The following commands are available in the Command Palette:

**The following commands require the Git plugin, available through the Package Manager. After installing, restart Sublime Text.**

**Note:** These commands use the currently checked out branch to generate GitHub URLs. Each command also has a corresponding version, such as **GitHub: Blame (master)**, that always uses the master branch, regardless of which branch is checked out locally. All commands except **GitHub: Edit** have a corresponding "permalink" version too, like **GitHub: Blame (permalink)**, that uses the most recent commit on the current branch ([more info](https://help.github.com/en/articles/getting-permanent-links-to-files)).
**Note:** These commands use the currently checked-out branch to generate GitHub URLs. Each command also has a corresponding version, such as **GitHub: Blame (master)**, that always uses the master branch, regardless of which branch is checked-out locally. All commands except **GitHub: Edit** have a corresponding "permalink" version too, like **GitHub: Blame (permalink)**, that references the currently checked-out commit ([more info](https://help.github.com/en/articles/getting-permanent-links-to-files)).

* **GitHub: Open Remote URL in Browser**

Expand Down
51 changes: 37 additions & 14 deletions sublime_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,19 +431,35 @@ def run(self, edit):
if self.branch == "master":
branch = "master"
else:
# Get the current remote branch--useful whether we want to link directly to that
# branch or to the branch's HEAD.
# Get the current remote branch. Won't be used for permalink commands but is still
# useful to give us the remote name.
branch = ""
command = "git rev-parse --abbrev-ref --symbolic-full-name %s@{upstream}" % branch
self.run_command(command.split(), self.done_rev_parse)
self.run_command(command.split(), self.done_remote_branch)

def done_rev_parse(self, result):
def done_remote_branch(self, result):
if "fatal:" in result:
sublime.error_message(result)
return
if ("no upstream configured" in result or "HEAD does not point to a branch" in result) and not self.branch:
# These results indicate either that the user has not pushed the branch to the remote
# or that the user has a commit checked out rather than a branch. If this is a permalink
# command (`not self.branch`) and the user has only one remote, then we can proceed
# regardless, since we don't calculate the permalink with respect to the remote branch
# but rather the local HEAD--see `generate_url` for why.
self.run_command("git remote".split(), self.done_remote_list)
else:
sublime.error_message(result)
else:
remote, self.remote_branch = result.strip().split("/", 1)
self.done_remote(remote)

remote, self.remote_branch = result.strip().split("/", 1)
def done_remote_list(self, result):
remote_list = result.strip().split('\n')
if len(remote_list) == 1:
self.done_remote(remote_list[0])
else:
sublime.error_message("Please push this branch to a remote, then re-run this command.")

def done_remote(self, remote):
self.settings = sublime.load_settings("GitHub.sublime-settings")
self.active_account = self.settings.get("active_account")
self.accounts = self.settings.get("accounts")
Expand All @@ -457,9 +473,9 @@ def done_rev_parse(self, result):

command = "git ls-remote --get-url " + remote

self.run_command(command.split(), self.done_remote)
self.run_command(command.split(), self.done_remote_url)

def done_remote(self, result):
def done_remote_url(self, result):
remote_loc = result.split()[0]
repo_url = re.sub('^git(@|://)', self.protocol + '://', remote_loc)
# Replace the "tld:" with "tld/"
Expand Down Expand Up @@ -505,18 +521,25 @@ def done_toplevel(self, result):
if self.branch:
self.generate_url()
else:
command = "git rev-parse " + self.remote_branch
self.run_command(command.split(), self.done_remote_head)
command = "git rev-parse HEAD"
self.run_command(command.split(), self.done_head)

def done_remote_head(self, result):
self.remote_head = result.strip()
def done_head(self, result):
self.head = result.strip()
self.generate_url()

def generate_url(self):
if self.branch:
remote_id = self.remote_branch
else:
remote_id = self.remote_head
# Reference the local HEAD for permalinks, rather than the HEAD of the remote branch, because
# this way we'll get a link to what the user is actually looking at in their editor. This also
# lets the user run the permalink command with a commit checked out rather than a branch; or
# having checked out a branch that they've just created, if the user has neither added commits
# to that branch nor pushed the branch to the remote. If the user _has_ added commits to such
# a branch without pushing them to the remote, then the link will 404 on GitHub. At some
# future point, it might be nice to detect this and show an error message locally.
remote_id = self.head
self.url = "%s/%s/%s%s%s" % (self.repo_url, self.url_type, remote_id, self.relative_path, self.line_nums)
self.on_done()
else:
Expand Down