Don't parse the same .bazelrc file more than once. The old behavior is problematic if a .bazelrc file specifies an option that is allowed to be repeated, duplicates of that option are problematic (one example is http://bazel.io/docs/bazel-user-manual.html#flag--per_file_copt).

--
MOS_MIGRATED_REVID=110689696
diff --git a/src/main/cpp/option_processor.cc b/src/main/cpp/option_processor.cc
index 209c9a0..a71b565 100644
--- a/src/main/cpp/option_processor.cc
+++ b/src/main/cpp/option_processor.cc
@@ -20,6 +20,7 @@
 #include <unistd.h>
 #include <algorithm>
 #include <cassert>
+#include <set>
 #include <utility>
 
 #include "src/main/cpp/blaze_util.h"
@@ -29,6 +30,7 @@
 
 using std::list;
 using std::map;
+using std::set;
 using std::vector;
 
 // On OSX, there apparently is no header that defines this.
@@ -278,37 +280,13 @@
   }
 
   // Parse depot and user blazerc files.
-  // This is not a little ineffective (copying a multimap around), but it is a
+  // This is a little inefficient (copying a multimap around), but it is a
   // small one and this way I don't have to care about memory management.
+  vector<string> candidate_blazerc_paths;
   if (use_master_blazerc) {
-    string depot_blazerc_path = FindDepotBlazerc(workspace);
-    if (!depot_blazerc_path.empty()) {
-      blazercs_.push_back(new RcFile(depot_blazerc_path, blazercs_.size()));
-      blaze_exit_code::ExitCode parse_exit_code =
-          blazercs_.back()->Parse(workspace, &blazercs_, &rcoptions_, error);
-      if (parse_exit_code != blaze_exit_code::SUCCESS) {
-        return parse_exit_code;
-      }
-    }
-    string alongside_binary_blazerc = FindAlongsideBinaryBlazerc(cwd, args[0]);
-    if (!alongside_binary_blazerc.empty()) {
-      blazercs_.push_back(new RcFile(alongside_binary_blazerc,
-          blazercs_.size()));
-      blaze_exit_code::ExitCode parse_exit_code =
-          blazercs_.back()->Parse(workspace, &blazercs_, &rcoptions_, error);
-      if (parse_exit_code != blaze_exit_code::SUCCESS) {
-        return parse_exit_code;
-      }
-    }
-    string system_wide_blazerc = FindSystemWideBlazerc();
-    if (!system_wide_blazerc.empty()) {
-      blazercs_.push_back(new RcFile(system_wide_blazerc, blazercs_.size()));
-      blaze_exit_code::ExitCode parse_exit_code =
-          blazercs_.back()->Parse(workspace, &blazercs_, &rcoptions_, error);
-      if (parse_exit_code != blaze_exit_code::SUCCESS) {
-        return parse_exit_code;
-      }
-    }
+    candidate_blazerc_paths.push_back(FindDepotBlazerc(workspace));
+    candidate_blazerc_paths.push_back(FindAlongsideBinaryBlazerc(cwd, args[0]));
+    candidate_blazerc_paths.push_back(FindSystemWideBlazerc());
   }
 
   string user_blazerc_path;
@@ -318,12 +296,22 @@
   if (find_blazerc_exit_code != blaze_exit_code::SUCCESS) {
     return find_blazerc_exit_code;
   }
-  if (!user_blazerc_path.empty()) {
-    blazercs_.push_back(new RcFile(user_blazerc_path, blazercs_.size()));
-    blaze_exit_code::ExitCode parse_exit_code =
-        blazercs_.back()->Parse(workspace, &blazercs_, &rcoptions_, error);
-    if (parse_exit_code != blaze_exit_code::SUCCESS) {
-      return parse_exit_code;
+  candidate_blazerc_paths.push_back(user_blazerc_path);
+
+  // Throw away missing files, dedupe candidate blazerc paths, and parse the
+  // blazercs, all while preserving order. Duplicates can arise if e.g. the
+  // binary's path *is* the depot path.
+  set<string> blazerc_paths;
+  for (const auto& candidate_blazerc_path : candidate_blazerc_paths) {
+    if (!candidate_blazerc_path.empty()
+        && (blazerc_paths.insert(candidate_blazerc_path).second)) {
+      blazercs_.push_back(
+          new RcFile(candidate_blazerc_path, blazercs_.size()));
+      blaze_exit_code::ExitCode parse_exit_code =
+          blazercs_.back()->Parse(workspace, &blazercs_, &rcoptions_, error);
+      if (parse_exit_code != blaze_exit_code::SUCCESS) {
+        return parse_exit_code;
+      }
     }
   }