Index: Gruntfile.js
===================================================================
--- Gruntfile.js	(revision 37156)
+++ Gruntfile.js	(working copy)
@@ -1,7 +1,8 @@
-/* jshint node:true */
+'use strict';
+
 module.exports = function(grunt) {
 	var path = require('path'),
-		gitorsvn = require('git-or-svn'),
+		fs = require( 'fs' ),
 		SOURCE_DIR = 'src/',
 		BUILD_DIR = 'build/',
 		autoprefixer = require('autoprefixer'),
@@ -295,6 +296,11 @@
 		jshint: {
 			options: grunt.file.readJSON('.jshintrc'),
 			grunt: {
+				options: {
+					es3: false,
+					esversion: 6,
+					node: true
+				},
 				src: ['Gruntfile.js']
 			},
 			tests: {
@@ -689,57 +695,55 @@
 
 	grunt.registerTask( 'precommit', 'Runs test and build tasks in preparation for a commit', function() {
 		var done = this.async();
-
-		// Figure out what tasks to run based on what files have been modified.
-		function enqueueTestingTasksForModifiedFiles( filesModified ) {
-			var taskList = ['precommit:base'];
-			if ( /.*\.js/.test( filesModified ) ) {
-				grunt.log.write( 'JavaScript source files modified. JavaScript tests will be run.\n');
-				taskList = taskList.concat( ['precommit:js'] );
-			}
-			if ( /src.*\.css/.test( filesModified ) ) {
-				grunt.log.write( 'CSS source files modified. CSS tests will be run.\n');
-				taskList = taskList.concat( ['postcss:core'] );
-			}
-			if ( /.*\.php/.test( filesModified ) ) {
-				grunt.log.write( 'PHP source files modified. PHP tests will be run.\n');
-				taskList = taskList.concat( ['precommit:php'] );
+		var map = {
+			svn: 'svn status --ignore-externals',
+			git: 'git status -s'
+		};
+
+		find( [
+			__dirname + '/.svn',
+			__dirname + '/.git',
+			path.dirname( __dirname ) + '/.svn'
+		] );
+
+		function find( set ) {
+			if ( set.length ) {
+				let dir = set.shift();
+
+				fs.access( dir, fs.F_OK, ( error ) => {
+					error ? find( set ) : run( path.basename( dir ).substr( 1 ) );
+				} );
+			} else {
+				grunt.fatal( 'This WordPress install is not under version control.' );
 			}
-			grunt.task.run( taskList );
-			done();
 		}
-		gitorsvn( __dirname, function(gitorsvn) {
-			if ( gitorsvn === 'svn' ) {
-				grunt.util.spawn(
-					{
-						cmd: 'svn',
-						args: ['status']
-					},
-					function(error, result, code) {
-						if ( code !== 0 ) {
-							grunt.fail.warn( 'The `svn status` command returned a non-zero exit code.', code );
-						}
-						enqueueTestingTasksForModifiedFiles( result.stdout );
-					}
-				);
-			} else if ( gitorsvn === 'git' ) {
-				grunt.util.spawn(
-					{
-						cmd: 'git',
-						args: ['diff', '--name-only']
-					},
-					function(error, result, code) {
-						if ( code !== 0 ) {
-							grunt.fail.warn( 'The `git diff --name-only` command returned a non-zero exit code.', code );
-						}
-						enqueueTestingTasksForModifiedFiles( result.stdout );
+
+		function run( type ) {
+			var command = map[ type ].split( ' ' );
+
+			grunt.util.spawn( {
+				cmd: command.shift(),
+				args: command
+			}, ( error, result, code ) => {
+				let taskList = [ 'precommit:base' ];
+
+				if ( code !== 0 ) {
+					grunt.fatal( 'The `' +  map[ type ] + '` command returned a non-zero exit code.', code );
+				}
+
+				[ 'js', 'css', 'php' ].forEach( function( extension ) {
+					if ( ( result.stdout + '\n' ).indexOf( '.' + extension + '\n' ) !== -1 ) {
+						grunt.log.writeln( extension.toUpperCase() + ' files modified. ' + extension.toUpperCase() + ' tests will be run.');
+						taskList.push( 'precommit:' + extension );
 					}
-				);
-			} else {
-				grunt.log.write( 'This WordPress install is not under version control. No tests will be run.' );
-			}
-		});
-	});
+				} );
+
+				grunt.task.run( taskList );
+
+				done();
+			} );
+		}
+	} );
 
 	grunt.registerTask( 'copy:all', [
 		'copy:files',
Index: package.json
===================================================================
--- package.json	(revision 37156)
+++ package.json	(working copy)
@@ -10,7 +10,6 @@
   "license": "GPL-2.0+",
   "devDependencies": {
     "autoprefixer": "~6.3.3",
-    "git-or-svn": "~0.1.0",
     "grunt": "~0.4.5",
     "grunt-browserify": "~5.0.0",
     "grunt-contrib-clean": "~1.0.0",
