diff --git a/.gitattributes b/.gitattributes
index d959918c706fb07061222cdd70df9dd954bae29a..38291609ee734bfcc74861c32fd419a3e293b970 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,6 +1,13 @@
 .gitattributes   export-ignore
 .hooks*          export-ignore
 
+# Custom attribute to mark sources as using our C code style.
+[attr]our-c-style  whitespace=tab-in-indent  format.clang-format
+
+# Custom attribute to mark sources as generated.
+# Do not perform whitespace checks.  Do not format.
+[attr]generated  whitespace=-tab-in-indent,-indent-with-non-tab -format.clang-format
+
 bootstrap        crlf=input
 configure        crlf=input
 *.[1-9]          crlf=input
@@ -16,10 +23,17 @@ configure        crlf=input
 *.sln           -crlf
 *.vcproj        -crlf
 
-*.c              whitespace=tab-in-indent
-*.h              whitespace=tab-in-indent
-*.cxx            whitespace=tab-in-indent
-*.txt            whitespace=tab-in-indent
-*.cmake          whitespace=tab-in-indent
+*.c              our-c-style
+*.cc             our-c-style
+*.cpp            our-c-style
+*.cu             our-c-style
+*.cxx            our-c-style
+*.h              our-c-style
+*.hh             our-c-style
+*.hpp            our-c-style
+*.hxx            our-c-style
+*.notcu          our-c-style
 
+*.cmake          whitespace=tab-in-indent
 *.rst            whitespace=tab-in-indent conflict-marker-size=79
+*.txt            whitespace=tab-in-indent
diff --git a/Source/.gitattributes b/Source/.gitattributes
index dbd6382cafdc4c24577ec7b464533d8b59ffc36e..1cec8a338e47991fc628ac506bf81cc3d6bbc989 100644
--- a/Source/.gitattributes
+++ b/Source/.gitattributes
@@ -1,10 +1,21 @@
-# Preserve indentation style in generated code.
-cmCommandArgumentLexer.cxx      whitespace=-tab-in-indent,-indent-with-non-tab
-cmCommandArgumentLexer.h        whitespace=-tab-in-indent,-indent-with-non-tab
-cmDependsJavaLexer.cxx          whitespace=-tab-in-indent,-indent-with-non-tab
-cmDependsJavaLexer.h            whitespace=-tab-in-indent,-indent-with-non-tab
-cmExprLexer.cxx                 whitespace=-tab-in-indent,-indent-with-non-tab
-cmExprLexer.h                   whitespace=-tab-in-indent,-indent-with-non-tab
-cmFortranLexer.cxx              whitespace=-tab-in-indent,-indent-with-non-tab
-cmFortranLexer.h                whitespace=-tab-in-indent,-indent-with-non-tab
-cmListFileLexer.c               whitespace=-tab-in-indent,-indent-with-non-tab
+/cmCommandArgumentLexer.cxx        generated
+/cmCommandArgumentLexer.h          generated
+/cmCommandArgumentParser.cxx       generated
+/cmCommandArgumentParserTokens.h   generated
+/cmDependsJavaLexer.cxx            generated
+/cmDependsJavaLexer.h              generated
+/cmDependsJavaParser.cxx           generated
+/cmDependsJavaParserTokens.h       generated
+/cmExprLexer.cxx                   generated
+/cmExprLexer.h                     generated
+/cmExprParser.cxx                  generated
+/cmExprParserTokens.h              generated
+/cmFortranLexer.cxx                generated
+/cmFortranLexer.h                  generated
+/cmFortranParser.cxx               generated
+/cmFortranParserTokens.h           generated
+/cmListFileLexer.c                 generated
+
+# Do not format third-party sources.
+/bindexplib.*                              -format.clang-format
+/kwsys/**                                  -format.clang-format
diff --git a/Source/CursesDialog/form/.gitattributes b/Source/CursesDialog/form/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..62d728cf660db7ab698ee5e9ea197e2694495907
--- /dev/null
+++ b/Source/CursesDialog/form/.gitattributes
@@ -0,0 +1 @@
+* -format.clang-format
diff --git a/Tests/CompileFeatures/.gitattributes b/Tests/CompileFeatures/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..83da28dac3d75bce2595dc8ae3e03c8ad4fa2e17
--- /dev/null
+++ b/Tests/CompileFeatures/.gitattributes
@@ -0,0 +1,2 @@
+# Do not format a source containing C++11 '>>' syntax as C++98.
+cxx_right_angle_brackets.cpp -format.clang-format
diff --git a/Tests/PositionIndependentTargets/.gitattributes b/Tests/PositionIndependentTargets/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..ed36631f4535b0e75e143e2b17beedd21991f33f
--- /dev/null
+++ b/Tests/PositionIndependentTargets/.gitattributes
@@ -0,0 +1,2 @@
+# Do not format a source where we want a long line preserved.
+pic_test.h -format.clang-format
diff --git a/Tests/RunCMake/CommandLine/cmake_depends/.gitattributes b/Tests/RunCMake/CommandLine/cmake_depends/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..9c22288cd8ad9e2a8b8883c8b82468f916c5df58
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/cmake_depends/.gitattributes
@@ -0,0 +1,2 @@
+# Do not format a source encoded in UTF-16.
+test_UTF-16LE.h -format.clang-format
diff --git a/Tests/RunCMake/GenerateExportHeader/reference/.gitattributes b/Tests/RunCMake/GenerateExportHeader/reference/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..883a7f16da27f623143243115e1215967d3d3c97
--- /dev/null
+++ b/Tests/RunCMake/GenerateExportHeader/reference/.gitattributes
@@ -0,0 +1,2 @@
+# Exclude reference content from formatting.
+* -format.clang-format
diff --git a/Utilities/.gitattributes b/Utilities/.gitattributes
index c6345eb29a3d08fba6517967c2c3a229bc039321..bd978021ba50a9cb39e8a8a5a233d6ed80d06067 100644
--- a/Utilities/.gitattributes
+++ b/Utilities/.gitattributes
@@ -1,3 +1,7 @@
 /Git                    export-ignore
 /GitSetup               export-ignore
 SetupForDevelopment.sh  export-ignore
+
+# Do not format third-party sources.
+/KWIML/**       -format.clang-format
+/cm*/**         -format.clang-format
diff --git a/Utilities/Scripts/clang-format.bash b/Utilities/Scripts/clang-format.bash
index 2b36ac5dd97c052f856904758a02a2f7a46edc23..edcda77b933ad0050bec391561de5997bb1a9941 100755
--- a/Utilities/Scripts/clang-format.bash
+++ b/Utilities/Scripts/clang-format.bash
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 #=============================================================================
-# Copyright 2015-2016 Kitware, Inc.
+# Copyright 2015-2017 Kitware, Inc.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -106,34 +106,12 @@ case "$mode" in
     *) die "invalid mode: $mode" ;;
 esac
 
