TK
All writing
Engineering

The Complete Git Guide for Developers & DevOps Engineers

Everything you need to master Git — from your first commit to production-grade workflows, GitOps, CI/CD, security, internals and recovery. A beginner-to-advanced reference for developers, DevOps, platform and SRE engineers.

Tanveer Khan42 min read

Git is one of the most important tools in modern software engineering. Whether you're a frontend developer, backend engineer, DevOps engineer, platform engineer or SRE, understanding Git beyond basic add, commit and push is essential.

Git is not just a version control system. It is the foundation of modern software collaboration, code review, release management, deployment automation and infrastructure management. This guide covers everything you need to use Git confidently in real-world engineering environments.

1. Introduction to Git

1.1 What is Git?

Git is a distributed version control system (DVCS) that tracks changes in source code and lets multiple developers collaborate on the same project.

  • Track changes in files and maintain full project history.
  • Collaborate with multiple developers and create independent branches.
  • Revert unwanted changes and resolve code conflicts.
  • Manage releases and versions.
  • Integrate with CI/CD pipelines and automate development workflows.

1.2 What is version control?

Version control records changes to files over time. Without it, developers end up with project-final, project-final-v2, project-final-latest, project-final-latest-fixed. With Git, all those changes are tracked systematically.

1.3 Git vs GitHub vs GitLab vs Bitbucket

ToolPurpose
GitDistributed version control system
GitHubGit hosting and collaboration platform
GitLabGit hosting, CI/CD, DevSecOps platform
BitbucketGit hosting and team collaboration
Azure ReposGit repository hosting within Azure DevOps
Gitea / ForgejoSelf-hosted Git services

Git is the underlying version-control technology. GitHub, GitLab and Bitbucket are platforms for hosting and collaborating on Git repositories.

1.4 Distributed vs centralized version control

In a centralized system (e.g. SVN) a central server holds the repository and developers depend on it. In a distributed system every developer has the complete history locally, most operations work offline, and synchronization happens through remotes. Git is distributed.

2. Installing and Configuring Git

2.1 Install Git

terminal
bash
# macOS
brew install git

# Ubuntu / Debian
sudo apt update
sudo apt install git

On Windows, download from git-scm.com/downloads. Verify the install:

terminal
bash
git --version

2.2 Configure your identity

terminal
bash
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

git config --list          # view all config
git config user.name       # view one setting
git config --global --edit # edit global config

2.3 Configuration levels

LevelScope
SystemAll users on the machine
GlobalThe current OS user
LocalThe current repository
terminal
bash
git config --system core.editor vim
git config --global init.defaultBranch main
git config --local user.name "Project Developer"

Local overrides global, which overrides system. Set per-repo identity with --local when you contribute under different names.

2.4 Useful defaults

terminal
bash
git config --global init.defaultBranch main
git config --global core.editor "code --wait"
git config --global color.ui auto
git config --global fetch.prune true
git config --global core.autocrlf input

3. Understanding Git Architecture

3.1 The four areas

  1. 1Working Directory — where you create, edit and delete files.
  2. 2Staging Area (Index) — where you prepare changes before committing.
  3. 3Local Repository — where Git stores committed history.
  4. 4Remote Repository — a repo hosted on GitHub, GitLab, Bitbucket, etc.
git-workflow
text
Working Directory
       |
       | git add
       v
  Staging Area
       |
       | git commit
       v
 Local Repository
       |
       | git push
       v
 Remote Repository

3.2 The object model

ObjectDescription
BlobStores file contents
TreeStores directory structure and file references
CommitStores a snapshot reference and commit metadata
TagA named reference to a specific object, usually a commit

Git uses content-addressed storage: object IDs are cryptographic hashes of their content. Repositories use SHA-1 by default in many environments, with SHA-256 support also available.

3.3 What is HEAD?

HEAD references the current checkout position, normally the tip of the current branch.

terminal
bash
git rev-parse HEAD
cat .git/HEAD

3.4 What is the index?

The index is the staging area — it lets you choose exactly which changes become the next commit.

terminal
bash
git ls-files --stage

4. Creating and Managing Repositories

4.1 Initialize

terminal
bash
git init
git init my-project

4.2 Clone

