mirror of
https://github.com/hanzoai/deploy.git
synced 2026-10-07 08:44:50 +00:00
Reconcile could never have worked. RealGit set no working directory, so every command ran wherever the process started — for a scheduled job, nowhere — and git answers "fatal: not a git repository" to the fetch. That error arrives on the branch that reports GITHUB as unreadable, so a reconciler with perfect credentials and a perfect table would have called all 24 repos unreachable and asked a person to look at each one. The dry run passed throughout, because a dry run resolves names and never touches git. Git therefore takes the directory as a parameter, and Workspace prepares one store per repo under a root that MAY survive between runs. May, not must: git's fetch negotiation offers whatever is already present, so a kept root makes later runs deltas, and an empty one is equally correct and merely slower. That is what lets the job use an emptyDir instead of a claim — a ReadWriteOnce volume would buy the same time at the price of a job pod deadlocking on Multi-Attach whenever it schedules away from the node holding it. Both sides are now fetched, not just GitHub. The forge goes first for two reasons: its tip has to be local before a genuine divergence can be NAMED rather than reported as "ancestry undetermined", and once its history is present those objects are offered in negotiation, so the internet side of every run is a delta even on an empty store. That is the whole reason ten-minute scheduling is affordable over two dozen repositories. The proof is a real one. TestFastForwardMovesARealRepository builds two bare repositories, leaves the forge a commit behind, and requires it to end on GitHub's tip — then rewinds GitHub so the two genuinely disagree and requires the forge NOT to move. Every other test in this file uses a fake that agrees with the code about what git is, which is exactly why none of them caught this. Verified by mutation: drop `cmd.Dir` and it fails. Shipping is one binary, not two. cmd/hanzo-mirror becomes cmd/cd-mirror, dispatched by argv[0] like every other cd command, so the reconciler travels in the image the control plane already builds, pins and deploys — no second artifact to version, and no second chance for the two to disagree about which repos exist. The table travels with it at common.DefaultMirrorTable rather than living in a ConfigMap, so the JSON that CI validates is the JSON the scheduled run reads. Co-authored-by: Hanzo Dev <[email protected]>
79 lines
2.7 KiB
Bash
Executable File
79 lines
2.7 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# An example hook script to update a checked-out tree on a git push.
|
|
#
|
|
# This hook is invoked by git-receive-pack(1) when it reacts to git
|
|
# push and updates reference(s) in its repository, and when the push
|
|
# tries to update the branch that is currently checked out and the
|
|
# receive.denyCurrentBranch configuration variable is set to
|
|
# updateInstead.
|
|
#
|
|
# By default, such a push is refused if the working tree and the index
|
|
# of the remote repository has any difference from the currently
|
|
# checked out commit; when both the working tree and the index match
|
|
# the current commit, they are updated to match the newly pushed tip
|
|
# of the branch. This hook is to be used to override the default
|
|
# behaviour; however the code below reimplements the default behaviour
|
|
# as a starting point for convenient modification.
|
|
#
|
|
# The hook receives the commit with which the tip of the current
|
|
# branch is going to be updated:
|
|
commit=$1
|
|
|
|
# It can exit with a non-zero status to refuse the push (when it does
|
|
# so, it must not modify the index or the working tree).
|
|
die () {
|
|
echo >&2 "$*"
|
|
exit 1
|
|
}
|
|
|
|
# Or it can make any necessary changes to the working tree and to the
|
|
# index to bring them to the desired state when the tip of the current
|
|
# branch is updated to the new commit, and exit with a zero status.
|
|
#
|
|
# For example, the hook can simply run git read-tree -u -m HEAD "$1"
|
|
# in order to emulate git fetch that is run in the reverse direction
|
|
# with git push, as the two-tree form of git read-tree -u -m is
|
|
# essentially the same as git switch or git checkout that switches
|
|
# branches while keeping the local changes in the working tree that do
|
|
# not interfere with the difference between the branches.
|
|
|
|
# The below is a more-or-less exact translation to shell of the C code
|
|
# for the default behaviour for git's push-to-checkout hook defined in
|
|
# the push_to_deploy() function in builtin/receive-pack.c.
|
|
#
|
|
# Note that the hook will be executed from the repository directory,
|
|
# not from the working tree, so if you want to perform operations on
|
|
# the working tree, you will have to adapt your code accordingly, e.g.
|
|
# by adding "cd .." or using relative paths.
|
|
|
|
if ! git update-index -q --ignore-submodules --refresh
|
|
then
|
|
die "Up-to-date check failed"
|
|
fi
|
|
|
|
if ! git diff-files --quiet --ignore-submodules --
|
|
then
|
|
die "Working directory has unstaged changes"
|
|
fi
|
|
|
|
# This is a rough translation of:
|
|
#
|
|
# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX
|
|
if git cat-file -e HEAD 2>/dev/null
|
|
then
|
|
head=HEAD
|
|
else
|
|
head=$(git hash-object -t tree --stdin </dev/null)
|
|
fi
|
|
|
|
if ! git diff-index --quiet --cached --ignore-submodules $head --
|
|
then
|
|
die "Working directory has staged changes"
|
|
fi
|
|
|
|
if ! git read-tree -u -m "$commit"
|
|
then
|
|
die "Could not update working tree to new HEAD"
|
|
fi
|