class DTK::Common::GritAdapter::FileAccess
Copyright (C) 2010-2016 dtk contributors
This file is part of the dtk project.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Constants
- DefaultAuthor
- TempBranch
temp branch #TODO: make sure no name conflict
Public Instance Methods
# File lib/grit_adapter/file_access.rb, line 242 def add_branch(branch) chdir_and_checkout() do git_command(:branch,branch) end end
# File lib/grit_adapter/file_access.rb, line 237 def add_branch?(branch) unless branches().include?(branch) add_branch(branch) end end
# File lib/grit_adapter/file_access.rb, line 27 def add_file(file_rel_path, content=nil) content ||= String.new file_path = qualified_path(file_rel_path) chdir_and_checkout do File.open(file_path,"w"){|f|f << content} git_command__add(file_path) end end
# File lib/grit_adapter/file_access.rb, line 36 def add_file_command(file_rel_path) chdir_and_checkout do file_path = qualified_path(file_rel_path) git_command__add(file_path) end end
Method will add and remove all files, after commit with given msg
# File lib/grit_adapter/file_access.rb, line 149 def add_remove_commit_all(commit_msg) chdir do # modified, untracked changed_files().each do |c_file| add_file_command(c_file.first) end # deleted deleted_files().each do |d_file| remove_file(d_file.first) end # commit commit(commit_msg) end end
Checks for changes add/delete/modified
# File lib/grit_adapter/file_access.rb, line 142 def changed? !(changed_files() + deleted_files).empty? end
# File lib/grit_adapter/file_access.rb, line 91 def changed_files() # NOTE: There is issue with grit and git. Where grit.status will report file changed (modified) # and git status will not. Grit registers changing file time-stamp as change while git doesn't. This would # not be a problem but `git push` will fail because of this. Following is fix for that. output = git_command_status() grit_files = @grit_repo.status.files.select { |k,v| (v.type =~ /(A|M)/ || v.untracked) } changed_files = grit_files.select do |file| file_name = file.instance_of?(String) ? file : file.first filter_file_through_status_output(file_name,output) end # returns array of arrays (first element name of file) changed_files.to_a end
# File lib/grit_adapter/file_access.rb, line 164 def commit(commit_msg,opts={}) cmd_args = [:commit,"-a","-m",commit_msg] author = "#{opts[:author_username]||DefaultAuthor[:username]} <#{opts[:author_email]||DefaultAuthor[:email]}>" cmd_args += ["--author",author] chdir_and_checkout do #note using following because silent failure @grit_repo.commit_all(commit_msg) git_command(*cmd_args) end end
# File lib/grit_adapter/file_access.rb, line 123 def deleted_files() # returns array of arrays (first element name of file) @grit_repo.status.deleted().to_a end
# File lib/grit_adapter/file_access.rb, line 65 def fetch(remote=nil) remote ||= default_remote() chdir do git_command(:fetch,remote) end end
# File lib/grit_adapter/file_access.rb, line 232 def find_remote_sha(ref) remote = @grit_repo.remotes.find{|r|r.name == ref} remote && remote.commit.id end
# File lib/grit_adapter/file_access.rb, line 228 def head_commit_sha() head = @grit_repo.heads.find{|r|r.name == @branch} head && head.commit.id end
# File lib/grit_adapter/file_access.rb, line 85 def merge(remote_branch_ref) chdir_and_checkout do git_command(:merge,remote_branch_ref) end end
# File lib/grit_adapter/file_access.rb, line 74 def merge_theirs(remote_branch_ref) #since there is no 'git merge -s theirs' we need to simulate it chdir do git_command(:checkout,"-b",TempBranch,remote_branch_ref) git_command(:merge,@branch,"-s","ours") git_command(:checkout,@branch) git_command(:reset,"--hard",TempBranch) git_command(:branch,"-D",TempBranch) end end
# File lib/grit_adapter/file_access.rb, line 128 def print_status() changes = [@grit_repo.status.changed(), @grit_repo.status.untracked(), @grit_repo.status.deleted()] puts "\nModified files:\n".colorize(:green) unless changes[0].empty? changes[0].each { |item| puts "\t#{item.first}" } puts "\nAdded files:\n".colorize(:yellow) unless changes[1].empty? changes[1].each { |item| puts "\t#{item.first}" } puts "\nDeleted files:\n".colorize(:red) unless changes[2].empty? changes[2].each { |item| puts "\t#{item.first}" } puts "" end
# File lib/grit_adapter/file_access.rb, line 58 def pull(remote_branch,local_branch,remote=nil) remote ||= default_remote() chdir do git_command(:pull,remote,"#{remote_branch}:#{local_branch}") end end
# File lib/grit_adapter/file_access.rb, line 252 def remove_branch(branch) checkout_branch = @branch chdir_and_checkout(checkout_branch,:stay_on_checkout_branch => true) do git_command(:branch,"-d",branch) end.first end
# File lib/grit_adapter/file_access.rb, line 247 def remove_branch?(branch) if branches().include?(branch) remove_branch(branch) end end
# File lib/grit_adapter/file_access.rb, line 49 def remove_file(file_rel_path) file_path = qualified_path(file_rel_path) chdir_and_checkout do if File.exists?(file_path) git_command(:rm,file_path) end end end
returns :equal, :local_behind, :local_ahead, or :branchpoint type can be :remote_branch or :local_branch
# File lib/grit_adapter/file_access.rb, line 180 def ret_merge_relationship(type,ref,opts={}) if (type == :remote_branch and opts[:fetch_if_needed]) #TODO: this fetches all branches on the remote; see if anyway to just fetch a specfic branch #ref will be of form remote_name/branch #TODO: also see if more efficient to use git ls-remote fetch(ref.split("/").first) end other_grit_ref = case type when :remote_branch @grit_repo.remotes.find{|r|r.name == ref} when :local_branch @grit_repo.heads.find{|r|r.name == ref} else raise Error.new("Illegal type parameter (#{type}) passed to ret_merge_relationship") end local_sha = head_commit_sha() if opts[:ret_commit_shas] opts[:ret_commit_shas][:local_sha] = local_sha end unless other_grit_ref if type == :remote_branch return :no_remote_ref end raise Error.new("Cannot find git ref (#{ref})") end other_sha = other_grit_ref.commit.id if opts[:ret_commit_shas] opts[:ret_commit_shas][:other_sha] = other_sha end if other_sha == local_sha :equal else #shas can be different but they can have same content so do a git diff unless any_diffs?(local_sha,other_sha) return :equal end #TODO: see if missing or mis-categorizing any condition below if git_command__rev_list_contains?(local_sha,other_sha) then :local_ahead elsif git_command__rev_list_contains?(other_sha,local_sha) then :local_behind else :branchpoint end end end
Private Instance Methods
TODO: would like more efficient way of doing this as opposed to below which first produces object with full diff as opposed to summary
# File lib/grit_adapter/file_access.rb, line 286 def any_diffs?(ref1,ref2) not @grit_repo.diff(ref1,ref2).empty? end
# File lib/grit_adapter/file_access.rb, line 305 def chdir(&block) unless File.directory?(@repo_dir) raise Error.new("Trying to chdir to directory (#{@repo_dir}) that does not exist") end Dir.chdir(@repo_dir){yield} end
TODO: may determine where –git-dir option makes an actual chdir unnecssary
# File lib/grit_adapter/file_access.rb, line 291 def chdir_and_checkout(branch=nil,opts={},&block) branch ||= @branch chdir do current_head = @grit_repo.head.name git_command(:checkout,branch) unless current_head == branch return unless block ret = yield unless opts[:stay_on_checkout_branch] or (current_head == branch) git_command(:checkout,current_head) end ret end end
# File lib/grit_adapter/file_access.rb, line 272 def default_remote() "origin" end
TODO: see if we can do away with this
# File lib/grit_adapter/file_access.rb, line 107 def filter_file_through_status_output(file_name,output) #need to search for both filename and whether dircetory added if output.include?(file_name) true else file_parts = file_name.split('/') file_parts.pop while not file_parts.empty? do return true if output.include?(file_parts.join('/')+'/') file_parts.pop end false end end
# File lib/grit_adapter/file_access.rb, line 43 def git_command__add(file_path) #put in -f to avoid error being thrown if try to add an ignored file git_command(:add,file_path,"-f") end
# File lib/grit_adapter/file_access.rb, line 280 def git_command__rev_list_contains?(container_sha,index_sha) rev_list = git_command(:rev_list,container_sha) !rev_list.split("\n").grep(index_sha).empty?() end
There is issue with Grit 1.8.7 and 1.9.3 version have diffrent returns on changed/deleted files
1.8.7 => Returns array of arrays where file name is first elemenet 1.9.3 => Returns hash where keys are file names
No need for it now, but when refactoring code use this instead of .to_a fix
# File lib/grit_adapter/file_access.rb, line 268 def grit_compability_transform(grit_files) grit_files.instance_of?(Hash) ? grit_files.keys : grit_files.collect { |element| element.first } end
# File lib/grit_adapter/file_access.rb, line 276 def qualified_path(file_rel_path) "#{@repo_dir}/#{file_rel_path}" end