|
6 | 6 | using System.Globalization; |
7 | 7 | using System.IO; |
8 | 8 | using System.Linq; |
| 9 | +using System.Runtime.InteropServices; |
9 | 10 | using System.Text; |
10 | 11 |
|
11 | 12 | namespace Nerdbank.GitVersioning.ManagedGit |
@@ -110,16 +111,14 @@ public GitRepository(string workingDirectory, string gitDirectory, string common |
110 | 111 | var length = alternateStream!.Read(alternates); |
111 | 112 | alternates = alternates.Slice(0, length); |
112 | 113 |
|
113 | | - int index = 0; |
114 | | - |
115 | | - while ((index = alternates.IndexOf((byte)':')) > 0) |
| 114 | + foreach(var alternate in ParseAlternates(alternates)) |
116 | 115 | { |
117 | | - var alternate = GetString(alternates.Slice(0, index)); |
118 | | - alternate = Path.GetFullPath(Path.Combine(this.ObjectDirectory, alternate)); |
119 | | - |
120 | | - this.alternates.Add(GitRepository.Create(workingDirectory, gitDirectory, commonDirectory, alternate)); |
121 | | - |
122 | | - alternates = alternates.Slice(index + 1); |
| 116 | + this.alternates.Add( |
| 117 | + GitRepository.Create( |
| 118 | + workingDirectory, |
| 119 | + gitDirectory, |
| 120 | + commonDirectory, |
| 121 | + objectDirectory: Path.GetFullPath(Path.Combine(this.ObjectDirectory, alternate)))); |
123 | 122 | } |
124 | 123 | } |
125 | 124 |
|
@@ -714,5 +713,33 @@ public static unsafe string GetString(ReadOnlySpan<byte> bytes) |
714 | 713 | return Encoding.GetString(pBytes, bytes.Length); |
715 | 714 | } |
716 | 715 | } |
| 716 | + |
| 717 | + /// <summary> |
| 718 | + /// Parses the contents of the alternates file, and returns a list of (relative) paths to the alternate object directories. |
| 719 | + /// </summary> |
| 720 | + /// <param name="alternates"> |
| 721 | + /// The contents of the alternates files. |
| 722 | + /// </param> |
| 723 | + /// <returns> |
| 724 | + /// A list of (relative) paths to the alternate object directories.</returns> |
| 725 | + public static List<string> ParseAlternates(ReadOnlySpan<byte> alternates) |
| 726 | + { |
| 727 | + List<string> values = new List<string>(); |
| 728 | + |
| 729 | + int index = 0; |
| 730 | + |
| 731 | + // The alternates path is colon (:)-separated. On Windows, there may be full paths, such as |
| 732 | + // C:/Users/username/source/repos/nbgv/.git, which also contain a colon. Because the colon |
| 733 | + // can only appear at the second position, we skip the first two characters (e.g. C:) on Windows. |
| 734 | + int skipCount = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 2 : 0; |
| 735 | + |
| 736 | + while (alternates.Length > skipCount && (index = alternates.Slice(skipCount).IndexOfAny((byte)':', (byte)'\n')) > 0) |
| 737 | + { |
| 738 | + values.Add(GetString(alternates.Slice(0, skipCount + index))); |
| 739 | + alternates = alternates.Slice(skipCount + index + 1); |
| 740 | + } |
| 741 | + |
| 742 | + return values; |
| 743 | + } |
717 | 744 | } |
718 | 745 | } |
0 commit comments