require 'build-tool/vcs/base' require 'build-tool/errors' module BuildTool; module VCS class GitError < BuildTool::Error; end class GitConfiguration < BaseConfiguration def name "git" end attr_accessor :remote def initialize( mod = nil ) super( mod ) @remote = {} end def vcs( mod ) @module = mod Git.new( self ) end def track_remote rc = self.module.remote_path.split('/') # If there is only one string we assume it is the branch name from # origin return "origin" if rc.length == 1 return rc[0] end def track_branch rc = self.module.remote_path.split('/') # If there is only one string we assume it is the branch name from # origin return rc[0] if rc.length == 1 return rc[1..-1].join( '/' ) end end # # Implementation for the git version control system. # class Git < Base def initialize( config ) super( config ) @remote = {} @vcs = nil end # ### ATTRIBUTES # def name "git" end def fetching_supported? true end # ### METHODS # def checkedout? return false if !local_path_exist? if !Pathname.new( local_path ).join( ".git" ).exist? raise Base::VcsError, "Checkout path #{local_path} is not a git repo!" end return true end # Initialize the local repository def clone # Check if path exists if local_path_exist? raise GitError, "Failed to create repository at '#{local_path}': Path exists" end # Create the directory FileUtils.mkdir_p( local_path ) if !$noop # Initialize the repository if git( "init", local_path ) != 0 raise GitError, "Error while initializing the repo `git init #{local_path}'`: #{$?}" end config.remote.each do |name, val| if git( "remote add #{name} #{val.url}" ) != 0 raise GitError, "Error while initializing the repo `git remote add #{name} #{val.url}`: #{$?}" end end cmd = "remote add origin #{repository.url}" if git( cmd, local_path ) != 0 raise GitError, "Error while initializing the repo `#{cmd}`: #{$?}" end logger.info <<-EOS The following command sometimes fails when issued from this script. Reason unknown. The best chance you have is issuing the command manually! #{local_path}: #{cmd} #{local_path}: git checkout -b #{config.track_branch} #{config.track_remote}/#{config.track_branch} EOS fetch() cmd = "checkout -b #{config.track_branch} #{config.track_remote}/#{config.track_branch}" if git( cmd, local_path ) != 0 raise GitError, "Error while initializing the repo `#{cmd}`: #{$?}" end end def remote?( name ) found = false git( "remote" ) do |line| found = true if line == name end return found end # Fetch from +repository+ # # Initializes the local clone if it does not exist. def fetch() if !checkedout? and !$noop clone end cmd = "fetch #{config.track_remote}" if ( rc = git( cmd ) ) != 0 raise GitError, "Error while fetching: #{rc}" end end def git( command, wd = local_path, &block ) rc = self.class.execute "git #{command}", wd, &block if rc != 0 raise GitError, "git #{command || "" } failed with error code #{rc}"; end rc end def rebase if 0 != ( git "rebase #{config.track_remote}/#{config.track_branch}" ) raise GitSvnError, "Error while rebasing the repo with `git rebase git-svn: #{$?}" end end end # class Git class GitRemote attr_accessor :server attr_accessor :path attr_reader :name def initialize( name ) @name = name @path = nil end def url url = "" if @server url = @server.url end if @path url = "#{url}/#{path}" end url end def to_s "REMOTE: #{name} #{url}" end end # class Remote end; end # module BuildTool::VCS