git workflow mode: CLEAN HISTORY, CLEAR INTENT
when this skill is active, you follow disciplined git practices. this is a comprehensive guide to professional version control.
PHASE 0: ENVIRONMENT VERIFICATION
before doing ANY git operations, verify your configuration.
verify git is installed
git --version
if git not installed: macOS: brew install git
linux: sudo apt install git sudo yum install git
windows: winget install Git.Git
verify git identity
git config --global user.name
git config --global user.email
if not configured:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
critical: use your real email. your identity is part of the permanent record.
verify default branch
git config --global init.defaultBranch
if not set:
git config --global init.defaultBranch main
modern standard: main, not master.
verify useful defaults
git config --global core.autocrlf
macOS/Linux: git config --global core.autocrlf input
windows: git config --global core.autocrlf true
enable helpful options
git config --global core.quotePath false
git config --global init.defaultBranch main
git config --global rebase.autoStash true
git config --global push.autoSetupRemote true
verify remote access
git remote -v
if no remote: [warn] working without backup [warn] push to remote frequently
if remote exists, verify access: git ls-remote origin
verify current repository state
git status
git branch --show-current
git log --oneline -5
understand where you are before making changes.
PHASE 1: GIT FUNDAMENTALS
the three states
working directory -> staging area -> repository
working directory: your actual files staging area: files prepared for commit repository: committed history
git status
shows: which files are in which state
the basic commands
add: move file from working to staging git add filename.py
commit: move from staging to repository git commit -m "message"
status: see what state files are in git status
diff: see what changed git diff # working vs staging git diff --staged # staging vs repository
reading git status
$ git status On branch main Your branch is up to date with 'origin/main'.
Changes not staged for commit: modified: app.py modified: utils.py
Untracked files: new_file.py
breakdown: - on branch main: current branch - up to date: local matches origin - modified: changed but not staged - untracked: new file, not tracked
PHASE 2: BRANCHING STRATEGY
why branch
branches enable:
- parallel work
- isolation of changes
- safe experimentation
- code review before merge
branch naming conventions
feature work: feature/add-user-authentication feature/payment-processing feat/shopping-cart
bug fixes: bugfix/login-timeout fix/memory-leak hotfix/security-patch
chores: refactor/user-module chore/update-dependencies docs/api-endpoints test/add-user-tests
release: release/v1.2.0 prepare-release/v1.0.0
create a branch
git checkout -b feature/add-user-auth
equivalent: git branch feature/add-user-auth git checkout feature/add-user-auth
list branches
git branch
git branch -a # show remote too git branch -vv # show tracking info
switch branches
git checkout main
git switch feature/add-user-auth
note: git switch is newer, more intuitive
delete branches
local: git branch -d feature/complete
force delete (unmerged): git branch -D feature/experimental
remote: git push origin --delete feature/complete
PHASE 3: THE COMMIT HABIT
what makes a good commit
[ok] small, focused change [ok] complete (works, tests pass) [ok] clear message explaining why [x] large, sweeping changes [x] broken code (WIP commits) [x] vague messages ("update", "fix stuff") [x] multiple unrelated changes
commit message format
subject line (50 chars or less): - imperative mood ("add" not "added" or "adds") - complete sentence - no trailing period
body (optional): - what and why - not how - wrapped at 72 chars
examples:
add user authentication with JWT tokens
implement login and registration endpoints with JWT-based
authentication. passwords are hashed with bcrypt.
fixes #123
refactor: extract user validation to separate module
the validation logic was duplicated across multiple controllers.
extracting to a shared module reduces duplication and makes
testing easier.
fix: prevent null pointer in user lookup
when a user id doesn't exist, the lookup was returning None
without handling, causing a null pointer error. added explicit
check and raise 404 instead.
commit often
after each logical unit: - one function extracted - one test written - one bug fixed
benefits: - easier to revert if needed - clearer history - smaller review chunks
anti-pattern: [x] one giant commit at end of day [x] "work in progress" commits that break tests
amend commits
only for most recent commit: git commit --amend
only for trivial fixes (typos, forgot to add file) never amend pushed commits (rewrites history)
add file to previous commit: git add forgotten_file.py git commit --amend --no-edit
PHASE 4: STAGING AND COMMITTING
interactive staging
stage parts of a file: git add -p filename.py
prompts for each hunk: - y: stage this hunk - n: don't stage this hunk - s: split into smaller hunks - q: quit
useful when: - file has multiple unrelated changes - want atomic commits
stage by file
stage specific files: git add app.py utils.py
stage all changes: git add .
careful: stages everything review first with: git status
unstage files
git restore --staged filename.py
or: git reset HEAD filename.py
moves from staging back to working directory
discard working changes
git restore filename.py
or: git checkout -- filename.py
warning: destroys changes be certain you don't need them
PHASE 5: MERGE VS REBASE
when to merge
use merge when:
- preserving complete history
- working on shared branch
- want explicit merge commit
git checkout main git merge feature/new-auth
creates merge commit combining histories.
when to rebase
use rebase when:
- cleaning up local branch before push
- linear history preferred
- integrating upstream changes
git checkout feature/new-auth git rebase main
reapplies your commits on top of main.
golden rules
[1] never rebase pushed commits rebase rewrites history others may have based work on those commits rebase = trouble for collaborators
[2] never rebase shared branches main, develop, release branches only rebase your local feature branches
[3] force push with caution only after rebase only to your own branches git push --force-with-lease
PHASE 6: HANDLING MERGE CONFLICTS
conflict markers
when git can't auto-merge:
<<<<<<< HEAD current branch content
incoming branch content
feature-branch
you decide which to keep, or combine both.
resolution process
[1] identify conflict git status
shows "both modified" files
[2] open file in editor find conflict markers understand what each side does
[3] resolve conflict choose: - keep HEAD (current) - keep incoming - combine both - write new solution
[4] remove markers delete <<<<<<<, =======, >>>>>>>
[5] stage resolution git add resolved_file.py
[6] complete merge/rebase git commit # for merge git rebase --continue # for rebase
conflict resolution tools
use merge tool: git mergetool
configure: git config --global merge.tool vscode git config --global mergetool.vscode.cmd 'code --wait $MERGED'
abort on trouble
abort merge: git merge --abort
abort rebase: git rebase --abort
returns to state before operation.
PHASE 7: SYNCING WITH REMOTE
fetch vs pull
fetch: get remote changes, don't merge git fetch origin
safe, lets you review before integrating
pull: fetch and merge in one step git pull
convenient but creates merge commit
pull with rebase: git pull --rebase
cleaner history, reapplies your work on top
push branches
first push (set upstream): git push -u origin feature/new-auth
subsequent pushes: git push
with autoSetupRemote configured: git push # sets upstream automatically
update local branch
when remote has updates:
git fetch origin git rebase origin/main
or: git pull --rebase
before starting work
always start from latest: git checkout main git pull git checkout -b feature/new-work
prevents merge conflicts later
PHASE 8: INSPECTING HISTORY
view commits
recent commits: git log
one line per commit: git log --oneline
with graph: git log --oneline --graph --all
pretty format: git log --pretty=format:"%h %ad | %s" --date=short
view specific commit
show commit details: git show abc123
show file at commit: git show abc123:path/to/file.py
view changes
diff between commits: git diff abc123 def456
diff between branches: git diff main feature
what changed in file: git log -p filename.py
blame: who changed what
git blame filename.py
shows each line with commit and author.
specific line range: git blame -L 50,60 filename.py
PHASE 9: UNDOING CHANGES
undo working directory changes
discard all changes: git restore .
discard specific file: git restore filename.py
warning: cannot be undone
undo staged changes
unstage file: git restore --staged filename.py
unstage all: git restore --staged .
undo commits (not pushed)
remove last commit, keep changes: git reset --soft HEAD~1
remove last commit, discard changes: git reset --hard HEAD~1
go back to specific commit: git reset --hard abc123
undo pushed commits
create reversal commit: git revert abc123
reverts changes in new commit. safe for shared history.
PHASE 10: STASHING
when to stash
temporarily save work when:
- need to switch branches
- want to pull latest changes
- need to test something else
stash is a stack of temporary commits
basic stash
git stash
saves working directory and index. returns to clean state.
view stashes
git stash list
stash@{0}: On main: add user login stash@{1}: On feature: WIP on authentication
apply stash
git stash apply
applies most recent stash, keeps it in list.
apply specific stash: git stash apply stash@{1}
drop stash
git stash drop
or combine: git stash pop
applies and removes most recent stash.
stash with message
git stash save "work on user auth"
helpful for identifying stashes later
stash specific files
git stash push -m "config changes" config.json
only stashes specified file
PHASE 11: TAGGING
when to tag
mark releases:
- v1.0.0
- v1.1.0
- v2.0.0
tag production deployments tag significant milestones
create tags
annotated (recommended): git tag -a v1.0.0 -m "Release version 1.0.0"
lightweight: git tag v1.0.0
annotated tags have message, date, author.
view tags
list all tags: git tag
show tag details: git show v1.0.0
push tags
push specific tag: git push origin v1.0.0
push all tags: git push origin --tags
delete tags
local: git tag -d v1.0.0
remote: git push origin --delete v1.0.0
checkout tags
view code at tag: git checkout v1.0.0
creates detached HEAD state. to work, create a branch: git checkout -b patch-1.0.1 v1.0.0
PHASE 12: GITIGNORE
what to ignore
never commit:
- dependencies/ (node_modules, venv, pycache)
- build artifacts (.pyc, .o, .dll)
- environment files (.env, .env.local)
- ide settings (.idea/, .vscode/)
- os files (.DS_Store, Thumbs.db)
- logs (*.log)
- temporary files (*.tmp, *.swp)
create .gitignore
cat > .gitignore << 'EOF'
python
pycache/ *.py[cod] *$py.class .venv/ venv/ *.egg-info/
environment
.env .env.local .env.*.local
ide
.idea/ .vscode/ *.swp *.swo
os
.DS_Store Thumbs.db
logs
*.log logs/
testing
.coverage htmlcov/ .pytest_cache/
build
dist/ build/ *.egg EOF
existing .gitignore not working
files already tracked must be removed: git rm --cached filename
for directory: git rm -r --cached directory/
then commit.
ignore tracked file locally
git update-index --assume-unchanged config.local.json
keeps file locally, ignores for commits.
to undo: git update-index --no-assume-unchanged config.local.json
PHASE 13: COMMON WORKFLOWS
feature branch workflow
update main git checkout main git pull
create feature branch git checkout -b feature/new-feature
do work # ... make changes ... git add . git commit -m "implement feature"
update from main git fetch origin git rebase origin/main
resolve conflicts if any
push git push -u origin feature/new-feature
create pull request
after merge, delete branch git branch -d feature/new-feature
hotfix workflow
create hotfix from main git checkout main git pull git checkout -b hotfix/critical-bug
fix the bug # ... make minimal fix ... git commit -m "fix: critical security issue"
push and create expedited PR git push -u origin hotfix/critical-bug
merge to main immediately git checkout main git merge hotfix/critical-bug git push
tag release git tag -a v1.0.1 -m "Hotfix for security issue" git push origin v1.0.1
PHASE 14: REBASING FOR CLEAN HISTORY
interactive rebase
clean up last N commits: git rebase -i HEAD~3
or: git rebase -i abc123
opens editor with commands:
pick abc1234 first commit pick def5678 second commit pick ghi9012 third commit
commands:
- pick: keep as-is
- reword: edit commit message
- edit: pause for changes
- squash: combine with previous
- fixup: combine with previous, discard message
- drop: remove commit
squash related commits
before: pick abc1234 add user model pick def5678 fix user model typo pick ghi9012 add user validation
after: pick abc1234 add user model fixup def5678 fix user model typo fixup ghi9012 add user validation
result: one commit with message "add user model"
reorder commits
before: pick abc1234 add feature pick def5678 write tests pick ghi9012 add documentation
after: pick def5678 write tests pick abc1234 add feature pick ghi9012 add documentation
helps logical ordering
PHASE 15: RECOVERING FROM MISTAKES
reflog: find lost commits
git reflog
shows all git operations, including lost commits.
find the commit you want: git reflog | grep "commit message"
restore it: git checkout abc123 git checkout -b recovered-branch
recover dropped stash
git fsck --no-reflog | grep "stash"
or: git log --oneline --all --graph --stash
recover: git stash apply abc123
undo force push
if you force pushed and regret it:
find original reflog: git reflog origin/main
reset to before force push: git reset --hard origin/main@{1}
force push again (carefully!): git push --force
recover deleted branch
git reflog | grep "checkout: from"
find where you were: git checkout abc123
recreate branch: git checkout -b feature/lost-branch
PHASE 16: GIT RULES (STRICT MODE)
while this skill is active, these rules are MANDATORY:
[1] NEVER commit broken code tests must pass code must work no "wip" commits that break the build
[2] write meaningful commit messages subject: what changed, imperative mood body: why, if not obvious reference issues: fixes #123
[3] pull before push integrate remote changes first avoid unnecessary merge commits git pull --rebase
[4] never force push to shared branches main, develop, release branches only force push your own feature branches git push --force-with-lease
[5] use branches for all work never commit directly to main feature branches, bugfix branches one branch per logical unit
[6] keep commits atomic one logical change per commit complete and working easy to review and revert
[7] review before committing git diff git status know what you're committing
[8] push frequently backup your work enable code review don't hold changes hostage
PHASE 17: GIT SESSION CHECKLIST
before starting work:
[ ] git status is clean [ ] on correct branch [ ] branch name is descriptive [ ] pulled latest from origin
while working:
[ ] commit often [ ] commit messages are clear [ ] tests pass before commit [ ] pushed to remote periodically
before creating PR:
[ ] branch is up to date with main [ ] rebase if needed [ ] no conflicts [ ] tests pass [ ] code is clean
after merge:
[ ] delete local branch [ ] delete remote branch [ ] pull latest main [ ] ready for next feature
FINAL REMINDERS
git is your safety net
commit frequently push often small changes are easy to fix big changes are scary
the golden rule
if you're unsure what will happen: git status git diff git log --oneline -5
know your state before acting
when in doubt
branch is cheap create one and experiment you can always delete it your work is safe on main
the goal
clean history clear intent easy to understand easy to collaborate
now go commit something great.
Source: kollaborai/kollab — distributed by TomeVault.