Understand version-control concepts, daily workflows, branching strategies, team organization, access permissions, migrating codebases, and securing your repositories for humans and AI agents.
Beginner to advanced40 minute guideReviewed July 26, 2026
What You Will Be Able to Do
Explain what a repository, commit, branch, and merge are in plain language.
Set up Git on your computer and connect to a remote hosting service.
Follow a daily workflow: clone, branch, commit, push, and open a pull request.
Choose a branching strategy that fits your team size and release rhythm.
Write clear commit messages and pull request descriptions.
Fork a repository, keep it in sync with upstream, and submit pull requests from your fork.
Mirror a repository for backups, migration, or offline availability.
Contribute to an existing project by following its contribution guidelines and workflow.
Structure an organization with teams, roles, and access levels.
Configure access permissions for human developers, bots, and autonomous agents.
Migrate existing codebases into a Git provider safely and securely.
Secure repositories with branch protection, secret scanning, and audit controls.
Work with AI coding agents that propose changes, run tests, and open draft PRs.
Review code changes with a structured checklist and leave useful feedback.
Why Version Control Matters
Version control is the system that records every change to your files over time. It answers three questions: what changed, who changed it, and why. Beyond tracking history, it enables collaboration without conflicts, safe experimentation through branches, and reliable rollbacks when something breaks.
Solo projects
You get a full history, free experimentation, and the ability to undo mistakes. Even alone, branches let you try a direction without risking the working code.
Teams of 2-5
Branches isolate work, pull requests surface changes for review, and the merge history documents decisions. Conflicts are resolved before code reaches the main line.
Larger teams and open source
Protected branches, required reviews, CI checks, and release tags keep the codebase stable. The merge history becomes an audit trail for compliance and debugging.
AI-assisted development
AI agents propose changes on branches. You or a reviewer examines the diff, runs tests, and approves. Version control is the safety boundary between agent autonomy and human judgment.
Git is not just for code. Documentation, configuration, design specs, data schemas, and infrastructure definitions all benefit from version control.
Core Concepts and Terminology
Git uses a specific vocabulary. Understanding these terms will make every tutorial, error message, and team conversation clearer.
Term
What it means
Everyday analogy
Repository (repo)
A project folder tracked by Git, containing all files and their complete history.
A filing cabinet with every version of every document.
Commit
A saved snapshot of changes with a message, author, and timestamp.
A dated entry in a lab notebook explaining what you did.
Branch
A named, independent line of development that diverges from and can merge back into other branches.
A parallel storyline you can write without affecting the published version.
Remote
A copy of the repository hosted on a server (GitHub, GitLab, Gitea, etc.) that teams share.
A shared cloud folder everyone can sync with.
Clone
Creating a local copy of a remote repository with full history.
Downloading the entire filing cabinet to your desk.
Push
Uploading your local commits to the remote so others can see them.
Submitting your work to the shared folder.
Pull / Fetch
Downloading commits from the remote. Pull downloads and merges; fetch only downloads.
Checking for updates others have submitted.
Staging area
A middle step where you choose which changes go into the next commit.
A packing box where you select items before sealing the shipment.
Merge
Combining changes from one branch into another.
Weaving two storylines back together.
Pull request (PR)
A proposal to merge one branch into another, with discussion, review, and automated checks.
A formal review request before publishing changes.
Setting Up Git from Zero
1
Install Git
Download from git-scm.com and follow the installer for your operating system. Open a terminal and run git --version to confirm it is installed.
2
Identify yourself
Git records your name and email on every commit. Set them once with:
Use the same email you registered with your hosting provider (GitHub, GitLab, Gitea) so commits are attributed correctly.
3
Choose a hosting provider
Provider
Best for
Notes
GitHub
Open source, large community, Copilot integration
Industry standard; owned by Microsoft
GitLab
Self-hosting, built-in CI/CD, DevOps workflows
Strong for teams wanting full control
Gitea
Lightweight, self-hosted, simple interface
Runs on modest hardware; easy to deploy
Bitbucket
Atlassian ecosystem (Jira, Trello integration)
Free for small private teams
4
Set up authentication
Use SSH keys or personal access tokens—never passwords. Generate an SSH key with ssh-keygen -t ed25519, then add the public key to your hosting provider settings. Test with ssh -T git@github.com (or your provider's equivalent).
5
Create your first repository
On the hosting site, create a new repository. Clone it to your computer:
git clone git@github.com:username/myproject.git
cd myproject
Start adding files, committing, and pushing. Your local folder is now connected to the shared remote.
Avoid the "add a remote later" trap. Initialize the repository on the hosting platform first, then clone. It prevents URL mismatches and gives you immediate web access.
Daily Workflow
This is the cycle you will repeat most days. Think of it as the heartbeat of collaborative development.
1
Pull the latest changes
Before starting work, sync with the remote so you have the current code:
git checkout main
git pull origin main
2
Create a feature branch
Never work directly on main. Create a branch with a descriptive name:
git checkout -b feat/add-contact-form
Branch naming conventions: feat/ for features, fix/ for bug fixes, docs/ for documentation, refactor/ for internal improvements.
3
Make changes and commit
Stage the files you want to include, then commit with a clear message:
git add src/contact.html src/contact.css
git commit -m "Add contact form with validation"
Write commit messages in imperative mood: "Add contact form" not "Added contact form" or "adding contact form." The first line is under 72 characters; add detail on subsequent lines if needed.
4
Push and open a pull request
Upload your branch and create a PR for review:
git push origin feat/add-contact-form
Then open the PR on your hosting platform. Write a description: what changed, why, and how to test it. Attach screenshots for visual changes.
5
Address feedback and merge
Reviewers may request changes. Make the fixes, commit them to the same branch, and push. The PR updates automatically. Once approved and tests pass, merge the PR and delete the branch.
git checkout main
git pull origin main
git branch -d feat/add-contact-form
Commit often, push regularly. Small commits with focused messages are easier to review and revert than one massive commit at the end of a day.
Branching Strategies
How your team creates, names, and merges branches defines your workflow. Choose based on team size and release frequency.
Strategy
How it works
Best for
Trade-offs
GitHub Flow
Feature branches merge into main; releases are tagged from main.
Continuous deployment, small teams, rapid iteration.
Simple, but no staging environment between branch and production.
GitFlow
main for releases, develop for integration, feature/release/hotfix branches.
Versioned software with scheduled releases.
More branches and merges to manage; complexity grows with team size.
Trunk-Based Development
Everyone merges to main frequently (daily). Short-lived feature branches or feature flags.
Large engineering teams with strong CI/CD.
Requires automated tests and deployment gates; steep learning curve.
Forking Workflow
Each contributor forks the repo, works on their fork, and submits PRs to the original.
Open source projects with external contributors.
Syncing forks requires discipline; not ideal for internal teams.
Choosing your strategy
Start with GitHub Flow. It is the simplest and works for most teams.
Add a develop branch only when you need a staging environment separate from production.
Adopt trunk-based development only when your CI/CD pipeline can catch regressions before they reach users.
Document your chosen strategy so new contributors know the rules.
Forks: Working with Copies You Don't Own
A fork is a server-side copy of a repository under your own account. It lets you experiment freely or contribute to a project where you do not have write access to the original.
When to fork
Situation
Fork or branch?
You have write access to the repo and are on the team
Use a branch. No fork needed.
You want to contribute to an open-source project
Fork the repo, work on your fork, and submit a pull request.
You want to experiment without affecting the original
Fork if you may want to share results later; a branch is fine for private experiments.
You are building on top of someone else's project as a starting point
Fork it. You get full history and can diverge freely.
The fork workflow
1
Fork the repository
On your hosting platform (GitHub, GitLab, Gitea), click the "Fork" button. This creates a copy under your account, for example your-username/project-name.
2
Clone your fork locally
git clone git@github.com:your-username/project-name.git
cd project-name
Your local clone has origin pointing to your fork, not the original.
3
Add the upstream remote
Connect your local clone to the original repository so you can pull in changes:
On your hosting platform, open a PR from your fork's branch to the original repository's main branch. The platform handles cross-repository PRs automatically.
Keep your fork synced. A stale fork leads to merge conflicts. Sync with upstream before every new feature branch, not just when you start contributing.
Mirroring Repositories
A mirror is an exact copy of a repository, including all refs (branches, tags) and the full history. Unlike a regular clone, a mirror is a bare repository designed to be pushed to another location.
When to mirror
Backups
Keep an identical copy on a different hosting provider or server. If your primary host goes down, the mirror has everything.
Migration
Moving a project from one platform to another (for example, GitHub to Gitea)? Mirror-push preserves all history, branches, and tags.
Offline availability
A mirror on a local server gives your team fast access to the full repo without depending on an external connection.
Read-only distribution
Publish a public mirror of an internal repo so external users can clone and follow along without write access.
This creates a bare repository (no working directory) that contains every ref. The --mirror flag configures the remote to fetch all refs.
2
Push the mirror to the destination
cd project-name.git
git push --mirror git@gitea.example.com:your-account/project-name.git
The --mirror flag on push ensures all refs, including deleted ones, are replicated. Warning: this overwrites the destination. Use it only on empty or intended-to-be-replaced targets.
3
Keep the mirror in sync
Run this periodically (manually or via a cron job):
The -p flag prunes refs that no longer exist on the source.
Mirror push is destructive.git push --mirror deletes any refs on the destination that do not exist on the source. Double-check the destination URL before running it.
Mirror vs. fork
Aspect
Fork
Mirror
Purpose
Contribute to or diverge from a project
Exact copy for backup, migration, or distribution
Working directory
Yes, a normal clone
No, a bare repository
Independent history
Yes, your fork can diverge
No, mirrors should stay identical
Pull requests
You can open PRs back to the original
No, mirrors are read-only copies
Contributing to Existing Projects
Contributing to someone else's project follows a predictable pattern. Understanding it removes the anxiety of making your first contribution.
The contribution workflow
1
Read the contribution guidelines
Look for CONTRIBUTING.md, CONTRIBUTING.rst, or a "Contributing" section in the README.md. These guidelines tell you:
What kinds of contributions are welcome (bug fixes, features, docs, translations)
How to set up the development environment
Coding style and conventions
How to structure your commits and PRs
Whether you need to open an issue before a PR
If there are no guidelines, look at recent PRs to understand the project's conventions.
2
Find or open an issue
Check the issue tracker for something you want to work on. If you have a new idea, open an issue first to discuss it with maintainers before writing code. This avoids wasted effort on changes the project may not want.
3
Fork and clone
git clone git@github.com:your-username/project-name.git
cd project-name
git remote add upstream git@github.com:original-owner/project-name.git
4
Set up the development environment
Follow the project's setup instructions. Install dependencies, configure linters, and make sure the test suite passes on the unmodified codebase before you start.
5
Create a focused branch
git checkout -b fix/issue-42-null-pointer
One branch per issue or feature. Keep the scope narrow. A PR that fixes one bug is easier to review than a PR that fixes five.
6
Make changes, test, and commit
Write the code, add or update tests, and run the full test suite. Commit with a message that references the issue:
git commit -m "Fix null pointer when user profile is empty
Closes #42"
Many platforms (GitHub, GitLab, Gitea) auto-close issues when a PR with this text merges.
7
Push and open a pull request
git push origin fix/issue-42-null-pointer
Open the PR from your fork to the original repo. In the description, explain what changed, why, and how to test it. Reference the issue number.
8
Respond to review feedback
Maintainers will review your PR. They may request changes, ask questions, or suggest alternatives. Respond promptly, make the requested changes, and push updates to the same branch. The PR updates automatically.
Etiquette for contributors
Be respectful
Maintainers are often volunteers. Accept feedback gracefully, even when it is critical. Disagree with evidence, not emotion.
Keep PRs small
A PR under 200 lines of changes is far more likely to be reviewed quickly. Split large changes into multiple PRs when possible.
Follow the style
Match the project's existing conventions: indentation, naming, file structure, and commit message format. Consistency matters more than your personal preference.
Do not drive-by refactor
Do not reformat code or rename variables in a PR that is supposed to fix a bug. Scope creep frustrates reviewers and delays merges.
First contributions are welcome everywhere. Many projects label issues as good first issue or beginner friendly. These are designed to be approachable entry points. Your first PR does not need to be impressive; it needs to be correct and well-described.
Collaboration: Pull Requests and Code Reviews
A pull request is more than a merge button. It is the primary communication channel between authors, reviewers, and the team.
Writing a good PR description
Include: what changed in user-facing terms, why the change was made, how to test it, and any screenshots for visual changes. Link related issues. A reviewer should understand the change without reading every line.
Requesting the right reviewers
Ask someone who knows the affected code area. For cross-cutting changes, add a second reviewer. Do not request yourself. Many platforms support auto-assign based on file ownership.
Leaving useful review comments
Comment on behavior, clarity, and risk—not personal style preferences. Suggest a fix when you can. Distinguish "must fix" from "nit" (minor suggestion). Approve when the change is safe and correct; request changes when it is not.
Handling conflicts
When two branches edit the same lines, Git marks the conflict. Update your branch with git merge main, resolve markers in the editor, stage, and commit. Test the merged result before pushing.
Code review is not code policing. The goal is to catch bugs, share knowledge, and maintain quality—not to enforce personal preferences or slow down the ship.
Setting Up Your Organization
As you move from a personal account to a team, you need structure. An organization (GitHub), group (GitLab), or organization (Gitea) gives you teams, shared ownership, and centralized access controls.
Steps to set up your organization
1
Create the organization
On your hosting provider, create an organization with a clear name that reflects your team or company. Invite founding members as owners so they can manage settings and billing. Keep the number of owners small (2-3) for security.
2
Define teams
Create teams that match how your group works: frontend, backend, devops, design, etc. Add members to the appropriate teams. Teams inherit repository access, so you manage permissions once instead of per-person per-repo.
3
Set default repository settings
Configure organization-level defaults so every new repository starts secure:
Default branch: Set to main with protection rules.
Require PR reviews: At least one approval before merging.
Require status checks: CI must pass before merging.
Restrict force pushes: Disable on protected branches.
Require signed commits: Enable for high-security repos.
4
Create a template repository
Build a repo-template with your standard README.md, .gitignore, CONTRIBUTING.md, license file, and CI configuration. Enable it as a template so new projects start with consistent structure and tooling.
5
Document your conventions
Store team conventions in an ORG-CONVENTIONS.md or wiki: branch naming, commit message format, PR template, code style, release process, and on-call rotation. Link it from the organization profile so new members find it immediately.
Start simple, add complexity only when needed. A two-person team does not need five teams and a deployment board. Add structure as the team grows and the pain of managing access increases.
Access Permissions: Bots, Developers, and Autonomous Agents
Not every actor that touches your repositories is a human developer. Bots, CI systems, and autonomous AI agents each need carefully scoped permissions. The principle of least privilege applies to all of them.
Permission levels
Role
Read
Write branches
Create PRs
Merge PRs
Admin
Viewer
Yes
No
No
No
No
Developer
Yes
Yes
Yes
No
No
Maintainer
Yes
Yes
Yes
Yes
No
Owner / Admin
Yes
Yes
Yes
Yes
Yes
Bot / CI Token
Yes
Limited
Yes
No
No
AI Agent Token
Yes
Feature branches only
Draft PRs only
No
No
Configuring access for each actor type
Human developers
Individual accounts with two-factor authentication (2FA) required. Add to teams based on their role. Developers can push to feature branches, open PRs, and review. Only maintainers merge to main. Rotate team membership quarterly to remove stale access.
CI / CD bots
Use a dedicated bot account with a fine-grained personal access token. Scope the token to specific repositories. The bot can push to CI status branches, update PR checks, and deploy from protected branches. Never give a CI bot admin access or the ability to change branch protection rules. Rotate tokens every 90 days.
Autonomous AI agents
Create a dedicated bot account for each agent or use a shared agent service account. Grant the minimum permissions: read all repos, push to agent-created branches, and create draft PRs. Agents cannot merge, delete repos, change settings, or modify branch protection. Use branch naming rules like agent/ to identify agent work. Review all agent PRs before merging.
External contributors
Use the fork-and-PR model. External contributors never have direct write access. They fork the repo, make changes, and submit PRs. Enable CODEOWNERS to require review from specific teams for sensitive files. Use a CONTRIBUTING.md to set expectations.
Token management best practices
Use fine-grained tokens scoped to specific repositories and actions.
Set expiration dates on all tokens. No token should be permanent.
Audit token usage monthly. Revoke unused or overly permissive tokens.
Never embed tokens in code. Use environment variables or secret managers.
Enable token usage alerts so you know when a token is used unexpectedly.
An AI agent token with admin access is a critical risk. If compromised, an agent could modify branch protection, add new owners, or exfiltrate code. Always use the minimum permissions needed for the agent's task.
Migrating Codebases to a Git Provider
Whether you are moving from a local drive, another version control system, or a legacy server, migrating codebases requires care to preserve history, maintain security, and avoid data loss.
Before you migrate
1
Audit what you are moving
List all projects, estimate sizes, identify sensitive files (credentials, API keys, personal data), and note which projects have existing Git history versus flat file dumps. Check for large binary files that should go to a blob store instead of Git.
2
Clean the source
Remove credentials, secrets, and personal data before migration. Check for accidentally committed secrets using tools like git-secrets or trufflehog. If secrets are already in Git history, use git filter-repo to remove them before pushing to the new provider.
3
Set up the destination
Create the organization, teams, and repositories on the new provider before migrating. Configure branch protection, default permissions, and webhooks. Having the structure ready prevents ad-hoc access grants during the migration.
Verify the clone: Check file counts, commit history, and branch list on the new provider.
Test a checkout: Clone the new repo to a clean machine and verify it builds or serves correctly.
Update all remotes: Have every developer update their local origin to the new URL.
Decommission the old source: After a grace period (2-4 weeks), remove write access from the old location. Leave it read-only for recovery, then archive it.
Rotate any exposed secrets: If old credentials were in the source, rotate all affected API keys and passwords immediately.
Never skip the pre-migration secret scan. Migrating a repo with embedded credentials to a cloud provider makes those credentials accessible to everyone with read access. Scan first, clean history, then push.
Securing Your Repositories
Security is not a one-time setup. It is a series of controls that work together to prevent unauthorized access, detect breaches early, and limit damage when something goes wrong.
Essential security controls
1
Branch protection
Enable on main and any release branches. Require at least one PR review, require status checks to pass, restrict who can push, and disable force pushes. This is your first line of defense against accidental or malicious changes.
2
Two-factor authentication (2FA)
Require 2FA for all organization members. Most providers let you enforce this at the organization level. Without 2FA, a compromised password gives full access to your code.
3
Secret scanning and push protection
Enable built-in secret scanning (GitHub, GitLab, and Gitea all offer this). It detects accidentally committed API keys, tokens, and passwords. Push protection blocks the commit before it reaches the repo. Review alerts weekly and rotate any exposed secrets immediately.
4
Access reviews
Run quarterly access reviews. Remove users who have left, downgrade permissions that are no longer needed, and revoke unused tokens. Most providers show a list of collaborators and their last activity—use it.
5
Audit logs
Enable and monitor audit logs. They record every login, permission change, branch protection modification, and repository deletion. Set up alerts for high-risk actions: new owners added, branch protection disabled, or repositories transferred. Review logs monthly for anomalies.
Advanced protections
CODEOWNERS
Define file and directory ownership so changes to critical paths require review from designated people or teams. Place a CODEOWNERS file in .github/, .gitlab/, or the repo root. Example: /src/auth/ @security-team.
Required CI checks
Require automated checks to pass before merging: linting, type checking, unit tests, and security scans. A PR cannot merge until the green checks appear. This catches regressions before they reach main.
Signed commits
Require GPG or SSH-signed commits for high-security repositories. Signed commits prove the change came from the claimed author. Enable commit signature verification in branch protection.
Repository backups
Even with a cloud provider, maintain independent backups. Use git clone --mirror to create a bare backup on a separate system or cloud storage. Automate weekly backups and test restoration quarterly.
Incident response for compromised repos
When a breach is detected
Revoke the compromised token or account immediately.
Rotate all secrets that may have been exposed: API keys, database passwords, deployment tokens.
Review the audit log to understand what the attacker accessed and changed.
Check all PRs and branches created by the compromised account for backdoors.
Rebuild from a known-good commit if code was modified maliciousally.
Enable additional monitoring (enhanced audit logging, IP restrictions) for 30 days.
Document the incident and update your security checklist to prevent recurrence.
Security is a process, not a product. No single tool makes your repo secure. Combine branch protection, secret scanning, access reviews, audit logs, and team training. Review your security posture quarterly.
Working with AI Coding Agents
AI coding agents can read repositories, propose changes, run tests, and open pull requests. Version control is the boundary that keeps agent work safe and reviewable.
How AI agents use Git
Agent action
What happens
What you control
Read and understand
The agent explores the repository, reads files, and searches for patterns.
Read-only access; no files are changed.
Propose changes
The agent edits files on a new branch, keeping the main branch untouched.
You review the diff before any change reaches the main line.
Run validation
The agent runs linters, type checkers, or tests to verify correctness.
You see test results and can run additional checks.
Open a draft PR
The agent pushes the branch and opens a draft pull request for your review.
You approve, request changes, or close the PR.
Address feedback
You leave review comments; the agent implements fixes and pushes updates.
You control when the PR is ready and when it merges.
Safety principles for AI agent workflows
Branch isolation: Agents always work on their own branch. The main branch is never modified directly by an agent.
Draft PRs first: Agent-submitted PRs start as drafts. You mark them ready for review when you are satisfied.
No direct merges: Agents do not merge their own PRs. A human approves the merge.
Least-privilege access: Agent tokens can push to branches and create PRs but cannot delete repositories, change branch protection rules, or add new users.
Branch naming rules: Use agent/ prefix so agent work is identifiable in branch lists and audit logs.
Token expiration: Agent tokens expire on a schedule. Expired tokens prompt a review of whether the agent still needs access.
Reviewing Code: A Practical Checklist
Whether reviewing human or AI-submitted changes, use this checklist to focus your attention on what matters.
1
Does it do what the PR says?
Read the description, then skim the diff. Does the change match the stated intent? Is the scope reasonable, or has it crept beyond the original goal?
2
Is it correct?
Check for logic errors, null handling, error paths, and edge cases. Does the code handle failure gracefully, or does it crash silently?
3
Is it secure?
Look for unvalidated input, hardcoded secrets, excessive permissions, SQL injection, XSS, and data exposure. A change that introduces a vulnerability is not acceptable even if the feature works.
4
Is it testable?
Are there tests for the new behavior? Do existing tests still pass? If the change is untestable, flag it—untested code is untrusted code.
5
Is it maintainable?
Is the code readable and consistent with the project's style? Are complex functions broken into smaller pieces? Will the next person understand this in six months?
Review the behavior, not the author. Comment on the code's effect: "This will fail when the API returns an empty array" instead of "You forgot to handle empty arrays."
Hands-On Practice
30-minute Git exercise
Create a new repository on your hosting provider called git-practice.
Clone it to your computer and create a file called README.md with a project description.
Commit and push to main.
Create a branch called feat/add-features and add a features.md file listing three features you want to build.
Commit, push the branch, and open a pull request with a description.
Ask an AI coding agent to add a fourth feature to the list. Review its changes in the PR diff.
Approve and merge the PR if the change is correct, or request changes if it needs improvement.
Delete the merged branch and pull the latest main.
After this exercise, you will have experienced the full cycle: create, branch, commit, push, PR, review, merge, and cleanup.
45-minute org and security exercise
Create an organization on your hosting provider and invite a teammate as a member.
Create a developers team and add your teammate. Set the team's default access to Developer.
Create a repository under the organization and enable branch protection on main with required PR reviews.
Generate a fine-grained personal access token scoped to that repository with read and write access. Test it by cloning with the token.
Enable secret scanning on the repository. Commit a fake API key (e.g., FAKE_KEY_12345 in a .env.example file) and verify the scanner detects it.
Review the audit log to see your actions recorded. Note the login, repo creation, and branch protection changes.
Revoke the test token and confirm it no longer works.
This exercise gives you hands-on experience with organization structure, team permissions, branch protection, token management, secret scanning, and audit logging.