@openthink/stamp 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7532,6 +7532,15 @@ function verifyRef(oldSha, newSha, refname) {
7532
7532
  `push is not fast-forward (old ${oldSha.slice(0, 8)} is not an ancestor of new ${newSha.slice(0, 8)}). Force-push to a protected branch is not allowed.`
7533
7533
  );
7534
7534
  }
7535
+ const liveTip = readLiveRef(refname);
7536
+ if (liveTip !== null && liveTip !== oldSha) {
7537
+ if (!isAncestor(liveTip, newSha)) {
7538
+ reject(
7539
+ refname,
7540
+ `concurrent push detected: live tip is ${liveTip.slice(0, 8)} but this push expected ${oldSha.slice(0, 8)}, and new ${newSha.slice(0, 8)} is not a descendant of the live tip. Fetch the latest main and re-run stamp merge so your work lands on top of the current tip.`
7541
+ );
7542
+ }
7543
+ }
7535
7544
  const trustedKeys = readTrustedKeysAt(oldSha);
7536
7545
  const newCommits = listNewCommits(oldSha, newSha);
7537
7546
  for (const sha of newCommits) {
@@ -7839,6 +7848,16 @@ function readTrustedKeysAt(sha) {
7839
7848
  }
7840
7849
  return map;
7841
7850
  }
7851
+ function readLiveRef(refname) {
7852
+ try {
7853
+ return (0, import_node_child_process.execFileSync)("git", ["rev-parse", "--verify", refname], {
7854
+ encoding: "utf8",
7855
+ stdio: ["ignore", "pipe", "pipe"]
7856
+ }).trim();
7857
+ } catch {
7858
+ return null;
7859
+ }
7860
+ }
7842
7861
  function isAncestor(ancestor, descendant) {
7843
7862
  try {
7844
7863
  (0, import_node_child_process.execFileSync)(