terminal
bash
git clone https://github.com/user/project.git        # HTTPS
git clone git@github.com:user/project.git            # SSH
git clone https://github.com/user/project.git mydir  # custom dir
git clone -b develop https://github.com/user/project.git  # a branch

4.3 Shallow clone

terminal
bash
git clone --depth 1 https://github.com/user/project.git

A shallow clone skips history — useful in CI/CD where full history is unnecessary.

4.4 Status, add, commit

terminal
bash
git status
git status --short

git add index.js            # one file
git add .                   # everything
git add -u                  # tracked modifications & deletions
git add -A                  # all changes incl. untracked

git commit -m "feat: add authentication"
git commit                  # open editor for a detailed message
git commit -am "fix: resolve login issue"  # stage+commit tracked files

git commit -am does NOT include new untracked files — only already-tracked ones. Run git status before committing to be sure.

4.5 View history

terminal
bash
git log
git log --oneline
git log --oneline --graph --all --decorate
git log -5
git log --author="Tanveer"

5. Understanding git diff

terminal
bash
git diff                       # unstaged changes
git diff --staged              # staged changes
git diff main develop          # between branches
git diff commit1 commit2       # between commits
git diff main develop -- src/app.js
git diff --stat                # statistics
git diff --name-only
git diff -w                    # ignore whitespace

Always inspect your changes before committing or opening a PR. Diffs catch accidental edits, debugging statements, stray files, hardcoded credentials and unintended deletions.

6. Git Branching

A branch lets you work on features, fixes or experiments without touching the main development line.

terminal
bash
git branch                    # list local
git branch -r                 # list remote
git branch -a                 # list all

git branch feature/auth       # create
git switch feature/auth       # switch (modern)
git checkout feature/auth     # switch (legacy)
git switch -c feature/profile # create + switch

git branch -m new-name        # rename current
git branch -d feature/auth    # delete merged
git branch -D feature/auth    # force delete
git push origin --delete feature/auth   # delete remote
terminal
bash
git switch --track origin/develop
git branch --set-upstream-to=origin/develop develop

7. Git Branching Strategies

7.1 Git Flow

