For Sitecore, we all love the web.config include patching functionality, which makes the whole configuration management much easier. However earlier today it took me a bit of time to figure out an issue when I tried to overwrite a patch with another patch.
Scenario:
In Include folder, there's a zzz_WebsiteName folder and a zzz folder. Patch A is inside of zzz_WebsiteName, I created another patch B which is to remove part of what Patch A applied. So this means patch B only works when it's applied after Patch A is applied.
  • I placed patch B inside zzz folder, it didn't work. I expect this, it's fine.
  • I placed patch B inside zzz_WebsiteName folder, it worked. I expect this, all good.
  • I placed patch B inside zzzz folder, it didn't work. Not good.
  • I placed patch B inside ZZZZ folder, didn't work either.
So I went ahead and checked the source code where Sitecore looks for the config files in Include folder:

private static void LoadAutoIncludeFiles(ConfigPatcher patcher, string folder)
    {
      Assert.ArgumentNotNull((object) patcher, "patcher");
      Assert.ArgumentNotNull((object) folder, "folder");
      try
      {
        if (!Directory.Exists(folder))
          return;
        foreach (string str in Directory.GetFiles(folder, "*.config"))
        {
          try
          {
            if ((File.GetAttributes(str) & FileAttributes.Hidden) == (FileAttributes) 0)
              patcher.ApplyPatch(str);
          }
          catch (Exception ex)
          {
            Log.Error(string.Concat(new object[4]
            {
              (object) "Could not load configuration file: ",
              (object) str,
              (object) ": ",
              (object) ex
            }), typeof (Factory));
          }
        }
        foreach (string str in Directory.GetDirectories(folder))
        {
          try
          {
            if ((File.GetAttributes(str) & FileAttributes.Hidden) == (FileAttributes) 0)
              Factory.LoadAutoIncludeFiles(patcher, str);
          }
          catch (Exception ex)
          {
            Log.Error(string.Concat(new object[4]
            {
              (object) "Could not scan configuration folder ",
              (object) str,
              (object) " for files: ",
              (object) ex
            }), typeof (Factory));
          }
        }
      }
      catch (Exception ex)
      {
        Log.Error(string.Concat(new object[4]
        {
          (object) "Could not scan configuration folder ",
          (object) folder,
          (object) " for files: ",
          (object) ex
        }), typeof (Factory));
      }
    }

Actually it all looks fine, so it process files in Include folder first, then go through every folder in order.
However the key thing here is this line:

Directory.GetDirectories(folder)

When I ran it on my machine, it returned this(I created some folder to test):

C:\Sitecore\sc80rev150621\Website\App_Config\Include\Channel
C:\Sitecore\sc80rev150621\Website\App_Config\Include\ContentTesting
C:\Sitecore\sc80rev150621\Website\App_Config\Include\ExperienceAnalytics
C:\Sitecore\sc80rev150621\Website\App_Config\Include\ExperienceProfile
C:\Sitecore\sc80rev150621\Website\App_Config\Include\FXM
C:\Sitecore\sc80rev150621\Website\App_Config\Include\ListManagement
C:\Sitecore\sc80rev150621\Website\App_Config\Include\Social
C:\Sitecore\sc80rev150621\Website\App_Config\Include\XdbCloud
C:\Sitecore\sc80rev150621\Website\App_Config\Include\zzzzzzzzz
C:\Sitecore\sc80rev150621\Website\App_Config\Include\ZZZZZZZZZZZ
C:\Sitecore\sc80rev150621\Website\App_Config\Include\zzz_WebsiteName
C:\Sitecore\sc80rev150621\Website\App_Config\Include\zzz_z

Yes, based on this result, zzz_WebsiteName is behind other folders, so it shouldn't work when I put the files in zzzz or ZZZZ folder. However here is what we see in Windows Exploer:

zzz_WebsiteName
zzz_z
zzzzzzzzz
ZZZZZZZZZZZ

It's different!
Then I ran dir command in CMD:

05/02/2016  03:36 PM <DIR> zzzzzzzzz
16/03/2016  12:43 PM <DIR> ZZZZZZZZZZZ
16/03/2016  12:40 PM <DIR> zzz_WebsiteName
16/03/2016  12:43 PM <DIR> zzz_z

This time it's the same as what the code returns.
After Googling a bit, found this reference:Why do NTFS and Explorer disagree on filename sorting?. Basically the ordering algorithm from the file system is different from Windows Explorer. So the order we thought we arranged is not actually true when Sitecore executes the logic.
Remember to verify the order using CMD in the future...