-# Filter sources to which our style should apply.
-$git_ls -z -- '*.c' '*.cc' '*.cpp' '*.cxx' '*.h' '*.hh' '*.hpp' '*.hxx' '*.cu' '*.notcu' |
+# List files as selected above.
+$git_ls |
 
-  # Exclude lexer/parser generator input and output.
-  egrep -z -v '^Source/cmCommandArgumentLexer\.' |
-  egrep -z -v '^Source/cmCommandArgumentParser(\.y|\.cxx|Tokens\.h)' |
-  egrep -z -v '^Source/cmDependsJavaLexer\.' |
-  egrep -z -v '^Source/cmDependsJavaParser(\.y|\.cxx|Tokens\.h)' |
-  egrep -z -v '^Source/cmExprLexer\.' |
-  egrep -z -v '^Source/cmExprParser(\.y|\.cxx|Tokens\.h)' |
-  egrep -z -v '^Source/cmFortranLexer\.' |
-  egrep -z -v '^Source/cmFortranParser(\.y|\.cxx|Tokens\.h)' |
-  egrep -z -v '^Source/cmListFileLexer(\.in\.l|\.c)' |
-
-  # Exclude third-party sources.
-  egrep -z -v '^Source/bindexplib' |
-  egrep -z -v '^Source/(kwsys|CursesDialog/form)/' |
-  egrep -z -v '^Utilities/(KW|cm).*/' |
-
-  # Exclude reference content.
-  egrep -z -v '^Tests/RunCMake/GenerateExportHeader/reference/' |
-
-  # Exclude manually-formatted sources (e.g. with long lines).
-  egrep -z -v '^Tests/PositionIndependentTargets/pic_test.h' |
-  egrep -z -v '^Tests/CompileFeatures/cxx_right_angle_brackets.cpp' |
-
-  # Exclude sources with encoding not suported by clang-format.
-  egrep -z -v '^Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h' |
+  # Select sources with our attribute.
+  git check-attr --stdin format.clang-format |
+  sed -n '/: format\.clang-format: set$/ {s/:[^:]*:[^:]*$//p}'  |
 
   # Update sources in-place.
-  xargs -0 "$clang_format" -i
+  xargs -d '\n' "$clang_format" -i