OPC # 0006: OPC Git Trunk-Based management

This commit is contained in:
amadzarak
2026-04-26 13:14:06 -04:00
parent b9f0f6dd5f
commit 571f0bf2a4
+14 -8
View File
@@ -91,7 +91,9 @@ public class PromotionService(IConfiguration config, ILogger<PromotionService> l
ct.ThrowIfCancellationRequested(); ct.ThrowIfCancellationRequested();
var branchName = Ladder[i]; var branchName = Ladder[i];
var branch = repo.Branches[branchName]; // Always read from the remote tracking ref so the status reflects what is on origin,
// not the server's potentially-stale local branch pointer.
var branch = repo.Branches[$"origin/{branchName}"];
if (branch?.Tip is null) if (branch?.Tip is null)
{ {
@@ -110,7 +112,7 @@ public class PromotionService(IConfiguration config, ILogger<PromotionService> l
if (i + 1 < Ladder.Length) if (i + 1 < Ladder.Length)
{ {
var nextBranch = repo.Branches[Ladder[i + 1]]; var nextBranch = repo.Branches[$"origin/{Ladder[i + 1]}"];
if (nextBranch?.Tip is not null) if (nextBranch?.Tip is not null)
{ {
var div = repo.ObjectDatabase.CalculateHistoryDivergence(tip, nextBranch.Tip); var div = repo.ObjectDatabase.CalculateHistoryDivergence(tip, nextBranch.Tip);
@@ -220,9 +222,12 @@ public class PromotionService(IConfiguration config, ILogger<PromotionService> l
var refSpecs = remote.FetchRefSpecs.Select(r => r.Specification).ToList(); var refSpecs = remote.FetchRefSpecs.Select(r => r.Specification).ToList();
repo.Network.Fetch(remote.Name, refSpecs, MakeFetchOptions()); repo.Network.Fetch(remote.Name, refSpecs, MakeFetchOptions());
// 2. Resolve local branches // 2. Resolve branches — always read from origin/ so we reflect what is actually on the remote,
var fromBranch = repo.Branches[from] // never the server's potentially-stale local branch pointers.
?? throw new InvalidOperationException($"Branch '{from}' not found."); var fromBranch = repo.Branches[$"origin/{from}"]
?? throw new InvalidOperationException($"Remote branch 'origin/{from}' not found.");
// `to` is read locally because we need to mutate its ref and push — it is immediately
// fast-forwarded to origin/{to} in the next step so it is never stale when used.
var toBranch = repo.Branches[to] var toBranch = repo.Branches[to]
?? throw new InvalidOperationException($"Branch '{to}' not found."); ?? throw new InvalidOperationException($"Branch '{to}' not found.");
@@ -566,12 +571,13 @@ public class PromotionService(IConfiguration config, ILogger<PromotionService> l
var branchName = Ladder[i]; var branchName = Ladder[i];
var srcName = i > 0 ? Ladder[i - 1] : null; // predecessor branch (e.g. develop for staging) var srcName = i > 0 ? Ladder[i - 1] : null; // predecessor branch (e.g. develop for staging)
var branch = repo.Branches[branchName]; // Always read from origin/ tracking refs — never local branch pointers.
var branch = repo.Branches[$"origin/{branchName}"];
// ── Branch missing ────────────────────────────────────────────── // ── Branch missing ──────────────────────────────────────────────
if (branch?.Tip is null) if (branch?.Tip is null)
{ {
var srcTip = srcName is not null ? repo.Branches[srcName]?.Tip?.Sha : null; var srcTip = srcName is not null ? repo.Branches[$"origin/{srcName}"]?.Tip?.Sha : null;
checks.Add(new BranchConformanceCheck( checks.Add(new BranchConformanceCheck(
branchName, srcName, branchName, srcName,
ConformanceViolation.Missing, ConformanceViolation.Missing,
@@ -592,7 +598,7 @@ public class PromotionService(IConfiguration config, ILogger<PromotionService> l
continue; continue;
} }
var srcBranch = repo.Branches[srcName]; var srcBranch = repo.Branches[$"origin/{srcName}"];
if (srcBranch?.Tip is null) if (srcBranch?.Tip is null)
{ {
// Source branch is itself missing — skip, it will be reported separately. // Source branch is itself missing — skip, it will be reported separately.