16 KiB
Project Velocity — Gitea Feature Contribution Guide
Version: 1.1
Last Updated: 2026-03-07
Upstream Repository (Sagnik's): https://git.desineuron.in/sagnik/Project_Velocity
Your Fork: https://git.desineuron.in/<YOUR_USERNAME>/Project_Velocity
This document is the canonical guide for every team member contributing to Project Velocity.
The team uses a Fork-based workflow: each contributor has their own fork of Sagnik's repository. All features are developed in your fork and merged into the upstream via Pull Requests.
It covers the full lifecycle: Issue → Branch → Commit → Push → Pull Request — both via the CLI and via Antigravity Source Control UI.
How the Fork Model Works
[upstream] sagnik/Project_Velocity ← the source of truth
↑ Pull Requests
[your fork] <you>/Project_Velocity ← where you develop
↑ git push
[local] /your/machine/Project_Velocity
upstream= Sagnik's repo — you pull from here to stay in sync.origin= Your fork — you push your branches here.- PRs go from your fork → upstream.
Table of Contents
- Naming Conventions
- One-Time Setup — Fork & Remotes
- Step 0 — Pre-flight: Populate
.gitignore&.gitkeep - Step 1 — Create a Gitea Issue
- Step 2 — Sync with Upstream Before Branching
- Step 3 — Create a Feature Branch
- Step 4 — Make Your Changes & Commit
- Step 5 — Push the Branch to Your Fork
- Step 6 — Create a Pull Request (Fork → Upstream)
- Quick Reference — CLI Cheat Sheet
Naming Conventions
Consistent naming keeps the repository clean and makes history easy to read.
| Type | Format | Example |
|---|---|---|
| Issue Title | feat : <Short description> |
feat : Build the native SwiftUI app shell |
| Branch Name | feat/#<issue-number> |
feat/#12 |
| Commit Message | feat(scope): <what changed> or fix(scope): <what was fixed> |
feat(ios): add Dashboard, Oracle and Sentinel tab views |
Use
fix,chore,docs,refactor, ortestinstead offeatwhere appropriate.
One-Time Setup — Fork & Remotes
Do this once when you first clone your fork onto a new machine. You only need to do this once per machine.
1. Clone your fork
git clone https://git.desineuron.in/<YOUR_USERNAME>/Project_Velocity.git
cd Project_Velocity
2. Add the upstream remote (Sagnik's repo)
git remote add upstream https://git.desineuron.in/sagnik/Project_Velocity.git
3. Verify your remotes
git remote -v
You should see two remotes:
origin https://git.desineuron.in/<YOUR_USERNAME>/Project_Velocity.git (fetch)
origin https://git.desineuron.in/<YOUR_USERNAME>/Project_Velocity.git (push)
upstream https://git.desineuron.in/sagnik/Project_Velocity.git (fetch)
upstream https://git.desineuron.in/sagnik/Project_Velocity.git (push)
⚠️ If you only see
origin, you haven't addedupstreamyet. Run step 2 above.
Via Antigravity Source Control UI
Antigravity does not have a direct UI button to add a new remote. Do this once via the terminal:
- Open a terminal inside Antigravity (
Ctrl + ````). - Run:
git remote add upstream https://git.desineuron.in/sagnik/Project_Velocity.git - The upstream remote will now appear in the Graph section of Source Control.
Step 0 — Pre-flight
Before pushing anything, ensure these files are properly configured at the root of the repository.
.gitignore
A root .gitignore already exists at the repository root. It covers:
- macOS system files (
DS_Store, etc.) - Node / Vite / React (
app/node_modules/,app/dist/) - Xcode / Swift (derived data,
.xcuserdata, build artifacts) - Python / ComfyUI (
__pycache__,.venv, model weights) - Infrastructure (Terraform state, secrets)
You should never commit:
- API keys or secrets (
.envfiles are ignored) node_modules/directory- Xcode
DerivedData/or.xcuserdata/ - Python virtual environments (
.venv/,venv/)
.gitkeep
A .gitkeep file is used to track an otherwise empty directory in Git (Git does not track empty folders).
When to add one: If you create a new directory that should be committed but has no files yet, add an empty .gitkeep file inside it:
touch path/to/your/new-empty-folder/.gitkeep
Step 1 — Create a Gitea Issue
Every feature or bug fix must start with a Gitea Issue. Issues must be created in Sagnik's upstream repository — not your fork. The upstream is the source of truth for the project, and Closes #<N> in your PR description will only auto-close the issue if it lives in the same repo your PR targets.
Via Browser (Gitea Web UI)
- Go to Sagnik's upstream repo:
https://git.desineuron.in/sagnik/Project_Velocity. - Click on the Issues tab.
- Click the green New Issue button.
- Fill in the title using the format:
Example:
feat : <Short description of your feature>feat : Build the native SwiftUI app shell mirroring the WebOS interface - Add a description explaining:
- What you are building.
- Why it is needed.
- Acceptance criteria (what "done" looks like).
- Assign the issue to yourself.
- Click Submit. Note down the Issue Number (e.g.,
#12) — you will need it for the branch name.
Via CLI (using curl or Gitea API)
# Replace placeholders before running
GITEA_URL="https://git.desineuron.in"
GITEA_TOKEN="<YOUR_PERSONAL_ACCESS_TOKEN>" # Generate at: Profile → Settings → Applications
REPO_OWNER="sagnik" # Issues go in the UPSTREAM repo
REPO_NAME="Project_Velocity"
ISSUE_TITLE="feat : <Short description of your feature>"
ISSUE_BODY="<Detailed description of what you are building and why>"
curl -s -X POST "$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/issues" \
-H "Content-Type: application/json" \
-H "Authorization: token $GITEA_TOKEN" \
-d "{
\"title\": \"$ISSUE_TITLE\",
\"body\": \"$ISSUE_BODY\",
\"assignees\": [\"$REPO_OWNER\"]
}"
The response JSON will contain the
numberfield — this is your issue number.
Step 2 — Sync with Upstream Before Branching
Before creating a feature branch, always pull the latest changes from upstream (Sagnik's repo) — not from your fork (origin). This ensures your work starts from the most up-to-date version of the project.
Via CLI
# Navigate to your project root
cd "/path/to/Project_Velocity"
# Switch to main
git checkout main
# Fetch all branches from upstream
git fetch upstream
# Merge upstream/main into your local main
git merge upstream/main
# (Optional) Push the synced main to your own fork to keep it up to date
git push origin main
Why
upstreamand notorigin?
originis your personal fork — it only knows about changes you've pushed.
upstreamis Sagnik's repository — the actual source of truth for the project.
Via Antigravity Source Control UI
Antigravity's sync button pulls from origin by default. To sync from upstream, use the terminal:
- Open a terminal in Antigravity (
Ctrl + ````). - Run:
git fetch upstream && git merge upstream/main - Then click the ↺ (Refresh) icon in the Source Control panel to refresh the view.
- Confirm the Graph section shows your local
mainis aligned withupstream/main.
Step 3 — Create a Feature Branch
Branch name format: feat/#<ISSUE_NUMBER>
IMPORTANT: Replace <ISSUE_NUMBER> with the actual number from Step 1.
Via CLI
# Make sure you are on main first
git checkout main
# Create and switch to the new branch
git checkout -b feat/#<ISSUE_NUMBER>
# Example:
# git checkout -b feat/#12
Via Antigravity Source Control UI
- In the Source Control panel, look at the bottom Graph section.
- Click on the branch name shown next to the current
HEADcommit (e.g.,main). - A branch picker will appear at the top of the screen.
- Type the new branch name exactly:
feat/#<ISSUE_NUMBER> - Select "Create new branch: feat/#<ISSUE_NUMBER>" from the dropdown.
- Confirm. Your working branch is now set to the new feature branch.
Step 4 — Make Your Changes & Commit
Stage Your Files
Via CLI
# Stage specific files
git add path/to/changed/file.swift
# Stage all changed/new files at once (use with care)
git add .
# Review what is staged before committing
git status
Via Antigravity Source Control UI
- In the Source Control panel, you will see two sections:
- Staged Changes — files ready to be committed.
- Changes — files that are modified but not yet staged.
- To stage a file: Hover over it in the Changes section and click the
+(plus) icon that appears on the right. - To unstage a file: Hover over it in Staged Changes and click the
-(minus) icon. - To stage all changes at once: Click the
+(plus) icon next to the Changes section header.
Write Your Commit Message
Use the Conventional Commits format:
<type>(scope): <short summary>
| Type | When to Use |
|---|---|
feat |
A new feature |
fix |
A bug fix |
docs |
Documentation changes only |
refactor |
Code restructured, no behavior change |
chore |
Config, build scripts, dependencies |
test |
Adding or fixing tests |
Example commit messages:
feat(ios): add Dashboard, Oracle, Sentinel, and Inventory tab views
feat(ios): implement AppStore with lead, visitor, and metrics models
fix(ios): correct ARSunOverlayView coordinate calculations
docs(agent): add velocity_ios_bible.md technical reference
Commit
Via CLI
git commit -m "<type>(scope): <short summary of your change>"
# Example:
# git commit -m "feat(ios): add Dashboard, Oracle, Sentinel tab views mirroring WebOS"
Via Antigravity Source Control UI
- Ensure your files are in the Staged Changes section.
- Click the Message text field at the top of the Source Control panel (placeholder:
Message (⌘Enter to com...)). - Type your commit message following the Conventional Commits format above.
- (Optional) Click Generate ✦ to let Antigravity AI suggest a commit message based on your staged diffs — review it before accepting.
- Click the blue ✓ Commit button (or press
⌘ + Enter) to commit.
Step 5 — Push the Branch to Gitea
Via CLI
# Push your feature branch to the remote (origin)
git push origin feat/#<ISSUE_NUMBER>
# Example:
# git push origin feat/#12
If this is the first push of a new branch, Git may ask you to set the upstream:
git push --set-upstream origin feat/#<ISSUE_NUMBER>
Via Antigravity Source Control UI
- After committing, look at the Changes header in the Source Control panel.
- Click the
...(More Actions) menu (top-right of the Changes section header). - Select Push from the dropdown.
- Alternatively, click the ↑ (Publish/Push) cloud icon if visible next to the branch name in the status bar or Graph section.
- Antigravity will push your local feature branch to
origin/feat/#<ISSUE_NUMBER>on Gitea.
Step 6 — Create a Pull Request (Fork → Upstream)
Since you are working on a fork, your PR goes from your fork's feature branch → Sagnik's upstream main. This is a cross-repository PR.
Via Browser (Gitea Web UI)
- Go to Sagnik's upstream repo:
https://git.desineuron.in/sagnik/Project_Velocity. - Click the Pull Requests tab → New Pull Request.
- Click "compare across forks" (Gitea shows this option when creating a cross-fork PR).
- Set up the PR direction:
- Base repository:
sagnik/Project_Velocity— Base branch:main - Head repository:
<YOUR_USERNAME>/Project_Velocity— Compare branch:feat/#<ISSUE_NUMBER>
- Base repository:
- Fill in the PR form:
- Title:
feat(scope): <Short description> - Description:
## Summary <What does this PR do?> ## Changes - <List the main changes> ## Related Issue Closes #<ISSUE_NUMBER> - Title:
- Assign Sagnik as reviewer.
- Click Create Pull Request.
💡 Alternatively, after you push your branch to your fork (
origin), Gitea may show a yellow banner inside Sagnik's upstream repo prompting you to create a cross-fork PR automatically. Click that if it appears.
Via CLI (using Gitea API)
For a cross-fork PR, the head must include your fork username as a prefix.
GITEA_URL="https://git.desineuron.in"
GITEA_TOKEN="<YOUR_PERSONAL_ACCESS_TOKEN>"
UPSTREAM_OWNER="sagnik" # Sagnik's username
UPSTREAM_REPO="Project_Velocity"
YOUR_USERNAME="<YOUR_USERNAME>" # Your Gitea username
FEATURE_BRANCH="feat/#<ISSUE_NUMBER>"
PR_TITLE="feat(scope): <Short description>"
PR_BODY="## Summary\n<What does this PR do?>\n\n## Changes\n- <List main changes>\n\n## Related Issue\nCloses #<ISSUE_NUMBER>"
curl -s -X POST "$GITEA_URL/api/v1/repos/$UPSTREAM_OWNER/$UPSTREAM_REPO/pulls" \
-H "Content-Type: application/json" \
-H "Authorization: token $GITEA_TOKEN" \
-d "{
\"title\": \"$PR_TITLE\",
\"body\": \"$PR_BODY\",
\"head\": \"$YOUR_USERNAME:$FEATURE_BRANCH\",
\"base\": \"main\"
}"
Note the
headformat:"<YOUR_USERNAME>:feat/#<ISSUE_NUMBER>"— this tells Gitea the branch lives in your fork, not the upstream.
Quick Reference — CLI Cheat Sheet
Copy and fill in the placeholders (<...>) before running.
# ── ONE-TIME SETUP (do this once per machine) ─────────────────
cd "/path/to/Project_Velocity"
git remote add upstream https://git.desineuron.in/sagnik/Project_Velocity.git
git remote -v # verify: you should see both origin and upstream
# ── 1. Create the Gitea Issue ──────────────────────────────────
# Go to Gitea web UI or use the curl command in Step 1
# Title format: feat : <Short description>
# Note the issue number: <ISSUE_NUMBER>
# ── 2. Sync from upstream main ────────────────────────────────
git checkout main
git fetch upstream
git merge upstream/main
git push origin main # keep your fork in sync too
# ── 3. Create & switch to feature branch ─────────────────────
git checkout -b feat/#<ISSUE_NUMBER>
# ── 4. Stage & Commit ─────────────────────────────────────────
git add .
git status # double-check what is staged
git commit -m "<type>(scope): <short summary>"
# ── 5. Push branch to YOUR FORK (origin) ──────────────────────
git push origin feat/#<ISSUE_NUMBER>
# ── 6. Create Pull Request (fork → upstream) ──────────────────
# Go to: https://git.desineuron.in/sagnik/Project_Velocity
# Pull Requests → New Pull Request → Compare across forks
# head: <YOUR_USERNAME>/Project_Velocity : feat/#<ISSUE_NUMBER>
# base: sagnik/Project_Velocity : main
Tips & Best Practices
- One issue = one branch = one PR. Keep your changes focused.
- Always sync from
upstream, notorigin. Your fork doesn't automatically know about changes Sagnik pushes. Rungit fetch upstream && git merge upstream/mainregularly. - Commit often, push when ready. Small commits make code review easier.
- Never commit directly to
main. Always work on a feature branch. - Push to
origin, PR toupstream. Push goes to your fork. The PR targets Sagnik's repo. - Reference issues in PRs. Using
Closes #<ISSUE_NUMBER>auto-closes the issue on merge. - Personal Access Token: Generate it once at
https://git.desineuron.in→ Profile → Settings → Applications → Generate Token. Store it securely (e.g., in your password manager or macOS Keychain). - Keep your fork's
mainclean. Never push feature work directly toorigin/main— only mergeupstream/maininto it to stay current.