12 KiB
SVN Guidelines — AgMission Project
Reference for daily SVN workflow, branching, merging, and common commands. Repo root:
https://svn.agnav.com:8443/svn/AgMission
Table of Contents
- Repository Layout
- Daily Workflow
- Branching
- Keeping a Branch in Sync with Trunk
- Merging a Branch into Trunk (Reintegrate)
- After Reintegrate: Branch Lifecycle
- Resolving Conflicts
- Common Commands Reference
- Best Practices and What to Avoid
1. Repository Layout
graph TD
ROOT["AgMission/ — repo root"]
ROOT --> T["trunk/"]
ROOT --> B["branches/"]
ROOT --> G["tags/"]
T --> DEV["Development/<br/>stable · always deployable"]
B --> SR["satloc-resume/<br/>spent — reintegrated"]
B --> DEA["data-export-api/<br/>active feature branch"]
B --> JI["job-invoicing/<br/>active feature branch"]
G --> R321["release-3.2.1/<br/>immutable snapshot"]
style DEV fill:#c8e6c9,stroke:#388e3c
style SR fill:#ffcdd2,stroke:#c62828
style DEA fill:#fff9c4,stroke:#f9a825
style JI fill:#fff9c4,stroke:#f9a825
style R321 fill:#e1bee7,stroke:#7b1fa2
Rules:
trunk/Developmentis always deployable. Never commit broken code directly here.- Each significant feature or release cycle gets its own branch.
- Tags are read-only snapshots — never commit to a tag.
2. Daily Workflow
Start of day — update your working copy
# Update the branch you're actively working in
cd /path/to/AgMission/branches/data-export-api
svn update
# Also update trunk if you need to reference it
cd /path/to/AgMission/trunk/Development
svn update
Check what you've changed
svn status # show all local changes (M=modified, A=added, D=deleted, ?=unversioned)
svn status -q # quiet: versioned changes only (excludes ? files)
svn diff # full diff of all changes
svn diff path/to/file # diff of a specific file
Stage and commit
SVN has no staging area — svn commit sends everything marked for change.
# Commit all pending changes
svn commit -m "Meaningful commit message describing WHAT and WHY"
# Commit specific files only
svn commit file1.js file2.js -m "Fix X in file1 and Y in file2"
Commit message format (recommended):
#<ticket> Short summary (imperative mood)
- Detail line 1
- Detail line 2
End of day — make sure nothing is left uncommitted
svn status -q # should return nothing if all work is committed
3. Branching
Create a new feature branch from trunk
# Server-side copy — instant, no data transferred
svn copy ^/trunk/Development ^/branches/my-feature \
-m "Create my-feature branch from trunk rXXX"
# Then check it out locally (if your working copy doesn't cover /branches/)
svn update branches/my-feature
Create a release tag
svn copy ^/trunk/Development ^/tags/release-X.Y.Z \
-m "Tag release X.Y.Z"
Delete a branch (after reintegrate — see §6)
svn delete ^/branches/my-feature \
-m "Remove spent my-feature branch post-reintegrate"
4. Keeping a Branch in Sync with Trunk
Do this regularly (at least weekly, or whenever trunk has significant commits) to keep the branch up to date and avoid large conflict batches at reintegrate time.
# From inside your feature branch working copy
cd branches/my-feature
svn update # make sure WC is current
svn merge ^/trunk/Development # merge trunk changes into branch
# resolve any conflicts (see §7)
svn commit -m "Sync trunk rXXX into my-feature"
⚠️ Never use
--record-onlyfor a routine sync.--record-onlyskips applying file changes and only updates mergeinfo. Use it only to fix mergeinfo bookkeeping gaps caused by very old revisions that predate the branch and have no content relevance. Using it incorrectly will silently discard real changes from trunk.
5. Merging a Branch into Trunk (Reintegrate)
SVN 1.8+ detects reintegration automatically. You do not need --reintegrate
(deprecated in 1.8, no-op in 1.14).
Prerequisites
- The branch must have been fully synced with trunk (§4) and that sync committed.
- Your trunk working copy must be clean (
svn status -qreturns nothing). - No local modifications in trunk WC.
# 1. Sync branch one last time (if there are recent trunk commits)
cd branches/my-feature
svn update
svn merge ^/trunk/Development
svn commit -m "Final trunk sync before reintegrate"
# 2. Switch to trunk and update
cd ../../trunk/Development
svn update
# 3. Run the reintegrate merge
svn merge ^/branches/my-feature
# SVN auto-detects this as reintegrate direction (branch → trunk)
# 4. Review and resolve any conflicts (see §7)
svn status
svn diff
# 5. Syntax-check JS files if applicable
node --check server/path/to/changed.js
# 6. Commit the merge
svn commit -m "Merge my-feature into trunk (reintegrate r1000-rXXX)"
What a reintegrate does
%%{init: {'gitGraph': {'mainBranchName': 'trunk', 'rotateCommitLabel': false}}}%%
gitGraph
commit id: "r999 — branch point"
branch my-feature
checkout my-feature
commit id: "r1001 feature work"
commit id: "r1002 feature work"
checkout trunk
commit id: "r1003 trunk work"
checkout my-feature
merge trunk id: "r1010 sync from trunk"
commit id: "r1050 final feature commit"
checkout trunk
merge my-feature id: "r1051 reintegrate"
SVN applies only the revisions from the branch that haven't already been merged to trunk
(tracked via svn:mergeinfo). After the reintegrate commit, the branch is spent — see §6.
6. After Reintegrate: Branch Lifecycle
A reintegrated branch is spent — its mergeinfo record says "all revisions merged." Do not continue developing on it; create a fresh branch from trunk instead.
stateDiagram-v2
direction LR
[*] --> Active : svn copy from trunk
Active --> Active : commit feature work
Active --> Syncing : svn merge trunk (weekly)
Syncing --> Active : conflicts resolved + committed
Active --> Reintegrating : feature complete
Reintegrating --> Spent : merge committed to trunk
Spent --> [*] : tag + svn delete
note right of Syncing
Never use --record-only
for routine syncs
end note
note right of Spent
Always tag before
deleting the branch
end note
# Optional: tag the branch state before deleting
svn copy ^/branches/my-feature ^/tags/my-feature-merged-rXXX \
-m "Tag my-feature before deletion"
# Delete the branch from the repository
svn delete ^/branches/my-feature \
-m "Remove spent my-feature branch post-reintegrate (rXXX)"
# Remove it from your local working copy
svn update # this will remove the local branches/my-feature directory
7. Resolving Conflicts
Listing conflicts
svn status | grep "^C\|^.C" # text conflicts (C) and tree conflicts
Text conflict — manual resolution
# Edit the file and fix conflict markers (<<<<, ====, >>>>)
# Then mark as resolved
svn resolve --accept working path/to/file.js
Text conflict — accept one side wholesale
svn resolve --accept mine-full path/to/file # keep your local version
svn resolve --accept theirs-full path/to/file # take incoming version entirely
Tree conflict (directory added/deleted/replaced)
svn info path/to/dir # read the conflict description
# After deciding what to keep:
svn resolve --accept working path/to/dir # keep local (working copy) state
After resolving all conflicts
svn status | grep "^C" # should return nothing
svn commit -m "Resolve merge conflicts"
8. Common Commands Reference
Information
| Command | What it does |
|---|---|
svn info |
Show WC path, URL, revision, last-changed info |
svn info ^/branches/my-feature |
Info on a repo path (no checkout needed) |
svn log --limit 10 |
Last 10 commits on current path |
svn log ^/trunk/Development --limit 5 |
Last 5 commits on trunk |
svn log -v --limit 3 |
Commits with list of changed files |
svn blame file.js |
Show author/revision per line |
Status & diff
| Command | What it does |
|---|---|
svn status |
All local changes (M, A, D, ?, C) |
svn status -q |
Versioned changes only |
svn diff |
Full diff of local changes |
svn diff -r HEAD |
Diff against HEAD revision |
svn diff ^/trunk/Development ^/branches/my-feature |
Diff two repo paths |
Update & revert
| Command | What it does |
|---|---|
svn update |
Bring WC up to latest revision |
svn update -r 993 |
Update to a specific revision |
svn revert file.js |
Discard local changes to one file |
svn revert -R . |
Discard ALL local changes recursively |
Add / remove
| Command | What it does |
|---|---|
svn add newfile.js |
Schedule new file for versioning |
svn add --force new-dir/ |
Add entire new directory |
svn delete file.js |
Schedule file for deletion |
svn delete ^/branches/old-branch -m "msg" |
Delete repo path directly |
Merge
| Command | What it does |
|---|---|
svn merge ^/trunk/Development |
Sync trunk into current branch (run from branch WC) |
svn merge ^/branches/my-feature |
Reintegrate branch into trunk (run from trunk WC) |
svn merge ^/trunk/Development --dry-run |
Preview merge without applying |
svn merge --record-only ^/trunk/Development |
Fix mergeinfo gaps only — no file changes |
svn mergeinfo ^/branches/my-feature |
Show what has/hasn't been merged |
Copy / branch / tag
| Command | What it does |
|---|---|
svn copy ^/trunk/Development ^/branches/new -m "msg" |
Create branch |
svn copy ^/trunk/Development ^/tags/v1.0 -m "msg" |
Create tag |
svn copy ^/branches/old ^/branches/new -m "msg" |
Copy branch |
9. Best Practices and What to Avoid
✅ Do
- Commit often with small, focused commits and meaningful messages.
- Sync trunk into your branch regularly (
svn merge ^/trunk/Development) — at least weekly. Early, small syncs are far easier to resolve than one big sync at reintegrate time. - Run
svn updatebefore every commit to catch conflicts early. - Syntax-check JS files before committing:
node --check path/to/file.js - Use
--dry-runon any merge to preview the result before applying. - Tag releases before merging or deleting branches.
- Delete spent branches to keep the branch list clean.
- Keep unversioned files out of the WC — use
.svnignoreor the globalglobal-ignoressetting.
❌ Avoid
| Mistake | Why | Instead |
|---|---|---|
| Committing directly to trunk | Breaks other developers; trunk must stay stable | Work on a feature branch |
--record-only on a routine sync |
Silently skips real trunk changes → content drift | Only use to fix bookkeeping gaps on very old revisions |
| Letting a branch go unsynced for months | Massive conflict blast at reintegrate | Sync from trunk weekly |
| Continuing to develop on a spent (reintegrated) branch | SVN mergeinfo considers all revisions merged; new commits will be missed on next merge | Create a new branch from trunk |
svn revert -R . without a backup |
Permanent loss of uncommitted work | Back up modified files first, or stash with a patch: svn diff > my.patch |
| Committing secrets/credentials | Irrecoverable from SVN history without admin intervention | Use .env files excluded by svnignore |
Saving work-in-progress without committing
SVN has no git stash. Use a patch file instead:
svn diff > /tmp/my-wip.patch # save all local changes
svn revert -R . # clean the WC
# ... do the other work, commit it ...
patch -p0 < /tmp/my-wip.patch # reapply your WIP
Setting up global ignores (one-time, per machine)
Add to ~/.subversion/config under [miscellany]:
global-ignores = *.o *.so *.log node_modules .env *.swp .DS_Store .specstory
Last updated: April 2026 — AgMission / AgNav