4 · Initialize the repository
Objective — expand the bootstrap git from Create the project into the full import repo: merge Code & repository setup ignore rules, set identity, wire develop, and lock down per-directory storage ignores — without re-running git init if .git/ already exists.
Steps at a glance:
- Set session variables — Export your project’s values once so every command here (and on the next pages) is copy-paste safe.
- Merge
.gitignore(bootstrap → Code & repository setup) — If Create the project ran, keep its anchored patterns (/vendor/,/_source/,!.env.tplwhen using 1Password,.vscodenegation from C2). - Initialize or confirm git on
develop—developand the frozenauthor/vX.X.Xbaseline already exist from AI dev environment setup. Commit & freeze pushes them — it does not recreate the import commit. - Lock down storage ignores — Laravel’s
storage/subtree must keep its folders in git but ignore their contents. Backfill any missing per-directory.gitignores. - Record the vendor’s installer-marker mechanism — Vendors differ in how they flag “install complete.” Record yours once so deploy excludes and the first-install caution stay accurate per project.
Background
Section titled “Background”The single most important ordering rule: .gitignore before the first commit that could track secrets or vendor/. Create the project already ran bootstrap git init, committed the pristine vendor baseline on author/v* + tag, and set develop — this page merges Code & repository setup patterns (remote prep, storage subtree, vault paths) without recreating the import. If you somehow skipped Create the project, write .gitignore first, then git init, then run pristine baseline commit before continuing.
1. Set session variables
Section titled “1. Set session variables”Export your project’s values once so every command here (and on the next pages) is copy-paste safe. Pull them from your Zaj-PROJECT.
-
Export the project variables.
Terminal window export PROJECT_NAME="<project>"export VERSION="x.y.z" # replace with the vendor's semverexport GITHUB_REPO="git@github.com:<your-org>/<project>.git"export GIT_USERNAME="Your Name"export GIT_EMAIL="<you>@users.noreply.github.com"echo "Project: $PROJECT_NAME · Version: $VERSION · Repo: $GITHUB_REPO"# Expected: the echoed line shows your real project / version / repo values- ✅ The echo prints your actual project, version, and repo — no
<placeholder>left.
- ✅ The echo prints your actual project, version, and repo — no
2. Merge .gitignore (bootstrap → Code & repository setup)
Section titled “2. Merge .gitignore (bootstrap → Code & repository setup)”If Create the project ran, keep its anchored patterns (/vendor/, /_source/, !.env.tpl when using 1Password, .vscode negation from C2). Add or reconcile the lines below — do not replace the whole file blindly. The bootstrap block lives on Create the project §4; this page only adds Phase-2 deltas.
Write or merge the ignore file so the very next git status stays clean.
flowchart LR A[".gitignore<br/>merged / written"] --> B{"git init<br/>already?"} B -->|no| C["git init"] B -->|yes| D["skip init"] C --> E["git branch -M develop"] D --> E E --> F["git config<br/>user.name / user.email"]-
Write a baseline
.gitignorefor a CodeCanyon Laravel app..gitignore # Dependencies/vendor//node_modules/# Secrets (never commit).env.env.*!.env.example!.env.tpl# Laravel generated/storage/*.key/bootstrap/cache/*.php# Installer "complete" marker — per-environment runtime state (like .env): gitignored so it is# never COMMITTED. It SHOULD exist on each installed environment (created by that env's own install)# and persists on the server via the shared storage/ dir — do NOT delete it on deploy/update.# The ONLY hazard is the FIRST install: a brand-new server must never receive a pre-made marker,# or its installer is skipped. (Replace with your vendor's marker — see step 5.)/storage/installed# Per-environment public symlinks — recreated by `php artisan storage:link` (and the module# `packages` link, for in-tree module apps); never commit. CodeCanyon vendors often ship# public/storage as a TRACKED absolute symlink to a server path (/var/www/...) — dead on every other env./public/storage/public/packages# Archive — NEVER in git (AI dev environment bootstrap)/_source/# OS & IDE — .vscode/*.json committed at C2 (machine setup); keep negation if present.DS_Store/.idea//.vscode/*!/.vscode/extensions.json!/.vscode/settings.json!/.vscode/launch.json# Logs & testing*.log.phpunit.result.cache# CodeCanyon ZIPs*.zip# Agent/browser automation state (can contain cookies, auth headers, PII)/.playwright-mcp/*!/.playwright-mcp/.gitkeep/.browser-mcp//test-results//playwright-report/# Build — comment out the next line if you use the Build-Locally strategy# /public/build/# Project vault (credentials)/Admin-Local/1-Project/2-Vault/- ✅
.gitignoreexists at the repo root before anygitcommand runs.
- ✅
-
Keep the Playwright MCP folder present but empty (edit-spec M5 — tracked placeholder, ignored session state).
Terminal window mkdir -p .playwright-mcpcat > .playwright-mcp/.gitkeep << 'EOF'# Playwright MCP session state lives here at runtime.# Root .gitignore ignores everything except this file so the folder exists in git# without committing cookies, auth headers, or other browser automation artifacts.EOFgit check-ignore .playwright-mcp/session.json && echo "✅ browser state ignored"# Expected: ✅ browser state ignored- ✅ Only
.playwright-mcp/.gitkeepis eligible for git; generated browser state is ignored.
- ✅ Only
-
Confirm the installer marker is ignored — but never delete it. The vendor’s “install complete” marker is per-environment runtime state (the same category as
.env): it must stay out of git, yet it should exist on each installed environment and persist on the server. Verify it is ignored and don’t stage or remove it.Terminal window # Default Laravel installer marker. If the vendor uses a different one, swap the path# (record it in step 5) — common variants: storage/installed, .installed, public/install.lockMARKER="storage/installed"git check-ignore -q "$MARKER" && echo "✅ $MARKER ignored (never committed)" \|| echo "❌ $MARKER NOT ignored — add it to .gitignore before staging"# If the marker is already TRACKED from the vendor import, stop tracking it WITHOUT deleting it.if git ls-files --error-unmatch "$MARKER" >/dev/null 2>&1; thengit rm --cached --quiet "$MARKER" && echo "⚠️ untracked $MARKER (file kept on disk)"elseecho "✅ $MARKER not tracked"fi# Expected: marker ignored and not tracked; the file on disk (if present) is left in place- ✅ The marker is git-ignored and not tracked, and the on-disk file (if any) is untouched —
git rm --cachedonly stops tracking; it does not delete.
- ✅ The marker is git-ignored and not tracked, and the on-disk file (if any) is untouched —
-
Untrack the per-environment public symlinks — they are recreated per environment, never committed.
public/storage(andpublic/packagesfor in-tree module apps like WorkDo) are per-environment symlinks: they belong to whichever machine ranphp artisan storage:link/ thepackageslink, not to git. CodeCanyon vendors frequently shippublic/storagetracked as an absolute symlink to their server path (/var/www/html/.../storage/app/public) — dead on every other environment, so all/storage/*assets 403/404 until relinked. Stop tracking any shipped symlink without deleting it; it is recreated in local development (Phase 3).Terminal window # Stop tracking the per-env symlinks if the vendor shipped them tracked (file kept on disk).for link in public/storage public/packages; doif git ls-files --error-unmatch "$link" >/dev/null 2>&1; thengit rm --cached --quiet "$link" && echo "⚠️ untracked $link (recreated per-env in Phase 3)"elseecho "✅ $link not tracked"fidone# Both must be ignored so a future relink/storage:link never re-stages them.git check-ignore public/storage public/packages# Expected: both paths echoed back (both ignored); neither tracked. A fresh clone has# NEITHER symlink until Phase 3 recreates them:# php artisan storage:link # → public/storage# cd public && ln -s ../packages packages # → public/packages (in-tree module apps)- ✅
public/storageandpublic/packagesare ignored and not tracked; both are recreated per environment in Phase 3, never committed.
- ✅
You ignore vendor/ so it never bloats history — but you do not delete the shipped tree (see Extract & snapshot).
3. Initialize or confirm git on develop
Section titled “3. Initialize or confirm git on develop”-
Phase 1 prerequisite gate — if any symptom below is true, stop and complete Create the project before continuing:
Symptom Fix No author/v*branchRun pristine baseline commit No author-v*tagSame — baseline step creates both Bootstrap .gitignoremissing/_source/Re-run §4 bootstrap gitignore On maininstead ofdevelopgit branch -M developafter initTerminal window git branch --list 'author/*'git tag --list 'author-*'grep -q '^/_source/' .gitignore && echo "✅ _source anchored" || echo "❌ fix bootstrap gitignore"# Expected: author branch + tag listed; _source anchored- ✅ Phase 1 baseline artifacts exist — or you went back to Create the project.
-
Init only if needed, confirm
develop, set identity — do not deleteauthor/v*branches.Terminal window if [ ! -d .git ]; then git init; figit branch --show-current # expect develop after AI dev environment setupgit branch -M develop 2>/dev/null || true # no-op if already developgit config user.name "$GIT_USERNAME"git config user.email "$GIT_EMAIL"git branch --list 'author/*'# Expected: develop current; author/vX.X.X still present from Create the project baseline- ✅
git branch --show-currentprintsdevelop;author/v*branch still listed;user.name/user.emailare set.
- ✅
develop and the frozen author/vX.X.X baseline already exist from AI dev environment setup. Commit & freeze pushes them — it does not recreate the import commit.
4. Lock down storage ignores
Section titled “4. Lock down storage ignores”Laravel’s storage/ subtree must keep its folders in git but ignore their contents. Backfill any missing per-directory .gitignores.
-
Backfill the per-directory storage ignores.
Terminal window for dir in storage/app storage/app/public storage/framework \storage/framework/cache storage/framework/sessions \storage/framework/views storage/logs; do[ -f "$dir/.gitignore" ] || { mkdir -p "$dir"; printf "*\n!.gitignore\n" > "$dir/.gitignore"; }done# Expected: each storage subdir ends up with a "* / !.gitignore" ignore file- ✅ Every
storage/**directory carries a.gitignore.
- ✅ Every
-
Confirm the root ignore catches the big three before you stage anything.
Terminal window grep -E "^/vendor|^/node_modules|^\.env$" .gitignore # all three should print# Expected: three matching lines (/vendor, /node_modules, .env)- ✅ All three patterns print, and
git statusshows novendor/,node_modules/, or.env.
- ✅ All three patterns print, and
-
Prove lock files are not ignored.
Terminal window for f in composer.lock package-lock.json pnpm-lock.yaml yarn.lock; dotest -e "$f" || continuegit check-ignore -q "$f" && echo "❌ ignored: $f" || echo "✅ tracked-capable: $f"done# Expected: every existing lock file is tracked-capable- ✅ Lock files remain commit-capable so dependency versions are reproducible.
-
Match
/public/buildand run the.gitignoresweep.Terminal window if grep -q '^/public/build/' .gitignore; thenecho "Strategy: build-on-server or CI artifact upload"elsetest -f public/build/manifest.json && echo "Strategy: build locally and commit public/build" \|| echo "Strategy: build locally (public/build not present yet)"figrep -q "^composer.lock" .gitignore && echo "❌ REMOVE composer.lock from .gitignore" || echo "✅ composer.lock not ignored"grep -q "^package-lock.json" .gitignore && echo "❌ REMOVE package-lock.json from .gitignore" || echo "✅ package-lock.json not ignored"# Expected: strategy line matches Zaj-PROJECT.md; lock files not ignored- ✅
.gitignoreand the deploy asset strategy agree; lock files stay tracked per Branch strategy §4.
- ✅
5. Record the vendor’s installer-marker mechanism
Section titled “5. Record the vendor’s installer-marker mechanism”Vendors differ in how they flag “install complete.” Record yours once so deploy excludes and the first-install caution stay accurate per project.
-
Find the marker your vendor writes. Grep the vendor tree for where the installer creates its “done” flag.
Terminal window # Most CodeCanyon Laravel installers write a file once /install finishes.grep -rIn --include='*.php' -E "storage_path\('installed'\)|'installed'|install(ed)?\.lock|InstallController|CheckInstallation" \app/ routes/ vendor/ 2>/dev/null | head -20# Expected: the path the installer writes (e.g. storage_path('installed')) + the# middleware that redirects to /install when the marker is absent- ✅ You can name the exact marker path and the middleware that gates
/install.
- ✅ You can name the exact marker path and the middleware that gates
-
Record it in your project notes so the next phases reference the real path, not the default.
Terminal window cat >> Admin-Local/1-Project/3-Templates/installer-marker.md << EOF# Installer marker — $PROJECT_NAME (vendor $VERSION)- Marker path: storage/installed # ← replace with the path grep found- Gate middleware: CheckInstallation # ← replace with the real class- Rule: gitignored (never committed); created by each env's own install;lives in shared storage/ on the server; deploy-EXCLUDE on a fresh server.EOFecho "✅ recorded installer marker for $PROJECT_NAME"# Expected: a per-project note capturing the marker path + gate so Phase 4/5 deploy excludes stay correct- ✅ The marker path and gate are recorded; if it differs from
storage/installed, update the.gitignoreline and the step-2MARKERvariable to match.
- ✅ The marker path and gate are recorded; if it differs from
Checklist
Section titled “Checklist”Do not mark this step done until every box below is checked.
- 🤖 Session variables exported —
PROJECT_NAME,VERSION,GITHUB_REPO, identity. - 🤖
.gitignoremerged — AI dev environment bootstrap anchors preserved; Code & repository setup patterns added; lock files not ignored. - 🤖 Tree clean —
git statusshows novendor/,node_modules/, or.env. - 🤖 On
develop—user.name/user.emailconfigured. - 🤖 Storage ignores in place — each
storage/**directory carries a.gitignore. - 🤖 Installer marker handled — gitignored and not tracked (
git rm --cachedonly, on-disk file kept), per-env symlinks (/public/storage,/public/packages) ignored, and the vendor’s marker path recorded inAdmin-Local/1-Project/3-Templates/installer-marker.md.