Class: VCSToolkit::Repository
- Inherits:
-
Object
- Object
- VCSToolkit::Repository
- Defined in:
- lib/vcs_toolkit/repository.rb
Instance Attribute Summary collapse
-
#blob_class ⇒ Object
readonly
Returns the value of attribute blob_class.
-
#branch_head ⇒ Object
Returns the value of attribute branch_head.
-
#commit_class ⇒ Object
readonly
Returns the value of attribute commit_class.
-
#head ⇒ Object
Returns the value of attribute head.
-
#label_class ⇒ Object
readonly
Returns the value of attribute label_class.
-
#object_store ⇒ Object
readonly
Returns the value of attribute object_store.
-
#staging_area ⇒ Object
readonly
Returns the value of attribute staging_area.
-
#tree_class ⇒ Object
readonly
Returns the value of attribute tree_class.
Instance Method Summary collapse
- #commit(message, author, date, ignores: [], parents: nil, **context) ⇒ Object
-
#commit_status(base_commit, new_commit, ignore: []) ⇒ Object
Return new, changed and deleted files by comparing two commits.
-
#file_difference(file_path, commit) ⇒ Object
Return a list of changes between a file in the staging area and a specific commit.
-
#get_object(object_id) ⇒ Object
(also: #[])
Return the object with this object_id or nil if it doesn’t exist.
-
#history ⇒ Object
Enumerate all commits beginning with branch_head and ending with the commits that have empty ‘parents` list.
-
#initialize(object_store, staging_area, head: nil, commit_class: Objects::Commit, tree_class: Objects::Tree, blob_class: Objects::Blob, label_class: Objects::Label) ⇒ Repository
constructor
A new instance of Repository.
-
#merge(commit_one, commit_two) ⇒ Object
Merge two commits and save the changes to the staging area.
- #restore(path = '', commit) ⇒ Object
-
#set_label(name, reference_id) ⇒ Object
Create a label (named object) pointing to ‘reference_id`.
-
#status(commit, ignore: []) ⇒ Object
Return new, changed and deleted files compared to a specific commit and the staging area.
Constructor Details
#initialize(object_store, staging_area, head: nil, commit_class: Objects::Commit, tree_class: Objects::Tree, blob_class: Objects::Blob, label_class: Objects::Label) ⇒ Repository
Returns a new instance of Repository.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/vcs_toolkit/repository.rb', line 9 def initialize(object_store, staging_area, head: nil, commit_class: Objects::Commit, tree_class: Objects::Tree, blob_class: Objects::Blob, label_class: Objects::Label) @object_store = object_store @staging_area = staging_area @commit_class = commit_class @tree_class = tree_class @blob_class = blob_class @label_class = label_class self.head = head if head end |
Instance Attribute Details
#blob_class ⇒ Object (readonly)
Returns the value of attribute blob_class.
4 5 6 |
# File 'lib/vcs_toolkit/repository.rb', line 4 def blob_class @blob_class end |
#branch_head ⇒ Object
Returns the value of attribute branch_head.
7 8 9 |
# File 'lib/vcs_toolkit/repository.rb', line 7 def branch_head @branch_head end |
#commit_class ⇒ Object (readonly)
Returns the value of attribute commit_class.
4 5 6 |
# File 'lib/vcs_toolkit/repository.rb', line 4 def commit_class @commit_class end |
#head ⇒ Object
Returns the value of attribute head.
7 8 9 |
# File 'lib/vcs_toolkit/repository.rb', line 7 def head @head end |
#label_class ⇒ Object (readonly)
Returns the value of attribute label_class.
4 5 6 |
# File 'lib/vcs_toolkit/repository.rb', line 4 def label_class @label_class end |
#object_store ⇒ Object (readonly)
Returns the value of attribute object_store.
4 5 6 |
# File 'lib/vcs_toolkit/repository.rb', line 4 def object_store @object_store end |
#staging_area ⇒ Object (readonly)
Returns the value of attribute staging_area.
4 5 6 |
# File 'lib/vcs_toolkit/repository.rb', line 4 def staging_area @staging_area end |
#tree_class ⇒ Object (readonly)
Returns the value of attribute tree_class.
4 5 6 |
# File 'lib/vcs_toolkit/repository.rb', line 4 def tree_class @tree_class end |
Instance Method Details
#commit(message, author, date, ignores: [], parents: nil, **context) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/vcs_toolkit/repository.rb', line 56 def commit(, , date, ignores: [], parents: nil, **context) tree = create_tree ignores: ignores, **context parents = branch_head.nil? ? [] : [branch_head] if parents.nil? commit = commit_class.new message: , tree: tree.id, parents: parents, author: , date: date, **context object_store.store commit.id, commit self.branch_head = commit commit end |
#commit_status(base_commit, new_commit, ignore: []) ⇒ Object
Return new, changed and deleted files by comparing two commits.
The return value is a hash with :created, :changed and :deleted keys.
104 105 106 107 108 109 110 111 112 |
# File 'lib/vcs_toolkit/repository.rb', line 104 def commit_status(base_commit, new_commit, ignore: []) base_tree = get_object(base_commit.tree) unless base_commit.nil? new_tree = get_object(new_commit.tree) unless new_commit.nil? Utils::Status.compare_trees base_tree, new_tree, object_store, ignore: ignore end |
#file_difference(file_path, commit) ⇒ Object
Return a list of changes between a file in the staging area and a specific commit.
This method is just a tiny wrapper around VCSToolkit::Diff.from_sequences which loads the two files and splits them by lines beforehand. It also ensures that both files have n at the end (otherwise the last two lines of the diff may be merged).
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/vcs_toolkit/repository.rb', line 179 def file_difference(file_path, commit) if staging_area.file? file_path file_lines = staging_area.fetch(file_path).lines file_lines.last << "\n" unless file_lines.last.nil? or file_lines.last.end_with? "\n" else file_lines = [] end tree = get_object commit.tree blob_name_and_id = tree.all_files(object_store).find { |file, _| file_path == file } if blob_name_and_id.nil? blob_lines = [] else blob = get_object blob_name_and_id.last blob_lines = blob.content.lines blob_lines.last << "\n" unless blob_lines.last.nil? or blob_lines.last.end_with? "\n" end Diff.from_sequences blob_lines, file_lines end |
#get_object(object_id) ⇒ Object Also known as: []
Return the object with this object_id or nil if it doesn’t exist.
77 78 79 |
# File 'lib/vcs_toolkit/repository.rb', line 77 def get_object(object_id) object_store.fetch object_id if object_store.key? object_id end |
#history ⇒ Object
Enumerate all commits beginning with branch_head and ending with the commits that have empty ‘parents` list.
They aren’t strictly ordered by date, but in a BFS visit order.
120 121 122 123 124 |
# File 'lib/vcs_toolkit/repository.rb', line 120 def history return [] if branch_head.nil? get_object(branch_head).history(object_store) end |
#merge(commit_one, commit_two) ⇒ Object
Merge two commits and save the changes to the staging area.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/vcs_toolkit/repository.rb', line 129 def merge(commit_one, commit_two) common_ancestor = commit_one.common_ancestor(commit_two, object_store) commit_one_files = Hash[get_object(commit_one.tree).all_files(object_store).to_a] commit_two_files = Hash[get_object(commit_two.tree).all_files(object_store).to_a] if common_ancestor.nil? ancestor_files = {} else ancestor_files = Hash[get_object(common_ancestor.tree).all_files(object_store).to_a] end all_files = commit_one_files.keys | commit_two_files.keys | ancestor_files.keys merged = [] conflicted = [] all_files.each do |file| ancestor = ancestor_files.key?(file) ? get_object(ancestor_files[file]).content.lines : [] file_one = commit_one_files.key?(file) ? get_object(commit_one_files[file]).content.lines : [] file_two = commit_two_files.key?(file) ? get_object(commit_two_files[file]).content.lines : [] diff = VCSToolkit::Merge.three_way ancestor, file_one, file_two if diff.has_conflicts? conflicted << file elsif diff.has_changes? merged << file end content = diff.new_content("<<<<< #{commit_one.id}\n", ">>>>> #{commit_two.id}\n", "=====\n") if content.empty? staging_area.delete_file file if staging_area.file? file else staging_area.store file, content.join('') end end {merged: merged, conflicted: conflicted} end |
#restore(path = '', commit) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/vcs_toolkit/repository.rb', line 202 def restore(path='', commit) tree = get_object commit.tree object_id = tree.find(object_store, path) raise KeyError, 'File does not exist in the specified commit' if object_id.nil? blob_or_tree = get_object object_id case blob_or_tree.object_type when :blob restore_file path, blob_or_tree when :tree restore_directory path, blob_or_tree else raise 'Unknown object type returned by Tree#find' end end |
#set_label(name, reference_id) ⇒ Object
Create a label (named object) pointing to ‘reference_id`
If the label already exists it is overriden.
225 226 227 228 229 |
# File 'lib/vcs_toolkit/repository.rb', line 225 def set_label(name, reference_id) label = label_class.new id: name, reference_id: reference_id object_store.store name, label end |
#status(commit, ignore: []) ⇒ Object
Return new, changed and deleted files compared to a specific commit and the staging area.
The return value is a hash with :created, :changed and :deleted keys.
89 90 91 92 93 94 95 96 |
# File 'lib/vcs_toolkit/repository.rb', line 89 def status(commit, ignore: []) tree = get_object(commit.tree) unless commit.nil? Utils::Status.compare_tree_and_store tree, staging_area, object_store, ignore: ignore end |