On Monday, 17 November, I gave a short training on Git & GitHub to students at Marmara University, and I’d like to share here a slightly more detailed version of the presentation I prepared for that session.

Why Version Control?

Human memory is unreliable; Git is the memory of your code. The era of copying files as “final_v3_son_bu_gercekten.zip” ended with the arrival of Git.

  • Git keeps a commit history like a time machine,
  • It lets teams work in parallel,
  • It makes it possible to roll back mistakes,
  • It gives a clear answer to “Who changed what, and when?”.

Git is a standalone local tool; GitHub is a cloud platform that hosts Git repositories and adds collaboration tools (Pull Request, Issues, Actions, etc.).

Short History & Today’s Use Cases

Git was designed in 2005 by Linus Torvalds to meet the distributed development needs of the Linux kernel. GitHub was founded in 2008 by Tom Preston-Werner, Chris Wanstrath, and PJ Hyett. It popularized the idea of “social coding”: Pull Request culture, starring, following, Issues/Wiki, etc. In 2018, it was acquired by Microsoft.

Use cases:

  • Open source projects
  • Private in-company repositories
  • DevOps / CI-CD

In short; Git is the engine, GitHub is the highway + service stations.

Core Git Concepts

Repository (repo)

The root folder of the project tracked by Git. The real magic lives in the .git/ directory: commits, branches, references, configuration.

How to use

  • New repo: git init (local), git clone <url> (remote copy).

  • Default main branch: main (in older projects this may be master).

  • Bare repo (for servers): git init --bare (no working directory; only version data).

Common mistakes

  • Running git init in the wrong folder → unnecessary .git/. Fix: delete the .git/ directory or work in the right folder with git -C <path>.

  • Committing large files → push problems. Fix: use Git LFS.

Tips

  • Project-level settings: .git/config, global settings: ~/.gitconfig.

  • .gitattributes for line endings, language-specific diffs, LFS tracking.


Working Directory / Staging Area / Commit

  • Working Directory: The current state of the files on disk.

  • Staging Area (index): The snapshot of “what should go into the next commit”.

  • Commit: A “photo” of the repository.

How to use

  • Status: git status

  • Add to stage: git add <file> / git add -p (hunk by hunk)

  • Remove from stage: git restore --staged <file>

  • Discard local changes: git restore <file>

  • Commit: git commit -m "Summary message"

  • Fix the last commit: git commit --amend

Common mistakes

  • Wrong files in the commit → clean up with git reset --soft HEAD~1 or git restore --staged.

  • “.gitignore doesn’t work” → the file was already being tracked.

    git rm -r --cached .
    git add .
    git commit-m "Honor .gitignore"

Tips

  • Message standard: short summary (around 50 characters) + details on the following lines.

  • Signing: git commit -S (GPG/SSH signing) increases trust.


Branch

A lightweight pointer to a chain of commits. HEAD usually points to the active branch.

How to use

  • List/create/switch:

    git branch
    git switch -c feature/api
    git switch main
  • Merge: git merge feature/api
  • Rebase: git rebase main (clean history; use carefully)

Common mistakes

  • Messy history → too much rebase chaos instead of merge. Set a team standard.

  • Committed to the wrong branch → move with git switch -c correct/branch, use revert if needed.

Tips

  • Naming: prefixes like feat/, fix/, chore/, docs/.

  • Protected branches and push restrictions: from repository settings.


Remote

A remote host (GitHub/GitLab etc.). Often called origin, and upstream for the main repo in open source.

How to use

  • Add/show:

    git remote add origin https://github.com/user/repo.git
    git remote -v
  • Fetch/pull/push: git fetch, git pull, git push

Common mistakes

  • Authentication issues: use a Personal Access Token (HTTPS) or SSH key.

  • “non-fast-forward” push rejection → fetch remote changes first:

     
    git pull --rebase git push

Tips

  • Tracking branch: after git push -u origin main, you can just use short git push/pull.

  • --force-with-lease is a safer way to force push:

    git push --force-with-lease
     

