diff --git a/skills/git-workflow/SKILL.md b/skills/git-workflow/SKILL.md index ca4379c..ea1c3a9 100644 --- a/skills/git-workflow/SKILL.md +++ b/skills/git-workflow/SKILL.md @@ -32,7 +32,7 @@ Load references on demand based on the task at hand: | Reference | Content Triggers | |-----------|-----------------| | `references/branching-strategies.md` | Branching model, Git Flow, GitHub Flow, trunk-based, branch protection | -| `references/commit-conventions.md` | Commit messages, conventional commits, semantic versioning, commitlint | +| `references/commit-conventions.md` | Commit messages, conventional commits, DCO sign-off, semantic versioning, commitlint | | `references/pull-request-workflow.md` | PR create/review/merge, thread resolution, merge strategies, CODEOWNERS, signed commits + rebase | | `references/ci-cd-integration.md` | GitHub Actions, GitLab CI, semantic release, deployment | | `references/advanced-git.md` | Rebase, cherry-pick, bisect, stash, worktrees, reflog, submodules, recovery | diff --git a/skills/git-workflow/references/commit-conventions.md b/skills/git-workflow/references/commit-conventions.md index f07dc89..b4465fb 100644 --- a/skills/git-workflow/references/commit-conventions.md +++ b/skills/git-workflow/references/commit-conventions.md @@ -123,6 +123,16 @@ When a conflict is detected, the operation is retried with fresh data. The retry limit is set to 3 attempts to prevent infinite loops. ``` +**Write multi-line or special-char bodies to a file, not inline `-m`.** The shell parses a double-quoted `-m "..."` before git sees it: an *unescaped* `"` in the body closes the string early, after which a bare `&` backgrounds the fragment and the message silently truncates (a tell-tale `... command not found` may scroll past). Even with the quotes balanced, the shell still expands `$var`, `` `cmd` ``/`$(...)`, and backslashes inside double quotes, so a body containing those is altered. A file or a *single-quoted* heredoc (`<<'EOF'`) sidesteps all of it — the text is passed verbatim: + +```bash +git commit -S --signoff -F - <<'EOF' +fix: prevent race condition in order processing + +Body may contain "quotes", & ampersands, `backticks` — all literal. +EOF +``` + ### Footer ```bash diff --git a/skills/git-workflow/references/pull-request-workflow.md b/skills/git-workflow/references/pull-request-workflow.md index cd05e7f..16ab707 100644 --- a/skills/git-workflow/references/pull-request-workflow.md +++ b/skills/git-workflow/references/pull-request-workflow.md @@ -554,6 +554,25 @@ git commit git push ``` +### `--force-with-lease` Rejected with "stale info" + +On PRs that bots touch (auto-approve, Renovate/Dependabot, a CI step that pushes), `git push --force-with-lease` can be rejected with `stale info` even when your local work is correct: a bot updated the remote branch since your last fetch, so the lease's expected ref (your `origin/` tracking ref) no longer matches and the push aborts. This is the safety check working — don't escalate to plain `--force`. + +Fetch, see what arrived, then push — the lease now matches the ref you just fetched: + +```bash +BR=feature/my-feature +git fetch origin "$BR" +git log HEAD..origin/"$BR" # what the bot pushed — safe to discard? +git push --force-with-lease origin "$BR" # lease compares against the fetched tracking ref +``` + +If a bot keeps pushing inside the fetch→push window so the plain lease never matches, pin it to the head you just inspected. This pins, not skips, the check — it accepts exactly that SHA, so only run it right after the `git log` above confirms those commits are safe to discard: + +```bash +git push --force-with-lease="$BR:$(git rev-parse origin/"$BR")" origin "$BR" +``` + ### Complex Conflicts ```bash