Skip to content

Commit 0905479

Browse files
Update Git to v2.43.0 (#4618)
* Update Git to a new version Add feature flag to use different Git versions in Worker and Listener Separate Git config and Git usage
1 parent bcc0324 commit 0905479

File tree

12 files changed

+417
-93
lines changed

12 files changed

+417
-93
lines changed

src/Agent.Plugins/GitCliManager.cs

+47-12
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@
1818

1919
namespace Agent.Plugins.Repository
2020
{
21-
public class GitCliManager
21+
public interface IGitCliManager
22+
{
23+
Task<int> GitConfig(AgentTaskPluginExecutionContext context, string repositoryPath, string configKey, string configValue);
24+
}
25+
26+
public class GitCliManager : IGitCliManager
2227
{
2328
private static Encoding _encoding
2429
{
@@ -77,27 +82,57 @@ public bool EnsureGitLFSVersion(Version requiredVersion, bool throwOnNotMatch)
7782
return gitLfsVersion >= requiredVersion;
7883
}
7984

85+
public (string gitPath, string gitLfsPath) GetInternalGitPaths(
86+
AgentTaskPluginExecutionContext context,
87+
bool useLatestGitVersion)
88+
{
89+
string agentHomeDir = context.Variables.GetValueOrDefault("agent.homedirectory")?.Value;
90+
ArgUtil.NotNullOrEmpty(agentHomeDir, nameof(agentHomeDir));
91+
92+
string gitPath;
93+
94+
if (useLatestGitVersion)
95+
{
96+
gitPath = Path.Combine(agentHomeDir, "externals", "ff_git", "cmd", $"git.exe");
97+
}
98+
else
99+
{
100+
gitPath = Path.Combine(agentHomeDir, "externals", "git", "cmd", $"git.exe");
101+
}
102+
103+
context.Debug($@"The useLatestGitVersion property is set to ""{useLatestGitVersion}"" therefore the Git path is ""{gitPath}""");
104+
105+
string gitLfsPath;
106+
107+
if (PlatformUtil.BuiltOnX86)
108+
{
109+
gitLfsPath = Path.Combine(agentHomeDir, "externals", "git", "mingw32", "bin", "git-lfs.exe");
110+
}
111+
else
112+
{
113+
gitLfsPath = Path.Combine(agentHomeDir, "externals", "git", "mingw64", "bin", "git-lfs.exe");
114+
}
115+
116+
return (gitPath, gitLfsPath);
117+
}
118+
80119
public virtual async Task LoadGitExecutionInfo(AgentTaskPluginExecutionContext context, bool useBuiltInGit)
81120
{
82121
// There is no built-in git for OSX/Linux
83122
gitPath = null;
123+
gitLfsPath = null;
84124

85125
// Resolve the location of git.
86126
if (useBuiltInGit && PlatformUtil.RunningOnWindows)
87127
{
88-
string agentHomeDir = context.Variables.GetValueOrDefault("agent.homedirectory")?.Value;
89-
ArgUtil.NotNullOrEmpty(agentHomeDir, nameof(agentHomeDir));
128+
context.Debug("Git paths are resolving from internal dependencies");
90129

91-
if (AgentKnobs.FixPossibleGitOutOfMemoryProblem.GetValue(context).AsBoolean())
92-
{
93-
gitPath = Path.Combine(agentHomeDir, "externals", "ff_git", "cmd", $"git.exe");
94-
}
95-
else
96-
{
97-
gitPath = Path.Combine(agentHomeDir, "externals", "git", "cmd", $"git.exe");
98-
}
130+
var (resolvedGitPath, resolvedGitLfsPath) = GetInternalGitPaths(
131+
context,
132+
AgentKnobs.UseLatestGitVersion.GetValue(context).AsBoolean());
99133

100-
gitLfsPath = Path.Combine(agentHomeDir, "externals", "git", PlatformUtil.BuiltOnX86 ? "mingw32" : "mingw64", "bin", "git-lfs.exe");
134+
gitPath = resolvedGitPath;
135+
gitLfsPath = resolvedGitLfsPath;
101136

102137
// Prepend the PATH.
103138
context.Output(StringUtil.Loc("Prepending0WithDirectoryContaining1", "Path", Path.GetFileName(gitPath)));

src/Agent.Plugins/GitSourceProvider.cs

+28-12
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ public async Task GetSourceAsync(
404404

405405
// Make sure the build machine met all requirements for the git repository
406406
// For now, the requirement we have are:
407-
// 1. git version greater than 2.9 and git-lfs version greater than 2.1 for on-prem tfsgit
407+
// 1. git version greater than 2.9 and git-lfs version greater than 2.1 for on-prem tfsgit
408408
// 2. git version greater than 2.14.2 if use SChannel for SSL backend (Windows only)
409409
RequirementCheck(executionContext, repository, gitCommandManager);
410410
string username = string.Empty;
@@ -684,17 +684,7 @@ public async Task GetSourceAsync(
684684
executionContext.Warning("Unable turn off git auto garbage collection, git fetch operation may trigger auto garbage collection which will affect the performance of fetching.");
685685
}
686686

687-
if (AgentKnobs.FixPossibleGitOutOfMemoryProblem.GetValue(executionContext).AsBoolean())
688-
{
689-
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.threads", "1");
690-
await gitCommandManager.GitConfig(executionContext, targetPath, "http.postBuffer", "524288000");
691-
await gitCommandManager.GitConfig(executionContext, targetPath, "core.packedgitwindowsize", "256m");
692-
await gitCommandManager.GitConfig(executionContext, targetPath, "core.packedgitlimit", "256m");
693-
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.windowmemory", "256m");
694-
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.deltaCacheSize", "256m");
695-
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.packSizeLimit", "256m");
696-
await gitCommandManager.GitConfig(executionContext, targetPath, "core.longpaths", "true");
697-
}
687+
SetGitFeatureFlagsConfiguration(executionContext, gitCommandManager, targetPath);
698688

699689
// always remove any possible left extraheader setting from git config.
700690
if (await gitCommandManager.GitConfigExist(executionContext, targetPath, $"http.{repositoryUrl.AbsoluteUri}.extraheader"))
@@ -1315,6 +1305,32 @@ public async Task PostJobCleanupAsync(AgentTaskPluginExecutionContext executionC
13151305
}
13161306
}
13171307

1308+
public async void SetGitFeatureFlagsConfiguration(
1309+
AgentTaskPluginExecutionContext executionContext,
1310+
IGitCliManager gitCommandManager,
1311+
string targetPath)
1312+
{
1313+
if (AgentKnobs.UseGitSingleThread.GetValue(executionContext).AsBoolean())
1314+
{
1315+
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.threads", "1");
1316+
}
1317+
1318+
if (AgentKnobs.FixPossibleGitOutOfMemoryProblem.GetValue(executionContext).AsBoolean())
1319+
{
1320+
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.windowmemory", "256m");
1321+
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.deltaCacheSize", "256m");
1322+
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.packSizeLimit", "256m");
1323+
await gitCommandManager.GitConfig(executionContext, targetPath, "http.postBuffer", "524288000");
1324+
await gitCommandManager.GitConfig(executionContext, targetPath, "core.packedgitwindowsize", "256m");
1325+
await gitCommandManager.GitConfig(executionContext, targetPath, "core.packedgitlimit", "256m");
1326+
}
1327+
1328+
if (AgentKnobs.UseGitLongPaths.GetValue(executionContext).AsBoolean())
1329+
{
1330+
await gitCommandManager.GitConfig(executionContext, targetPath, "core.longpaths", "true");
1331+
}
1332+
}
1333+
13181334
protected virtual GitCliManager GetCliManager(Dictionary<string, string> gitEnv = null)
13191335
{
13201336
return new GitCliManager(gitEnv);

src/Agent.Sdk/Knob/AgentKnobs.cs

+21
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,27 @@ public class AgentKnobs
128128
new EnvironmentKnobSource("FIX_POSSIBLE_GIT_OUT_OF_MEMORY_PROBLEM"),
129129
new BuiltInDefaultKnobSource("false"));
130130

131+
public static readonly Knob UseGitLongPaths = new Knob(
132+
nameof(UseGitLongPaths),
133+
"When true, set core.longpaths to true",
134+
new RuntimeKnobSource("USE_GIT_LONG_PATHS"),
135+
new EnvironmentKnobSource("USE_GIT_LONG_PATHS"),
136+
new BuiltInDefaultKnobSource("false"));
137+
138+
public static readonly Knob UseGitSingleThread = new Knob(
139+
nameof(UseGitSingleThread),
140+
"When true, spawn only one thread searching for best delta matches",
141+
new RuntimeKnobSource("USE_GIT_SINGLE_THREAD"),
142+
new EnvironmentKnobSource("USE_GIT_SINGLE_THREAD"),
143+
new BuiltInDefaultKnobSource("false"));
144+
145+
public static readonly Knob UseLatestGitVersion = new Knob(
146+
nameof(UseLatestGitVersion),
147+
"When true, set path to the latest git version",
148+
new RuntimeKnobSource("USE_LATEST_GIT_VERSION"),
149+
new EnvironmentKnobSource("USE_LATEST_GIT_VERSION"),
150+
new BuiltInDefaultKnobSource("false"));
151+
131152
public static readonly Knob TfVCUseSecureParameterPassing = new Knob(
132153
nameof(TfVCUseSecureParameterPassing),
133154
"If true, don't pass auth token in TFVC parameters",

src/Agent.Worker/Build/GitCommandManager.cs

+42-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public interface IGitCommandManager : IAgentService
2222

2323
bool EnsureGitLFSVersion(Version requiredVersion, bool throwOnNotMatch);
2424

25+
(string resolvedGitPath, string resolvedGitLfsPath) GetInternalGitPaths(IExecutionContext context, bool useLatestGitVersion);
26+
2527
// setup git execution info, git location, version, useragent, execpath
2628
Task LoadGitExecutionInfo(IExecutionContext context, bool useBuiltInGit, Dictionary<string, string> gitEnv = null);
2729

@@ -160,6 +162,38 @@ public bool EnsureGitLFSVersion(Version requiredVersion, bool throwOnNotMatch)
160162
return _gitLfsVersion >= requiredVersion;
161163
}
162164

165+
public (string resolvedGitPath, string resolvedGitLfsPath) GetInternalGitPaths(IExecutionContext context, bool useLatestGitVersion)
166+
{
167+
string externalsDirectoryPath = HostContext.GetDirectory(WellKnownDirectory.Externals);
168+
ArgUtil.NotNullOrEmpty(externalsDirectoryPath, nameof(WellKnownDirectory.Externals));
169+
170+
string gitPath;
171+
172+
if (useLatestGitVersion)
173+
{
174+
gitPath = Path.Combine(externalsDirectoryPath, "ff_git", "cmd", $"git.exe");
175+
}
176+
else
177+
{
178+
gitPath = Path.Combine(externalsDirectoryPath, "git", "cmd", $"git.exe");
179+
}
180+
181+
context.Debug($@"The useLatestGitVersion property is set to ""{useLatestGitVersion}"" therefore the Git path is ""{gitPath}""");
182+
183+
string gitLfsPath;
184+
185+
if (PlatformUtil.BuiltOnX86)
186+
{
187+
gitLfsPath = Path.Combine(externalsDirectoryPath, "git", "mingw32", "bin", $"git-lfs.exe");
188+
}
189+
else
190+
{
191+
gitLfsPath = Path.Combine(externalsDirectoryPath, "git", "mingw64", "bin", $"git-lfs.exe");
192+
}
193+
194+
return (gitPath, gitLfsPath);
195+
}
196+
163197
public async Task LoadGitExecutionInfo(IExecutionContext context, bool useBuiltInGit, Dictionary<string, string> gitEnv = null)
164198
{
165199
if (gitEnv != null)
@@ -181,8 +215,14 @@ public async Task LoadGitExecutionInfo(IExecutionContext context, bool useBuiltI
181215
// The Windows agent ships a copy of Git
182216
if (PlatformUtil.RunningOnWindows)
183217
{
184-
_gitPath = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), "git", "cmd", $"git{IOUtil.ExeExtension}");
185-
_gitLfsPath = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), "git", PlatformUtil.BuiltOnX86 ? "mingw32" : "mingw64", "bin", "git-lfs.exe");
218+
context.Debug("Git paths are resolving from internal dependencies");
219+
220+
var (resolvedGitPath, resolvedGitLfsPath) = GetInternalGitPaths(
221+
context,
222+
AgentKnobs.UseLatestGitVersion.GetValue(context).AsBoolean());
223+
224+
_gitPath = resolvedGitPath;
225+
_gitLfsPath = resolvedGitLfsPath;
186226

187227
// Prepend the PATH.
188228
context.Output(StringUtil.Loc("Prepending0WithDirectoryContaining1", Constants.PathVariable, Path.GetFileName(_gitPath)));

src/Agent.Worker/Build/GitSourceProvider.cs

+28
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,8 @@ public async Task GetSourceAsync(
657657
executionContext.Warning("Unable turn off git auto garbage collection, git fetch operation may trigger auto garbage collection which will affect the performance of fetching.");
658658
}
659659

660+
SetGitFeatureFlagsConfiguration(executionContext, _gitCommandManager, targetPath);
661+
660662
// always remove any possible left extraheader setting from git config.
661663
if (await _gitCommandManager.GitConfigExist(executionContext, targetPath, $"http.{repositoryUrl.AbsoluteUri}.extraheader"))
662664
{
@@ -1229,6 +1231,32 @@ public override async Task RunMaintenanceOperations(IExecutionContext executionC
12291231
}
12301232
}
12311233

1234+
public async void SetGitFeatureFlagsConfiguration(
1235+
IExecutionContext executionContext,
1236+
IGitCommandManager gitCommandManager,
1237+
string targetPath)
1238+
{
1239+
if (AgentKnobs.UseGitSingleThread.GetValue(executionContext).AsBoolean())
1240+
{
1241+
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.threads", "1");
1242+
}
1243+
1244+
if (AgentKnobs.FixPossibleGitOutOfMemoryProblem.GetValue(executionContext).AsBoolean())
1245+
{
1246+
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.windowmemory", "256m");
1247+
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.deltaCacheSize", "256m");
1248+
await gitCommandManager.GitConfig(executionContext, targetPath, "pack.packSizeLimit", "256m");
1249+
await gitCommandManager.GitConfig(executionContext, targetPath, "http.postBuffer", "524288000");
1250+
await gitCommandManager.GitConfig(executionContext, targetPath, "core.packedgitwindowsize", "256m");
1251+
await gitCommandManager.GitConfig(executionContext, targetPath, "core.packedgitlimit", "256m");
1252+
}
1253+
1254+
if (AgentKnobs.UseGitLongPaths.GetValue(executionContext).AsBoolean())
1255+
{
1256+
await gitCommandManager.GitConfig(executionContext, targetPath, "core.longpaths", "true");
1257+
}
1258+
}
1259+
12321260
public override void SetVariablesInEndpoint(IExecutionContext executionContext, ServiceEndpoint endpoint)
12331261
{
12341262
ArgUtil.NotNull(executionContext, nameof(executionContext));

src/Microsoft.VisualStudio.Services.Agent/Constants.cs

+8
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ public static class Agent
322322
public static readonly string ContainerMapping = "agent.containermapping";
323323
public static readonly string ContainerNetwork = "agent.containernetwork";
324324
public static readonly string Diagnostic = "agent.diagnostic";
325+
public static readonly string FixPossibleGitOutOfMemoryProblem = "FIX_POSSIBLE_GIT_OUT_OF_MEMORY_PROBLEM";
325326
public static readonly string HomeDirectory = "agent.homedirectory";
326327
public static readonly string Id = "agent.id";
327328
public static readonly string IsSelfHosted = "agent.isselfhosted";
@@ -351,6 +352,9 @@ public static class Agent
351352
public static readonly string SslSkipCertValidation = "agent.skipcertvalidation";
352353
public static readonly string TempDirectory = "agent.TempDirectory";
353354
public static readonly string ToolsDirectory = "agent.ToolsDirectory";
355+
public static readonly string UseGitLongPaths = "USE_GIT_LONG_PATHS";
356+
public static readonly string UseGitSingleThread = "USE_GIT_SINGLE_THREAD";
357+
public static readonly string UseLatestGitVersion = "USE_LATEST_GIT_VERSION";
354358
public static readonly string Version = "agent.version";
355359
public static readonly string WorkFolder = "agent.workfolder";
356360
public static readonly string WorkingDirectory = "agent.WorkingDirectory";
@@ -522,6 +526,7 @@ public static class Task
522526
Agent.ContainerMapping,
523527
Agent.ContainerNetwork,
524528
Agent.Diagnostic,
529+
Agent.FixPossibleGitOutOfMemoryProblem,
525530
Agent.GitUseSChannel,
526531
Agent.HomeDirectory,
527532
Agent.Id,
@@ -551,6 +556,9 @@ public static class Task
551556
Agent.SslSkipCertValidation,
552557
Agent.TempDirectory,
553558
Agent.ToolsDirectory,
559+
Agent.UseGitLongPaths,
560+
Agent.UseGitSingleThread,
561+
Agent.UseLatestGitVersion,
554562
Agent.Version,
555563
Agent.WorkFolder,
556564
Agent.WorkingDirectory,

src/Misc/externals.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ NODE10_VERSION="10.24.1"
1919
NODE16_VERSION="16.20.2"
2020
NODE20_VERSION="20.9.0"
2121
MINGIT_VERSION="2.39.1"
22-
FF_MINGIT_VERSION="2.42.0.2"
22+
FF_MINGIT_VERSION="2.43.0"
2323
LFS_VERSION="3.3.0"
2424

2525
get_abs_path() {

0 commit comments

Comments
 (0)