# File lib/grit/git.rb, line 270
    def native(cmd, options = {}, *args, &block)
      args     = args.first if args.size == 1 && args[0].is_a?(Array)
      args.map!    { |a| a.to_s.strip }
      args.reject! { |a| a.empty? }

      # special option arguments
      env = options.delete(:env) || {}
      raise_errors = options.delete(:raise)

      # fall back to using a shell when the last argument looks like it wants to
      # start a pipeline for compatibility with previous versions of grit.
      return run(prefix, cmd, '', options, args) if args[-1].to_s[0] == ?|

      # more options
      input    = options.delete(:input)
      timeout  = options.delete(:timeout); timeout = true if timeout.nil?
      base     = options.delete(:base);    base    = true if base.nil?
      chdir    = options.delete(:chdir)

      # build up the git process argv
      argv = []
      argv << Git.git_binary
      argv << "--git-dir=#{git_dir}" if base
      argv << cmd.to_s.tr('_', '-')
      argv.concat(options_to_argv(options))
      argv.concat(args)

      # run it and deal with fallout
      Grit.log(argv.join(' ')) if Grit.debug

      process =
        Grit::Process.new(argv, env,
          :input   => input,
          :chdir   => chdir,
          :timeout => (Grit::Git.git_timeout if timeout == true),
          :max     => (Grit::Git.git_max_size if timeout == true)
        )
      status = process.status
      Grit.log(process.out) if Grit.debug
      Grit.log(process.err) if Grit.debug
      if raise_errors && !status.success?
        raise CommandFailed.new(argv.join(' '), status.exitstatus, process.err)
      else
        process.out
      end
    rescue Grit::Process::TimeoutExceeded, Grit::Process::MaximumOutputExceeded
      raise GitTimeout, argv.join(' ')
    end