The Tech Trends Software Open Source How to Use Git and GitHub in 10 Steps: A Tutorial for New Developers
Software Open Source

How to Use Git and GitHub in 10 Steps: A Tutorial for New Developers

How to Use Git and GitHub in 10 Steps: A Tutorial for New Developers

If you’re just getting started with version control, this guide shows you exactly how to use Git and GitHub in a practical, safe workflow. Git tracks changes on your machine; GitHub hosts repositories and enables collaboration with pull requests, reviews, and automations. In short: Git manages your history, and GitHub helps you collaborate around it.

Definition: Git is a distributed version control system that snapshots your files over time. GitHub is a web platform where those Git repositories live so teams can review, discuss, and merge changes.

The 10 steps at a glance

1) Install & configure Git; 2) Create or clone a repo; 3) Make, stage, and commit changes; 4) Branch with purpose; 5) Connect & sync with remotes; 6) Open a pull request; 7) Merge or rebase safely; 8) Recover from mistakes; 9) Tag and version releases; 10) Automate and scale.

    Follow these steps and you’ll gain repeatable habits that keep your code reviewable, reversible, and ready to ship.


    1. Install and Configure Git Correctly

    Start by installing Git and telling it who you are, then choose a secure way to authenticate with GitHub. Doing this once establishes clean metadata for every commit and prevents “mystery author” problems later. The essentials are your name, email, default branch name, preferred editor, and line-ending behavior. Decide whether you’ll push via HTTPS with a token or via SSH keys; SSH reduces repeated prompts, while HTTPS tokens are simple and fine for many teams. Finally, set a couple of quality-of-life defaults—like colored output and a concise log format—so everyday commands are easier to read. With this foundation in place, every later step (branching, PRs, merging) inherits consistent, traceable history.

    How to do it

    # Check version
    git --version
    
    # Identify yourself (appears in commit metadata)
    git config --global user.name "Your Name"
    git config --global user.email "you@example.com"
    
    # Prefer 'main' for the default branch name
    git config --global init.defaultBranch main
    
    # Pick your editor (examples)
    git config --global core.editor "code --wait"
    # or: git config --global core.editor "nano"
    
    # Line endings (Windows often wants true; macOS/Linux usually false)
    git config --global core.autocrlf true   # Windows
    # git config --global core.autocrlf input # macOS/Linux
    
    # Nice extras
    git config --global color.ui auto
    git config --global pull.rebase false  # start with merges; rebase comes later
    

    Mini-checklist

    • Identity set: git config –global user.name shows your name.
    • Default branch: git config –global init.defaultBranch is main.
    • Auth chosen: Personal access token (HTTPS) or SSH keys.
    • Editor & line endings: Confirmed per OS.

    Synthesis: A clean Git configuration saves hours of confusion and makes every commit trustworthy and attributable.


    2. Create or Clone Your First Repository

    You can either create a brand-new repository (git init) for a fresh project or clone an existing one (git clone) to contribute. A repository is just a folder with a hidden .git directory storing the history and metadata. When starting from scratch, initialize the repo, create a README.md so there’s something to commit, and add a .gitignore to exclude build artifacts or secrets. When cloning, Git automatically pulls down the full history and sets a default remote called origin pointing to GitHub.

    How to do it

    Option A: New project

    mkdir hello-git && cd hello-git
    git init
    echo "# Hello Git" > README.md
    echo "node_modules/" > .gitignore
    git add .
    git commit -m "feat: initial commit with README and basic .gitignore"
    

    Option B: Clone an existing project

    git clone https://github.com/your-org/your-repo.git
    # or with SSH after keys are set up:
    # git clone git@github.com:your-org/your-repo.git
    cd your-repo
    

    Why it matters

    • git init lets you version anything, even solo projects.
    • git clone brings history and remotes, enabling collaboration and pull requests from moment one.
    • .gitignore prevents noise (logs, caches, local configs) from polluting history.

    Mini case: sanity numbers & guardrails

    • Keep the first commit small (for example, ≤ 200 lines) so future diffs stay readable.
    • .gitignore should cover the top 5–10 noisy paths early (e.g., dist/, build/, node_modules/, .env templates rather than real secrets).
    • One repo per deployable artifact is common; monorepos work too—decide based on team size and tooling.

    Synthesis: Whether you start fresh or clone, lay down a minimal README and .gitignore so your history starts clean and purposeful.


    3. Make, Stage, and Commit Changes You Can Trust

    Git’s power comes from its three areas: working directory (your files), staging area (index), and repository (committed snapshots). You edit files, stage only what you intend to track, and commit with a message that explains why the change exists. Adopting a consistent message style (for example, Conventional Commits) ensures your history doubles as an index of features, fixes, and breaking changes. Use .gitignore to exclude generated files and secrets. Before committing, review exactly what will be recorded with git status and git diff –staged so you don’t accidentally commit temporary or experimental code.

    How to do it

    # See what changed
    git status
    git diff            # unstaged changes
    git add fileA.js    # stage specific file
    git add -p          # interactively stage hunks
    git diff --staged   # review what's about to commit
    
    # Commit with a meaningful message
    git commit -m "feat(api): add /health endpoint with JSON status"
    

    Numbers & guardrails

    • Commits per PR: Aim for 3–7 coherent commits; squash micro-commits that just fix typos.
    • Commit scope: Try to limit each commit to one intention (feature, fix, refactor).
    • Message length: Keep the subject line around 50–72 characters; wrap bodies to readable lines.

    Common mistakes

    • Committing secrets or large binaries—use .env.example and .gitignore wisely.
    • Staging too much—use git add -p to include only what you mean.
    • Vague messages—“update stuff” won’t help you during a rollback.

    Synthesis: Treat each commit like a mini change proposal: small, reviewable, and justified by a crisp message.


    4. Branch With Purpose (Feature, Fix, and Release Branches)

    Branches let you develop independently without touching main until the work is ready. Create a branch for each feature or fix, name it clearly, and keep it short-lived to minimize merge pain. Your team may prefer GitHub Flow (simple feature branches off main) or a more structured approach with release/hotfix branches. Either way, branching reduces risk: unfinished work won’t block production, and code reviews happen on an isolated line of history.

    How to do it

    # Create and switch to a new branch
    git switch -c feat/health-endpoint
    # Work, stage, commit...
    git commit -m "feat(api): add /health endpoint"
    # Switch back to main when needed
    git switch main
    

    Naming patterns

    • feat/* for new features, fix/* for bug fixes, chore/* for tooling.
    • Include an issue key if your tracker uses them: feat/123-add-health-endpoint.

    Numbers & guardrails

    • Lifetime: Keep branches under 1–2 weeks of active work; rebase or merge frequently to avoid drift.
    • Size: A branch PR diff of 100–400 lines is reviewable; split bigger work.
    • Parallelism: Limit yourself to 2–3 active branches to avoid context switching.

    Synthesis: Purposeful, short-lived branches make reviews faster, merges cleaner, and production safer.


    5. Connect and Sync With Remotes Confidently

    A remote is a named URL to a hosted repository (e.g., GitHub). origin is the default. You’ll fetch changes from teammates and push your own branches to back them up and open PRs. The usual pattern is to create a branch locally, set its upstream to a remote branch, and push regularly. If you’re forking, you may add two remotes: your fork and the upstream project. Authentication can be via HTTPS tokens or SSH keys; SSH avoids repeated prompts while tokens are straightforward in GUI clients and automation.

    How to do it

    # See remotes
    git remote -v
    
    # Add a remote (if you started with git init)
    git remote add origin git@github.com:your-org/hello-git.git
    
    # Push and set upstream in one go
    git push -u origin feat/health-endpoint
    
    # Fetch all remote branches and tags
    git fetch --all --tags
    
    # Pull updates (merge by default)
    git pull
    

    Mini case & guardrails

    • First push: Use git push -u so future git pull and git push know which branch to track.
    • Forking: Add upstream to the original repo, keep your fork synced with git fetch upstream && git merge upstream/main or git rebase upstream/main (see Step 7).
    • Conflicts: If pull reports conflicts, don’t panic—open your editor, resolve files, git add them, and git commit the merge.

    Synthesis: Clear remote setup plus regular fetch/push cycles keep your branches backed up, discoverable, and ready for pull requests.


    6. Open a Pull Request That’s Easy to Review

    A pull request (PR) is a proposal to merge your branch into another (usually main). A great PR tells the reviewer what changed and why, links to any issues, and scopes the diff to a reviewable size. Draft PRs are perfect when you want early feedback but aren’t ready to merge. Add screenshots for UI changes, include reproduction steps for bug fixes, and request reviewers who own the area (CODEOWNERS can automate that). Use status checks (tests, linters, security scans) so reviewers can focus on logic, not formatting.

    How to do it

    1. Push your branch to GitHub.
    2. Click Compare & pull request (or use your tool/CLI).
    3. Write a concise title and a clear description (what, why, how).
    4. Link issues: “Fixes #123”.
    5. Request reviewers; mark as Draft if still in progress.
    6. Respond to review comments; push follow-up commits as needed.

    Mini case & numbers

    • Title format: feat(api): add /health endpoint.
    • PR size: Target ≤ 400 lines changed; split if larger.
    • Turnaround: Batch small, focused updates; avoid “mega PRs” that stall for days.

    Checklist for a solid PR

    • Tests updated or added.
    • Docs or comments adjusted.
    • Self-reviewed with a final git diff read-through.
    • All checks green; no unresolved conversations.

    Synthesis: Treat PRs as a narrative: present the problem, the change, and the evidence it works—reviewers will thank you.


    7. Merge or Rebase Safely (and Know When to Use Each)

    To integrate your branch, you can merge or rebase. A merge creates a new commit that ties histories together—safe, preserves context. Rebase rewrites your branch as if it started from the latest main, giving a linear history; it’s clean but must be handled with care. The practical rule: don’t rebase public branches that others depend on. It’s common to rebase a private feature branch before opening a PR (or early in a PR) to get a tidy history, then merge it. Teams also use “squash-merge” to condense many commits into one for main.

    How to do it

    Update your feature with merge

    git switch feat/health-endpoint
    git fetch origin
    git merge origin/main
    

    Or update with rebase (private branches only)

    git switch feat/health-endpoint
    git fetch origin
    git rebase origin/main
    # If conflicts: resolve files, git add <file>, then:
    git rebase --continue
    

    Integrate to main (after approval)

    • Merge commit via PR (default in many repos).
    • Squash & merge to keep main tidy.
    • Rebase & merge in repos that enforce a linear history.

    Numbers & guardrails

    • Conflicts: If you hit more than 3–5 conflict files repeatedly, you’re drifting; sync with main more often or split the work.
    • Force-push: Only after rebasing private branches (git push –force-with-lease), never on main.
    • Linear history: If your repo requires it, prefer rebase & merge or squash.

    Synthesis: Choose merge for safety and context; use rebase to clean private history. The best teams are consistent about which they prefer in which scenarios.


    8. Recover From Mistakes: Reset, Revert, Restore, Stash, Reflog

    Everyone makes mistakes; Git gives you escape hatches. Use git restore to throw away local file changes, git reset to move branch pointers (careful—this rewrites history), and git revert to create a new commit that undoes a prior one (safe for public branches). git stash shelves work-in-progress without committing, handy when switching tasks. And git reflog is your time machine, recording where branch pointers have been so you can recover lost commits.

    How to do it

    # Discard local changes in a file
    git restore path/to/file
    
    # Unstage a file you added by mistake
    git restore --staged path/to/file
    
    # Revert a bad commit by hash (safe on public branches)
    git revert <commit-sha>
    
    # Move the current branch back (private branches only)
    git reset --hard HEAD~1    # drops the last commit
    
    # Stash and come back later
    git stash push -m "WIP: experiment"
    git stash list
    git stash pop
    
    # When you're really stuck: see prior branch positions
    git reflog
    

    Mini case with numbers

    • You merged a PR that introduced a bug. Grab the commit SHA from history and git revert <sha>. That adds 1 new commit that cleanly undoes the change without rewriting history.
    • You committed secrets locally. On your private branch, rotate the secret, then git reset –soft HEAD~1, remove the secret file, commit again. Force-push the private branch; never force-push main.

    Quick checklist

    • Public branch? Prefer git revert.
    • Private branch cleanup? git rebase -i or git reset are fine.
    • Work to shelf? git stash with a message.
    • Lost work? Check git reflog before panicking.

    Synthesis: Knowing the difference between revert, reset, and restore turns scary situations into routine maintenance.


    9. Tag Releases and Use Semantic Versioning

    Tags mark specific commits as important—usually releases. Lightweight tags are simple pointers; annotated tags include a message and metadata and are preferred for releases. Combine tags with Semantic Versioning (SemVer)MAJOR.MINOR.PATCH—to signal the impact of changes. A bump to 1.2.4 typically means a patch fix; 1.3.0 adds backward-compatible features; 2.0.0 breaks compatibility. Pushing tags lets CI/CD pipelines deploy specific versions and lets users pin dependencies.

    How to do it

    # Create an annotated tag for a release
    git tag -a v1.0.0 -m "Initial stable release"
    
    # Push a single tag or all tags
    git push origin v1.0.0
    # or:
    git push --tags
    
    # List tags & view a tagged release
    git tag --list
    git show v1.0.0
    

    Numbers & guardrails

    • Tag style: Prefix with v (e.g., v1.2.3) for clarity.
    • Pre-releases: Use identifiers like -alpha.1, -beta.2, -rc.1 to stage changes before general release.
    • Frequency: Tag every deployable milestone; avoid skipping tags—consistency helps consumers and tooling.

    Tools/Examples

    • Release notes can be generated from Conventional Commits and tags.
    • Package managers and deployment tools often resolve exact tags, which simplifies rollbacks.

    Synthesis: Tags plus SemVer make your history readable by both humans and tools; releases become traceable, repeatable events.


    10. Automate and Scale: Hooks, Checks, and Branch Protection

    As your repo grows, automation preserves quality without slowing you down. Git hooks run scripts on events like commits or merges to enforce style or run quick tests locally. On GitHub, branch protection rules require reviews and passing checks before merges. Continuous Integration (CI) runs tests on every PR, and you can add status checks for linting, security scans, and coverage thresholds. CODEOWNERS files auto-request the right reviewers, and templates standardize issue and PR descriptions. These guardrails ensure that even under pressure, changes remain safe and standards stay consistent.

    How to do it

    • Local hooks: Add scripts in .git/hooks/ (e.g., pre-commit) to run linters or type checks before committing.
    • Status checks: Configure CI to run on PRs; require checks to pass before merging.
    • Branch protection: Disallow direct pushes to main, require 1–2 approvals, and enforce up-to-date with main.
    • Templates & ownership: Use .github/pull_request_template.md, .github/ISSUE_TEMPLATE/, and CODEOWNERS.

    Numbers & guardrails

    • Checks: Keep the critical checks list short (e.g., 3–6 must-pass jobs) to avoid bottlenecks.
    • Reviewers: Require at least 1 approval for small repos, 2 for critical components.
    • Runtime: Aim for CI under 10 minutes to keep feedback loops fast.

    Mini checklist

    • Lint, test, and security checks in CI.
    • Branch protection enabled on main.
    • CODEOWNERS file points to domain experts.
    • Secret scanning enabled; no credentials in repo.

    Synthesis: Automations enforce the rules you’d want to follow anyway, turning best practices into defaults.


    Quick Reference Table: Everyday Git Commands

    TaskCommandNotes
    Initialize repogit initCreates .git directory; honors default branch setting
    Clone repogit clone <url>Copies history and sets origin
    Check statusgit statusShows staged/unstaged/ignored files
    Stage changesgit add -p / git add <path>Stage interactively or by path
    Commitgit commit -m “type(scope): message”Prefer Conventional Commits style
    Switch branchesgit switch <name> / git switch -c <name>Create with -c
    Mergegit merge <branch>Non-destructive integration
    Rebasegit rebase <branch>Clean linear history (private branches)
    Revertgit revert <sha>Safe undo on public branches
    Taggit tag -a vX.Y.Z -m “notes”Annotated tags for releases

    Conclusion

    You’ve just walked through how to use Git and GitHub in a way that scales from solo tinkering to professional teamwork. Start by setting up Git correctly so every commit is attributable and consistent. Create or clone repositories with an intentional .gitignore, then practice the core loop: edit, stage, review, commit. Keep work isolated on short-lived branches, push to a remote, and tell a clear story through your pull requests. Choose merge for safety, rebase for tidy private histories, and rely on revert for public fixes. When mistakes happen, reach for restore, reset, stash, and reflog. Tag releases with SemVer so humans and tools can reason about changes, and add automation to keep quality high without slowing you down. Now pick a small feature, create a branch, and open a PR—ship something today.

    CTA: Ready to practice? Create a new branch right now and make your first pull request on a small change—then iterate using these 10 steps.


    FAQs

    1) Is Git the same as GitHub?
    No. Git is a local version control tool that records snapshots of your files. GitHub hosts Git repositories online and adds collaboration features like pull requests, code review, issue tracking, and automated checks. You can use Git without GitHub, but pairing them unlocks team workflows.

    2) Should I use HTTPS or SSH for GitHub?
    Both are secure when configured properly. HTTPS uses a token and is straightforward in many tools. SSH uses a key pair you create once; it reduces repeated prompts and is convenient for frequent pushes. Pick one and set it up thoroughly; switching later is easy.

    3) When should I merge vs rebase?
    Merge is safest and preserves history; it’s ideal once a branch is public or shared. Rebase rewrites your branch to start from a newer base, producing a linear history—clean but risky on shared branches. Rebase private branches to tidy them, merge into main for integration.

    4) How big should my pull request be?
    Aim for focused changes under a few hundred lines. Smaller PRs get reviewed faster and with fewer defects. If a change grows large, split it into preparatory refactors, the core feature, and follow-ups, each with its own PR.

    5) What’s the difference between reset, revert, and restore?
    restore adjusts files in your working directory or index. reset moves the branch pointer (rewrites history) and is best for private cleanup. revert adds a new commit that undoes a past commit—perfect for public branches because it keeps history intact.

    6) How do I avoid committing secrets or junk files?
    Use .gitignore to exclude build output, caches, and local config. Store secrets outside the repo (environment variables, secret managers). If a secret slips in, rotate it immediately and rewrite private history or revert as appropriate.

    7) Do I need a branching strategy?
    Yes, at least a lightweight one. Use feature branches off main (GitHub Flow) for most work. Add release or hotfix branches only when your deployment process needs them. Keep branches short-lived to reduce conflicts.

    8) What is a good commit message?
    A short subject that states intent, optionally followed by a wrapped body explaining the “why.” Conventional Commits (e.g., feat(ui): add dark mode toggle) make history machine-readable and help automate changelogs and version bumps.

    9) How do I link issues to pull requests?
    In your PR description, include keywords like “Fixes #123” or “Closes #456.” When the PR merges, the issue closes automatically, and anyone reading the issue can trace the code change that resolved it.

    10) How do I handle merge conflicts?
    After a merge or rebase reports conflicts, open the conflicting files, search for conflict markers, decide the correct content, and remove markers. Stage the resolved files and continue the merge/rebase. Resolve small conflicts quickly by syncing branches more often.

    11) What are tags and why use them?
    Tags label specific commits—commonly releases—so you can refer back to exact code states. Annotated tags include messages and metadata and are ideal for releases. Push tags to share them and to trigger deployments in CI/CD.

    12) What should I automate first?
    Start with linting and tests in CI for every pull request, then add security scans, type checks, and coverage thresholds. Protect the main branch by requiring at least one approval and passing checks. Add CODEOWNERS to route reviews to the right people.


    References

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Exit mobile version