docs: function publish(target, data, done) {
          if(data.enabled !== true)
              return grunt.fail.fatal('publishing is disabled; set "publish.enabled" to true to enable');
  
          if(!data.path)
              return grunt.fail.fatal('the "publish.path" attribute must be provided for the publish task');
  
          if(!data.message)
              return grunt.fail.fatal('the "publish.message" attribute must be provided for the publish task');
  
          /**
           * provide the defaults for the git commands.  by default, we are assuming the markdown repo is stored
           * in a separate directory, so our git commands need to support that...provide the git-dir and work-tree
           * paths.  the standard publish process is:
           *
           * git add .
           * git commit -m <configured commit message>
           * git push <remoteName> <remoteBranch> (defaults to upstream master)
           *
           */
          _.defaults(data, {
              addCmd: ['--git-dir='+ data.path +'/.git', '--work-tree='+ data.path, 'add', '.'],
              commitCmd: ['--git-dir='+ data.path +'/.git', '--work-tree='+ data.path, 'commit', '-m', data.message],
              pushCmd: ['--git-dir='+ data.path +'/.git', '--work-tree='+ data.path, 'push', data.remoteName || 'upstream', data.remoteBranch || 'master']
          });
  
          //run the git commands, using promises to handle when complete
          function cmd(args) {
              var def = Q.defer();
              grunt.util.spawn({ cmd: 'git', args: args }, def.resolve);
              return def.promise;
          }
  
          //add, commit, and publish the doc repository
          cmd(data.addCmd)
              .then(cmd.bind(this, data.commitCmd))
              .then(cmd.bind(this, data.pushCmd))
              .then(done);
      }