Structured strategy with long-lived main and develop, plus feature/*, release/* and hotfix/* branches. Best for scheduled releases and multiple maintained versions.

7.2 GitHub Flow

  1. 1Create a branch from main.
  2. 2Make changes and push the branch.
  3. 3Open a pull request.
  4. 4Review and test.
  5. 5Merge into main and deploy.

7.3 GitLab Flow

Combines feature development with environment or release-oriented branches and merge requests, depending on deployment needs.

7.4 Trunk-Based Development

  • Short-lived branches and small pull requests.
  • Frequent integration into a shared main branch.
  • Feature flags for incomplete features.
  • Heavy reliance on automated testing and CI.

7.5 Which to choose?

StrategyBest for
Git FlowScheduled releases
GitHub FlowContinuous deployment
GitLab FlowEnvironment-oriented delivery
Trunk-BasedFast-moving engineering teams

8. Working with Remote Repositories

terminal
bash
git remote -v                              # list
git remote add origin <url>                # add
git remote rename origin upstream          # rename
git remote remove origin                   # remove

git fetch                                  # fetch
git fetch --all --prune                    # all remotes, drop stale refs

git pull                                   # fetch + merge
git pull origin develop
git pull --rebase                          # keep history linear

git push
git push origin feature/login
git push -u origin feature/login           # set upstream
git push --tags

9. Git Merge

terminal
bash
git switch develop
git merge feature/login          # basic merge
git merge --ff-only feature/login  # fast-forward only
git merge --no-ff feature/login    # always create a merge commit
git merge --abort                  # bail out

A fast-forward merge just advances the branch pointer when there's no divergence. A three-way merge combines the common ancestor with both branch tips and may create a merge commit.

10. Git Rebase

terminal
bash
git switch feature/login
git rebase develop
MergeRebase
Preserves branch historyReplays commits onto a new base
May create merge commitsCan produce linear history
Good for integration historyGood for cleaning local history
Keeps existing commit IDsCreates new commit IDs

THE GOLDEN RULE: never rebase commits others already depend on, unless the team explicitly coordinates the history rewrite. Rebasing changes commit hashes.

Interactive rebase

terminal
bash
git rebase -i HEAD~5
  • pick — keep a commit.
  • reword — change its message.
  • edit — stop to amend it.
  • squash — combine, keeping a merged message.
  • fixup — combine, discarding the message.
  • drop — remove it.
terminal
bash
git rebase --abort      # cancel
git rebase --continue   # after resolving
git rebase --skip       # skip a commit

11. Git Cherry-Pick

terminal
bash
git log --oneline
git cherry-pick abc1234            # one commit
git cherry-pick abc1234 def5678    # multiple
git cherry-pick A..B               # a range (excludes A, includes B)
git cherry-pick --abort
git cherry-pick --continue
  • Move a production hotfix into develop.
  • Apply a specific fix to a release branch (backporting).
  • Pick individual changes without merging a whole branch.

12. Resolving Merge Conflicts

Conflicts happen when Git can't automatically combine changes — the same lines changed, or a file deleted on one side and modified on the other.

conflict
text
<<<<<<< HEAD
const message = "Hello Developer";
=======
const message = "Hello DevOps";
>>>>>>> feature/update-message
  • HEAD section — your current branch.
  • Incoming section — the other branch's changes.
  • Edit to the final result, delete all three marker lines, then stage.
terminal
bash
git add src/app.js        # mark resolved
git commit                # finalize a merge
# or, during a rebase:
git rebase --continue
terminal
bash
git checkout --ours src/app.js     # keep YOUR version
git checkout --theirs src/app.js   # take theirs
git add src/app.js

During a rebase the meanings of --ours and --theirs can feel reversed. Inspect the actual file before choosing a side.

13. Undoing Changes

terminal
bash
git restore src/app.js             # discard unstaged changes
git restore --staged src/app.js    # unstage (keep changes)
git restore --source=HEAD~1 -- src/app.js  # reset a file to a commit

Resetting commits

terminal
bash
git reset --soft HEAD~1    # undo commit, keep changes STAGED
git reset --mixed HEAD~1   # undo commit, keep changes UNSTAGED
git reset --hard HEAD~1    # undo commit, DISCARD changes

git reset --hard is destructive — it discards tracked working-tree and index changes. Check your work first.

Revert and amend

terminal
bash
git revert abc1234              # new commit that reverses abc1234 (safe on shared branches)
git commit --amend              # edit the last commit
git commit --amend -m "feat: improve authentication"
git commit --amend --no-edit    # fold staged changes in, keep message

On shared/production history, prefer git revert over rewriting published history with reset/amend.

14. Git Stash

terminal
bash
git stash                        # save uncommitted changes
git stash push -m "WIP: payment"  # with a message
git stash push -u                 # include untracked
git stash push -a                 # include ignored (use with care)

git stash list
git stash apply                   # re-apply, keep stash
git stash apply stash@{0}
git stash pop                     # re-apply and drop
git stash drop stash@{0}
git stash clear
git stash branch feature/new stash@{0}

15. Tags and Release Management

terminal
bash
git tag v1.0.0                       # lightweight
git tag -a v1.0.0 -m "Release 1.0.0" # annotated (preferred for releases)
git tag                              # list
git push origin v1.0.0
git push origin --tags
git tag -d v1.0.0                    # delete local
git push origin --delete v1.0.0     # delete remote

Semantic versioning uses MAJOR.MINOR.PATCH (e.g. 2.4.1): MAJOR for breaking changes, MINOR for backward-compatible features, PATCH for backward-compatible fixes.

16. .gitignore and Repository Hygiene

.gitignore
bash
node_modules/
.env
.env.local
dist/
build/
coverage/
.next/
.DS_Store
*.log
terminal
bash
# global ignore for personal cruft
touch ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global

Adding a file to .gitignore does NOT untrack a file Git already tracks. Remove it from the index: git rm --cached .env (then commit).

terminal
bash
git status --ignored
git check-ignore -v node_modules/   # which rule matches

17. Git Hooks and Automation

HookPurpose
pre-commitRuns before creating a commit
prepare-commit-msgPrepares the commit message
commit-msgValidates commit messages
post-commitRuns after a commit
pre-pushRuns before pushing
post-merge / post-checkoutRuns after merge / branch switch
.git/hooks/pre-commit
bash
#!/bin/sh
npm run lint
terminal
bash
chmod +x .git/hooks/pre-commit

Popular tooling: Husky, lint-staged, pre-commit, Lefthook — for linting, formatting, tests and commit-message validation.

Client-side hooks are not a security boundary. Enforce critical policies on the server or in CI/CD as well.

18. Commit Message Conventions

conventional-commits
text
feat(auth): implement JWT authentication
fix(booking): resolve incorrect pricing calculation
docs(readme): update installation instructions
refactor(api): simplify reservation service
chore(deps): update dependencies
ci(github): add deployment workflow
perf(database): optimize reservation query
TypeMeaning
featNew feature
fixBug fix
docsDocumentation
refactorCode restructuring
testTests
choreMaintenance
perfPerformance improvement
ci / buildPipeline / build-system changes

Conventional commits make history readable and power automated changelogs and semantic-version releases.

19. Git Security Best Practices

19.1 Never commit secrets

  • API keys, database passwords, cloud credentials, private SSH keys.
  • Access tokens, production env files, signing keys.
  • Use environment variables and secret managers instead.

19.2 Use SSH authentication

terminal
bash
ssh-keygen -t ed25519 -C "you@example.com"
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh -T git@github.com

19.3 Secret scanning

terminal
bash
gitleaks detect --source .

Tools: Gitleaks, TruffleHog, GitHub Secret Scanning, GitLab Secret Detection.

19.4 Signed commits

terminal
bash
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git commit -S -m "feat: add authentication"
git verify-commit HEAD

19.5 Protect important branches

  • Require pull-request reviews and successful CI checks.
  • Disallow force pushes and restrict direct pushes.
  • Require signed commits where appropriate.

Removing a secret from history does NOT make the exposed credential safe. Rotate it immediately, then rewrite history (e.g. git filter-repo) and review forks, caches and CI logs.

20. Advanced Git Commands

20.1 Reflog — your time machine

terminal
bash
git reflog
git reset --hard HEAD@{2}

Reflog records updates to HEAD and branches, so you can recover from accidental resets, rebases and deleted branches. Inspect carefully before any --hard reset.

20.2 Bisect — find the bad commit

terminal
bash
git bisect start
git bisect bad
git bisect good abc1234
# test each checkout, then mark good/bad...
git bisect run npm test   # or automate
git bisect reset

20.3 Blame, show, grep

terminal
bash
git blame src/app.js
git blame -L 10,30 src/app.js
git show abc1234
git show abc1234:src/app.js
git grep "TODO"
git grep "TODO" develop

20.4 Worktree

terminal
bash
git worktree add ../hotfix hotfix/payment
git worktree list
git worktree remove ../hotfix

Worktrees check out multiple branches into separate directories sharing one object database — ideal for a hotfix without disturbing your feature branch.

20.5 Submodules

terminal
bash
git submodule add https://github.com/user/shared.git libs/shared
git clone --recurse-submodules <url>
git submodule update --init --recursive
git submodule update --remote

20.6 Git LFS

terminal
bash
git lfs install
git lfs track "*.psd"
git lfs track "*.zip"
git lfs ls-files

21. Git Internals: How Git Actually Works

During git add

  1. 1Reads the file contents.
  2. 2Creates or reuses a blob object.
  3. 3Updates the index with the file's metadata and object ID.

During git commit

  1. 1Creates tree objects for the staged directory structure.
  2. 2Creates a commit object (parent, author, committer, timestamp, message).
  3. 3Updates the current branch reference.
terminal
bash
git show-ref
git cat-file -p HEAD      # pretty-print an object
git cat-file -t HEAD      # object type
git count-objects -v
git gc                    # garbage collect / optimize
git fsck                  # integrity check

Never manually delete files from .git/objects — let Git manage its object database.

22. Git for DevOps Engineers

Git underpins DevOps: it manages application code, Infrastructure as Code, Kubernetes manifests, Docker configs, CI/CD pipelines, environment configuration, deployment scripts, monitoring config and security policies.

22.1 GitOps

  1. 1Desired system state is declared in Git.
  2. 2Changes are made through version-controlled commits and pull requests.
  3. 3Automated controllers reconcile actual infrastructure with the declared state.
  4. 4Changes are auditable and traceable.

Popular GitOps controllers: Argo CD and Flux CD.

gitops-flow
text
Developer -> Git Repository -> Pull Request -> Review + Validation
          -> Merge -> GitOps Controller -> Kubernetes Cluster
          -> Actual State Reconciled

22.2 Infrastructure as Code

repo-layout
bash
infrastructure/
├── terraform/
├── ansible/
├── kubernetes/
├── helm/
└── scripts/

22.3 Git with Terraform

terminal
bash
terraform fmt -check
terraform init
terraform validate
terraform plan
terraform apply

Git manages the Terraform configuration history; Terraform manages infrastructure state. Never commit sensitive state files.

22.4 Git with Kubernetes

repo-layout
bash
k8s/
├── base/
│   ├── deployment.yaml
│   └── service.yaml
└── overlays/
    ├── development/
    ├── staging/
    └── production/

Never store plaintext production secrets in ordinary Git repositories.

23. Git in CI/CD Pipelines

A push or pull request can trigger dependency installs, linting, tests, security scans, Docker builds, artifact publishing and deployment.

.github/workflows/ci.yml
yaml
name: CI Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
      - name: Install
        run: npm ci
      - name: Test
        run: npm test
      - name: Build
        run: npm run build

In production, pin third-party actions to full commit SHAs, use least-privilege permissions, and scope secrets per environment.

.gitlab-ci.yml
yaml
stages: [install, test, build]

install:
  stage: install
  script: npm ci

test:
  stage: test
  script: npm test

build:
  stage: build
  script: npm run build

Jenkins can watch repositories, trigger on commits, run tests, build and push Docker images, and deploy — typically wired through a webhook.

24. Pull Requests and Code Reviews

  1. 1Create a feature branch and implement the change.
  2. 2Commit and push the branch.
  3. 3Open a PR; automated checks run.
  4. 4Request review and resolve comments.
  5. 5Merge, then delete the branch if appropriate.

A good PR has a clear title, the problem, the solution, screenshots for UI, testing details, a linked ticket and any breaking-change or deployment notes.

Review checklist

  • Correctness — requirements met, edge cases and error paths handled.
  • Security — no exposed secrets, input validated, permissions enforced.
  • Clarity — readable in six months; good naming and structure.
  • Tests — new behaviour covered; CI passes.
  • Not your personal style preferences — that's the linter's job.

25. Monorepos and Git

monorepo-layout
bash
company-platform/
├── apps/
│   ├── frontend/
│   ├── admin-dashboard/
│   └── backend/
├── packages/
│   ├── ui/
│   └── shared/
├── infrastructure/
└── .github/

Tools: Nx, Turborepo, pnpm Workspaces, Bazel. Find what changed relative to the common ancestor to decide what to test/deploy:

terminal
bash
git diff --name-only main...HEAD

Monorepo CI should account for shared-package dependencies, not just directly-modified folders.

26. Git Performance Optimization

terminal
bash
git clone --depth 1 <url>                 # shallow clone
git clone --filter=blob:none <url>        # partial clone
git sparse-checkout init --cone           # sparse checkout
git sparse-checkout set apps/frontend
git remote prune origin                   # prune stale branches
git count-objects -vH                     # repo size
git maintenance start                     # scheduled optimization

27. Common Git Problems and Solutions

ProblemSolution
Accidentally committed wrong filesgit reset --soft HEAD~1
Need to undo a public commitgit revert <hash>
Recover a lost commitgit reflog
Merge conflictResolve files, then continue the operation
Accidentally deleted a branchCheck git reflog
Wrong commit messagegit commit --amend
Need changes from another branchgit cherry-pick <hash>
Temporarily switch tasksgit stash
Local branch behind remotegit pull --rebase
Pushed sensitive dataRotate the secret immediately
Repository too largeGit LFS, history review, partial clone

28. Essential Commands Cheat Sheet

CommandPurpose
git init / cloneStart or copy a repository
git statusCheck working-tree status
git add . / commit -mStage and commit
git log --onelineView history
git switch -c <b>Create and switch branch
git merge / rebaseIntegrate branches
git cherry-pick <h>Apply a selected commit
git fetch / pull / pushSync with remotes
git stashTemporarily save changes
git restore / reset / revertUndo at various levels
git reflogRecover lost references
git bisectFind a bug-introducing commit
git worktreeMultiple working directories

29. Real-World Workflow for Developers

terminal
bash
# 1. update develop
git switch develop && git pull origin develop

# 2. feature branch
git switch -c feature/payment-integration

# 3. implement, then review
git status && git diff

# 4. stage, commit, push
git add .
git commit -m "feat(payment): integrate payment gateway"
git push -u origin feature/payment-integration

# 5. open a PR -> review -> merge, then clean up
git switch develop && git pull origin develop
git branch -d feature/payment-integration

30. Real-World Workflow for DevOps Engineers

terminal
bash
# 1. infra branch
git switch -c infra/update-api-resources

# 2. edit k8s/production/deployment.yaml, then validate
kubectl apply --dry-run=server -f k8s/production/

# 3. review, commit, push
git diff
git add k8s/
git commit -m "infra(k8s): update API resource limits"
git push -u origin infra/update-api-resources

# 4. PR -> CI validation -> merge -> GitOps reconcile
kubectl rollout status deployment/api
kubectl get pods

31. Best Practices for Professional Engineers

  • Pull/fetch the latest before starting new work; use meaningful branch names.
  • Keep commits small and focused; write descriptive messages.
  • Review git diff before committing; never commit secrets.
  • Prefer pull requests over direct pushes to protected branches.
  • Keep feature branches short-lived; avoid unnecessary force pushes.
  • Use git revert to undo shared commits; tag formal releases.
  • Maintain .gitignore; review dependency and lockfile changes.
  • Use signed commits when required; keep infrastructure version-controlled.
  • Understand a command before running destructive operations.

32. Learning Roadmap: Beginner to Advanced

Level 1 — Beginner

Install, configure, init, clone, status, add, commit, log, diff, push/pull. Goal: manage a basic repository independently.

Level 2 — Intermediate

Branching, merging, rebasing, remotes, conflicts, stash, reset, revert, tags, .gitignore. Goal: collaborate effectively on a team.

Level 3 — Advanced

Interactive rebase, cherry-pick, reflog, bisect, blame, worktrees, submodules, LFS, hooks, internals, optimization. Goal: diagnose complex repository problems.

Level 4 — Professional Developer

PR workflows, code review, Conventional Commits, release management, semantic versioning, branch protection, commit signing, monorepos. Goal: work in production engineering teams.

Level 5 — DevOps / Platform Engineer

GitOps, IaC, Terraform/Kubernetes with Git, GitHub Actions, GitLab CI/CD, Jenkins, secret scanning, supply-chain security, automated deployments, environment promotion, release automation. Goal: design and operate production-grade Git workflows.

33. Practical Projects to Master Git

  1. 1Collaborative workflow: feature branches, PRs, reviews, conflicts, rebase, release tags.
  2. 2Automated CI: a Node app with GitHub Actions — lint, test, build, PR checks.
  3. 3IaC repository: Terraform with formatting, validation, plan and PR approvals.
  4. 4GitOps Kubernetes deploy: manifests + Argo CD/Flux, reconciliation, verification.
  5. 5Release management: semantic versioning, Conventional Commits, changelogs, hotfix branches, rollback.

34. Official Learning Resources

  • Official Git documentation — git-scm.com/doc
  • Pro Git book (free) — git-scm.com/book/en/v2
  • GitHub Skills — skills.github.com
  • GitHub & GitLab docs — docs.github.com, docs.gitlab.com
  • Atlassian Git tutorials — atlassian.com/git/tutorials

Final Thoughts

Git mastery is not memorizing hundreds of commands. It's understanding how Git stores and tracks changes, how branches and commits work, how to collaborate without breaking others' work, how to recover from mistakes, and how Git fits into modern DevOps and GitOps.

If you want to become a strong software or DevOps engineer, don't just learn Git commands — learn how to use Git to manage real production engineering workflows.

Bookmark this guide and keep it open while you work on real projects.