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

add_branch(branch) click to toggle source
# File lib/grit_adapter/file_access.rb, line 242
def add_branch(branch)
  chdir_and_checkout() do 
    git_command(:branch,branch)
  end
end
add_branch?(branch) click to toggle source
# File lib/grit_adapter/file_access.rb, line 237
def add_branch?(branch)
  unless branches().include?(branch)
    add_branch(branch)
  end
end
add_file(file_rel_path, content=nil) click to toggle source
# 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
add_file_command(file_rel_path) click to toggle source
# 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
add_remove_commit_all(commit_msg) click to toggle source

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
changed?() click to toggle source

Checks for changes add/delete/modified

# File lib/grit_adapter/file_access.rb, line 142
def changed?
  !(changed_files() + deleted_files).empty?
end
changed_files() click to toggle source
# 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
commit(commit_msg,opts={}) click to toggle source
# 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
deleted_files() click to toggle source
# 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
fetch(remote=nil) click to toggle source
# File lib/grit_adapter/file_access.rb, line 65
def fetch(remote=nil)
  remote ||= default_remote()
  chdir do
    git_command(:fetch,remote)
  end
end
find_remote_sha(ref) click to toggle source
# 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
head_commit_sha() click to toggle source
# 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
merge(remote_branch_ref) click to toggle source
# 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
merge_theirs(remote_branch_ref) click to toggle source
# 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
print_status() click to toggle source
pull(remote_branch,local_branch,remote=nil) click to toggle source
# 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
remove_branch(branch) click to toggle source
# 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
remove_branch?(branch) click to toggle source
# File lib/grit_adapter/file_access.rb, line 247
def remove_branch?(branch)
  if branches().include?(branch)
    remove_branch(branch)
  end
end
remove_file(file_rel_path) click to toggle source
# 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
ret_merge_relationship(type,ref,opts={}) click to toggle source

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

any_diffs?(ref1,ref2) click to toggle source

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
chdir() { || ... } click to toggle source
# 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
chdir_and_checkout(branch=nil,opts={}) { || ... } click to toggle source

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
default_remote() click to toggle source
# File lib/grit_adapter/file_access.rb, line 272
def default_remote()
  "origin"
end
filter_file_through_status_output(file_name,output) click to toggle source

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
git_command__add(file_path) click to toggle source
# 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
git_command__rev_list_contains?(container_sha,index_sha) click to toggle source
# 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
grit_compability_transform(grit_files) click to toggle source

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
qualified_path(file_rel_path) click to toggle source
# File lib/grit_adapter/file_access.rb, line 276
def qualified_path(file_rel_path)
  "#{@repo_dir}/#{file_rel_path}"
end