Skip to content

Commit 95ec86b

Browse files
authored
Merge pull request #26 from netresearch/feat/worktree-convention-signed-commits
feat(refs): bare-worktree layout + signed-commit discipline
2 parents 3aaf511 + a2cbf10 commit 95ec86b

2 files changed

Lines changed: 110 additions & 1 deletion

File tree

skills/git-workflow/references/advanced-git.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,60 @@ git worktree remove ../project-feature
299299
git worktree prune
300300
```
301301

302+
### Bare-Worktree Project Layout (Recommended)
303+
304+
**One directory per branch; never switch branches in the same folder.**
305+
306+
Rationale: IDEs that index the tree (gopls, Intellij, VS Code) choke on in-place branch switches, and running parallel work on feature branches without losing the main-branch state is painful. Using a bare repo with per-branch subdirectories gives you parallel checkouts, cheap hotfix spin-ups, and a main checkout that's never "dirty because I was exploring".
307+
308+
```
309+
/projects/<repo>/
310+
├── .bare/ # bare git repository (clone --bare)
311+
├── main/ # main branch worktree
312+
├── feature-x/ # optional feature branch worktree
313+
└── bugfix-y/ # optional bugfix branch worktree
314+
```
315+
316+
**Setup a new project this way:**
317+
318+
```bash
319+
cd ~/projects
320+
mkdir <repo> && cd <repo>
321+
git clone --bare <repository-url> .bare
322+
323+
# Make the bare clone behave like a regular origin fetch target.
324+
cd .bare && git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" && cd ..
325+
326+
# Check out main into a named subdirectory.
327+
git -C .bare worktree add ../main main
328+
```
329+
330+
**Work on a new branch = create a new folder:**
331+
332+
```bash
333+
git -C .bare worktree add ../feature-x feature-x # or -b for a new branch
334+
cd feature-x
335+
# ... edit, commit, push ...
336+
cd ..
337+
git -C .bare worktree list # audit trail of what's checked out
338+
git -C .bare worktree remove feature-x # clean up when the PR merges
339+
```
340+
341+
When removing a worktree leaves a dangling branch reference (e.g., after deleting the physical directory manually), `git worktree prune` in `.bare/` cleans up the metadata.
342+
343+
**Batch cleanup after a session of PRs:**
344+
345+
```bash
346+
# For each branch whose PR landed, delete the worktree + local branch:
347+
for wt in feature-x bugfix-y sync/template-foo; do
348+
git -C /projects/<repo>/.bare worktree remove --force /projects/<repo>/$wt 2>&1 | tail -1
349+
git -C /projects/<repo>/main branch -D "$wt" 2>&1 | tail -1
350+
done
351+
352+
# Remote-side pruning (delete stale remote-tracking refs):
353+
git -C /projects/<repo>/main fetch --prune origin
354+
```
355+
302356
### Use Cases
303357

304358
```bash

skills/git-workflow/references/commit-conventions.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,4 +436,59 @@ git rebase -i --autosquash main
436436
4. **Reference issues**: Link commits to project management
437437
5. **Use scopes consistently**: Help with changelog generation
438438
6. **Don't include generated files**: Keep commits focused on source changes
439-
7. **Sign commits** (optional): Verify authorship with GPG
439+
7. **Always sign + signoff**: `git commit -S --signoff` — see next section
440+
441+
## Signed Commits + DCO Sign-Off (Required)
442+
443+
Run every commit with both flags explicit:
444+
445+
```bash
446+
git commit -S --signoff -m "feat: add login endpoint"
447+
```
448+
449+
**Why explicit `-S`.** Even with `commit.gpgsign=true` set globally, signing can silently fail in subprocess environments where the SSH agent isn't accessible. An explicit `-S` makes that failure visible instead of shipping an unsigned commit and finding out when branch protection rejects the push.
450+
451+
**Why `--signoff`.** Adds the `Signed-off-by:` trailer. Required for DCO compliance on any repo that has the DCO check enabled (most netresearch repos do).
452+
453+
**Sign-off identity must match `git config user.{name,email}`.** Mismatched identities fail the DCO check with an unhelpful "signoff required" error. Check before the first commit in a new worktree:
454+
455+
```bash
456+
git config user.name
457+
git config user.email
458+
```
459+
460+
**Never amend a commit with pre-commit-hook failures.** If the pre-commit hook fails, the commit **did not happen**. Running `git commit --amend` then modifies the PREVIOUS commit, which can destroy work. Fix the hook issue, re-stage, and create a new commit.
461+
462+
**Never skip hooks** unless explicitly told to. `--no-verify`, `--no-gpg-sign`, and `-c commit.gpgsign=false` all bypass enforcement that exists for good reasons. If a hook fails, diagnose the root cause.
463+
464+
## Atomic Commits
465+
466+
Each commit should be a **single, self-contained logical change** that builds and passes tests independently.
467+
468+
**Good:**
469+
470+
- `feat: add user authentication endpoint` (one feature, complete)
471+
- `fix: correct SAML attribute name mapping` (one bug, fixed)
472+
- `chore(deps): bump go-ldap/ldap/v3 from 3.4.8 to 3.4.11` (one bump)
473+
474+
**Bad:**
475+
476+
- `feat: add auth + fix typo + update deps` (three unrelated concerns)
477+
- `wip` / `fixup` (leftover scratch commits)
478+
479+
Rewrite messy history before opening the PR:
480+
481+
```bash
482+
git rebase -i main # interactive, squash / reword / reorder
483+
git rebase -i --autosquash main # auto-pick fixup!/squash! commits
484+
```
485+
486+
## Push Upstream on First Push
487+
488+
When pushing a new branch for the first time, set upstream tracking with `-u`:
489+
490+
```bash
491+
git push -u origin feature-branch
492+
```
493+
494+
This makes subsequent `git pull` / `git push` work without specifying remote+branch. Without `-u`, everyone who clones the branch later has to set it up themselves.

0 commit comments

Comments
 (0)