Check whether the version in flutter-candidate.txt is a tag or a commit hash (#7993)

Follow-up to https://github.com/flutter/devtools/pull/7989

Fixes error running `devtools_tool update-flutter-sdk` when the Flutter version is a commit hash:

```
~/develop/devtools/packages/devtools_app/ [ext-settings-button*] devtools_tool update-flutter-sdk --use-cache
Using Flutter SDK from /Users/kenzieschmoll/develop/devtools/tool/flutter-sdk
Updating to Flutter version from cache: tags/1c77696615558bf8f9fa7a6e2a473f438f1c03ca 
Updating Flutter at /Users/kenzieschmoll/develop/devtools/tool/flutter-sdk
/Users/kenzieschmoll/develop/devtools/tool/flutter-sdk > git fetch
/Users/kenzieschmoll/develop/devtools/tool/flutter-sdk > git checkout tags/1c77696615558bf8f9fa7a6e2a473f438f1c03ca -f
error: pathspec 'tags/1c77696615558bf8f9fa7a6e2a473f438f1c03ca' did not match any file(s) known to git
ProcessException: Failed with exit code: 1. 
  Command: git checkout tags/1c77696615558bf8f9fa7a6e2a473f438f1c03ca -f
```
diff --git a/tool/lib/commands/update_flutter_sdk.dart b/tool/lib/commands/update_flutter_sdk.dart
index 65858ad..5045b97 100644
--- a/tool/lib/commands/update_flutter_sdk.dart
+++ b/tool/lib/commands/update_flutter_sdk.dart
@@ -14,6 +14,8 @@
 const _updateOnPath = 'update-on-path';
 const _useCacheFlag = 'use-cache';
 
+final _flutterPreReleaseTagRegExp = RegExp(r'[0-9]+.[0-9]+.0-[0-9]+.0.pre');
+
 /// This command updates the the Flutter SDK contained in the 'tool/' directory
 /// to the latest Flutter candidate branch.
 ///
@@ -79,12 +81,18 @@
     final repo = DevToolsRepo.getInstance();
     final processManager = ProcessManager();
 
-    final String flutterTag;
+    final String? flutterVersion;
+
     if (useCachedVersion) {
-      flutterTag =
-          'tags/${repo.readFile(Uri.parse('flutter-candidate.txt')).trim()}';
+      final versionStr =
+          repo.readFile(Uri.parse('flutter-candidate.txt')).trim();
+      // If the version string doesn't match the expected pattern for a
+      // pre-release tag, then assume it's a commit hash:
+      flutterVersion = _flutterPreReleaseTagRegExp.hasMatch(versionStr)
+          ? 'tags/$versionStr'
+          : versionStr;
     } else {
-      flutterTag = (await processManager.runProcess(
+      flutterVersion = (await processManager.runProcess(
         CliCommand('sh', ['latest_flutter_candidate.sh']),
         workingDirectory: repo.toolDirectoryPath,
       ))
@@ -95,7 +103,7 @@
 
     log.stdout(
       'Updating to Flutter version '
-      '${useCachedVersion ? 'from cache' : 'from upstream'}: $flutterTag ',
+      '${useCachedVersion ? 'from cache' : 'from upstream'}: $flutterVersion',
     );
 
     final flutterSdkDirName = repo.sdkDirectoryName;
@@ -120,7 +128,7 @@
           CliCommand.git(['fetch', 'upstream']),
           CliCommand.git(['checkout', 'upstream/master']),
           CliCommand.git(['reset', '--hard', 'upstream/master']),
-          CliCommand.git(['checkout', flutterTag, '-f']),
+          CliCommand.git(['checkout', flutterVersion, '-f']),
           CliCommand.flutter(['--version']),
         ],
         workingDirectory: pathSdk.sdkPath,
@@ -134,7 +142,7 @@
       await processManager.runAll(
         commands: [
           CliCommand.git(['fetch']),
-          CliCommand.git(['checkout', flutterTag, '-f']),
+          CliCommand.git(['checkout', flutterVersion, '-f']),
           CliCommand.flutter(['--version']),
         ],
         workingDirectory: toolSdkPath,
@@ -149,7 +157,7 @@
       );
       await processManager.runAll(
         commands: [
-          CliCommand.git(['checkout', flutterTag, '-f']),
+          CliCommand.git(['checkout', flutterVersion, '-f']),
           CliCommand.flutter(['--version']),
         ],
         workingDirectory: toolSdkPath,