Clone / Pull / Push

  • Clone: Creates a local copy of the remote repository.

  • Pull: Gets remote changes (fetch + merge/rebase).

  • Push: Sends local commits to the remote.

How to use

  • Fast clone: git clone --depth 1 <url> (when you don’t need full history)

  • Sparse checkout (selective folders in a monorepo):

    git sparse-checkout init --cone
    git sparse-checkout set path/subdir
  • Pull strategy:

    git config pull.rebase false   # merge
    git config pull.rebase true    # rebase

Common mistakes

  • “Diverged” warnings → confusion about strategy. Align with your team.

  • Huge pushes → use LFS or release assets.

Tips

  • git fetch + git log origin/main..HEAD to see what you’re about to push.

  • Push policy: disable direct pushes to main, require PRs.


Fork

A personal copy of someone else’s repo. Used to send contributions via PR.

How to use (open source flow)

  1. Click the Fork button.

  2. Clone your fork: git clone <your-fork-url>

  3. Add the original as upstream:

     
    git remote add upstream https://github.com/original/owner/repo.git
  4. Work on your own branch: git switch -c feat/x

  5. Push to your fork: git push -u origin feat/x

  6. Open a Pull Request on GitHub.

Staying in sync with upstream

git fetch upstream
git switch main
git merge upstream/main    # or rebase

When to use a branch instead of a fork?

  • If you have write access, opening a branch in the same repo is more practical.


Pull Request (PR)

The process of proposing changes, running automated checks, doing code review and merging.

Flow

  1. Push from your branch → “Compare & pull request” on GitHub.

  2. Clear title/summary, fill in the PR template if there is one.

  3. Reviewers and CI (Actions) run: tests/format/lint.

  4. Use a “Draft PR” if it’s not ready yet but you want discussion.

  5. Merge strategies: Merge, Squash, Rebase.

Common mistakes

  • Monster PRs: huge changes → split into smaller pieces.

  • No tests → CI red. Add at least some tests/linting, even for small changes.

Tips

  • Code Owners for automatic reviewers per file/directory.

  • Use “Require status checks” + “Require reviews” as quality gates.

  • “Squash merge” turns many small commits into a single one; history stays clean.


Issues / Wiki / Projects / Actions

Issues (tracking & planning)

  • Labels, assignees, milestones, issue templates.

  • “Good first issue” and “help wanted” are good signs for newcomers to open source.

  • Discussions: questions/ideas → separate from Issues, more like a forum.

Wiki (documentation)

  • Project guides, setup instructions, architecture, decision records.

  • Keep it in sync with the repo; include updates in the PR process.

Projects (kanban/roadmap)

  • With Projects (v2), you get table/board views, custom fields, automation.

  • Connect Issues/PRs to columns for an “In Progress/Done” style flow.

Actions (CI/CD automation)

  • Workflows are defined in YAML:

    • triggers: push, pull_request, schedule, workflow_dispatch

    • runners: ubuntu-latest etc.

    • secrets: deploy keys, tokens.

  • Example (Node tests):

    name: CI
    on:
      pull_request:
      push:
        branches: [ "main" ]
    jobs:
      test:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: actions/setup-node@v4
            with:
              node-version: "20"
          - run: npm ci
          - run: npm test --if-present
    

Common mistakes

  • Committing secrets → never put .env in the repo; use Secrets.

  • Misusing the runner cache → inconsistent builds; version your cache keys.

Tips

  • Issue/PR templates and automatic labeling (via Actions) help standardize the flow.

  • “Required reviewers” and “auto-merge on green” (auto merge when tests pass) help keep team velocity up.

 


 

To briefly summarize, the basic commands look like this:

# repo
git init
git clone <url>

# working directory / staging / commit

git status
git add -p
git commit -m "feat: add user login"
git commit --amend

# branch

git switch -c feat/login
git merge feat/login
git rebase main

# remote

git remote add origin 
git fetch --all
git pull --rebase
git push --force-with-lease

# fork sync

git remote add upstream 
git fetch upstream
git merge upstream/main   # or rebase