lib/gitdocs/repository/committer.rb
# -*- encoding : utf-8 -*-
module Gitdocs
class Repository
class Committer
# @raise if the repository is not valid for commits
def initialize(root_dirname)
@root_dirname = root_dirname
@rugged = Rugged::Repository.new(root_dirname)
@grit = Grit::Repo.new(root_dirname)
@commit_message_path = File.expand_path('.gitmessage~', root_dirname)
rescue Rugged::OSError
raise(Gitdocs::Repository::InvalidError, 'No directory')
rescue Rugged::RepositoryError
raise(Gitdocs::Repository::InvalidError, 'Not a repository')
end
# @return [Boolean]
def commit
# Do this first to allow the message file to be deleted, if it exists.
message = read_and_delete_commit_message_file
mark_empty_directories
# FIXME: Consider a more appropriate location for the dirty check.
return false unless Gitdocs::Repository.new(@root_dirname).dirty?
Gitdocs.log_debug("Repo #{@root_dirname} is dirty")
# Commit any changes in the working directory.
Dir.chdir(@root_dirname) do
@rugged.index.add_all
@rugged.index.update_all
end
@rugged.index.write
Gitdocs.log_debug("Index to be committed #{@rugged.index}")
commit_result = @grit.commit_index(message)
Gitdocs.log_debug("Commit result: <#{commit_result.inspect}>")
true
end
# @param [String] message
# @return [void]
def write_commit_message(message)
return unless message
return if message.empty?
File.open(@commit_message_path, 'w') { |f| f.print(message) }
end
##########################################################################
private
def mark_empty_directories
Find.find(@root_dirname).each do |path|
Find.prune if File.basename(path) == '.git'
if File.directory?(path) && Dir.entries(path).count == 2
FileUtils.touch(File.join(path, '.gitignore'))
end
end
end
# @return [String] either the message in the file, or the regular
# automatic commit message.
def read_and_delete_commit_message_file
return(
'Auto-commit from gitdocs'
) unless File.exist?(@commit_message_path)
message = File.read(@commit_message_path)
File.delete(@commit_message_path)
message
end
end
end
end