Skip to content

Commit

Permalink
Enhancement: more history related methods
Browse files Browse the repository at this point in the history
  • Loading branch information
randy3k committed Jul 25, 2017
1 parent c2d42fb commit fedec73
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 44 deletions.
43 changes: 0 additions & 43 deletions core/commands/inline_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,49 +198,6 @@ def run(self, edit):

sublime.set_timeout_async(lambda: self.verify_not_conflict(), 0)

def get_indexed_file_object(self, file_path):
"""
Given an absolute path to a file contained in a git repo, return
git's internal object hash associated with the version of that file
in the index (if the file is staged) or in the HEAD (if it is not
staged).
"""
stdout = self.git("ls-files", "-s", file_path)

# 100644 c9d70aa928a3670bc2b879b4a596f10d3e81ba7c 0 SomeFile.py
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
git_file_entry = stdout.split(" ")
return git_file_entry[1]

def get_head_file_object(self, file_path):
"""
Given an absolute path to a file contained in a git repo, return
git's internal object hash associated with the version of that
file in the HEAD.
"""
stdout = self.git("ls-tree", "HEAD", file_path)

# 100644 blob 7317069f30eafd4d7674612679322d59f9fb65a4 SomeFile.py
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
git_file_entry = stdout.split() # split by spaces and tabs
return git_file_entry[2]

def get_object_contents(self, object_hash):
"""
Given the object hash to a versioned object in the current git repo,
display the contents of that object.
"""
return self.git("show", "--no-color", object_hash)

def get_object_from_string(self, string):
"""
Given a string, pipe the contents of that string to git and have it
stored in the current repo, and return an object-hash that can be
used to diff against.
"""
stdout = self.git("hash-object", "-w", "--stdin", stdin=string, encode=False)
return stdout.split("\n")[0]

def get_inline_diff_contents(self, original_contents, diff):
"""
Given a file's original contents and an array of hunks that could be
Expand Down
128 changes: 127 additions & 1 deletion core/git_mixins/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,12 @@ def get_short_hash(self, commit_hash):
def filename_at_commit(self, filename, commit_hash):
commit_len = len(commit_hash)
lines = self.git(
"log", "--pretty=oneline", "--follow", "--name-status", "--", filename
"log",
"--pretty=oneline",
"--follow",
"--name-status",
"{}..{}".format(commit_hash, "HEAD"),
"--", filename
).split("\n")

for i in range(0, len(lines), 2):
Expand All @@ -160,3 +165,124 @@ def filename_at_commit(self, filename, commit_hash):

# If the commit hash is not for this file.
return filename

def get_file_content_at_commit(self, filename, commit_hash):
filename = self.get_rel_path(filename)
filename = filename.replace('\\\\', '/')
filename = self.filename_at_commit(filename, commit_hash)
return self.git("show", commit_hash + ':' + filename)

def find_matching_lineno(self, base_commit, target_commit, line, file_path=None):
"""
Return the matching line of the target_commit given the line number of the base_commit.
"""
if not file_path:
file_path = self.file_path

if base_commit:
base_object = self.get_commit_file_object(base_commit, file_path)
else:
base_file_contents = util.file.get_file_contents_binary(self.repo_path, file_path)
base_object = self.get_object_from_string(base_file_contents)

target_object = self.get_commit_file_object(target_commit, file_path)

stdout = self.git(
"diff", "--no-color", "-U0", base_object, target_object)
diff = util.parse_diff(stdout)

if not diff:
return line

for hunk in reversed(diff):
head_start = hunk.head_start if hunk.head_length else hunk.head_start + 1
saved_start = hunk.saved_start if hunk.saved_length else hunk.saved_start + 1
head_end = head_start + hunk.head_length
saved_end = saved_start + hunk.saved_length

if head_end <= line:
return saved_end + line - head_end
elif head_start <= line:
return saved_start

# fails to find matching
return 1

def neighbor_commit(self, commit_hash, position):
"""
Get the commit before or after a specific commit
"""
if position == "older":
return self.git(
"log",
"--format=%H",
"--follow",
"-n", "1",
"{}~1".format(commit_hash),
"--", self.file_path
).strip()
elif position == "newer":
return self.git(
"log",
"--format=%H",
"--follow",
"--reverse",
"{}..{}".format(commit_hash, "HEAD"),
"--", self.file_path
).strip().split("\n", 1)[0]

def get_indexed_file_object(self, file_path):
"""
Given an absolute path to a file contained in a git repo, return
git's internal object hash associated with the version of that file
in the index (if the file is staged) or in the HEAD (if it is not
staged).
"""
stdout = self.git("ls-files", "-s", file_path)

# 100644 c9d70aa928a3670bc2b879b4a596f10d3e81ba7c 0 SomeFile.py
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
git_file_entry = stdout.split(" ")
return git_file_entry[1]

def get_head_file_object(self, file_path):
"""
Given an absolute path to a file contained in a git repo, return
git's internal object hash associated with the version of that
file in the HEAD.
"""
stdout = self.git("ls-tree", "HEAD", file_path)

# 100644 blob 7317069f30eafd4d7674612679322d59f9fb65a4 SomeFile.py
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
git_file_entry = stdout.split() # split by spaces and tabs
return git_file_entry[2]

def get_commit_file_object(self, commit, file_path):
"""
Given an absolute path to a file contained in a git repo, return
git's internal object hash associated with the version of that
file in the commit.
"""
stdout = self.git("ls-tree", commit, file_path)

# 100644 blob 7317069f30eafd4d7674612679322d59f9fb65a4 SomeFile.py
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
git_file_entry = stdout.split() # split by spaces and tabs
return git_file_entry[2]

def get_object_contents(self, object_hash):
"""
Given the object hash to a versioned object in the current git repo,
display the contents of that object.
"""
return self.git("show", "--no-color", object_hash)

def get_object_from_string(self, string):
"""
Given a string, pipe the contents of that string to git and have it
stored in the current repo, and return an object-hash that can be
used to diff against.
"""
stdout = self.git("hash-object", "-w", "--stdin", stdin=string, encode=False)
return stdout.split("\n")[0]

0 comments on commit fedec73

Please sign in to comment.