GitHub Manual
Source: git-scm.com / docs.github.com Author: Johan Beysen
1. Concepts — Git vs GitHub
| Git | GitHub | |
|---|---|---|
| What | Version control system (local) | Hosting platform for Git repositories |
| Where | On your machine | In the cloud |
| Made by | Linus Torvalds (2005) | Microsoft (acquired 2018) |
| Without internet | Fully functional | Not reachable |
Git is the engine. GitHub is the garage where you store and share it.
2. Installation & Initial Configuration
2.1 Installation
2.2 Setting Your Identity
This is required — every commit carries your name and email.
git config --global user.name "Johan Beysen"
git config --global user.email "johan@foxandfish.be"
# Set the default editor
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "vim" # Vim
# Default branch name
git config --global init.defaultBranch main
# Check your configuration
git config --list
2.3 Creating an SSH Key (recommended)
# Generate a new SSH key
ssh-keygen -t ed25519 -C "johan@foxandfish.be"
# Start the SSH agent
eval "$(ssh-agent -s)"
# Add the key to the agent
ssh-add ~/.ssh/id_ed25519
# Copy the public key (paste into GitHub → Settings → SSH Keys)
cat ~/.ssh/id_ed25519.pub
Testing it:
SSH vs HTTPS
SSH is more comfortable for daily use — no password needed on every push. HTTPS requires a Personal Access Token (PAT) as the password.
3. The Basics — Working Locally
3.1 Creating a Repository
# Starting a new project
mkdir my-project && cd my-project
git init
# Cloning an existing GitHub project locally
git clone git@github.com:JohanBeysen/my-repo.git
git clone https://github.com/JohanBeysen/my-repo.git
3.2 The Git Workflow
Working Directory → Staging Area → Repository (local) → Remote (GitHub)
[edit] [git add] [git commit] [git push]
# Viewing status (what has changed?)
git status
# Adding a specific file to staging
git add file.md
# Adding everything
git add .
# With selection (interactive)
git add -p
# Creating a commit
git commit -m "Add nmap reference"
# Add + commit in one step (only for already-tracked files)
git commit -am "Update nmap section"
3.3 Viewing History
# Full log
git log
# Compact (one line per commit)
git log --oneline
# Visual with branches
git log --oneline --graph --all
# Last 5 commits
git log -5 --oneline
# Commits by a specific author
git log --author="Johan"
# Commits that contain a certain word
git log --grep="nmap"
# Changes to a specific file
git log --follow file.md
3.4 Viewing Changes
# What has changed (working directory vs staging)
git diff
# What's in staging (vs the last commit)
git diff --staged
# Compare two commits
git diff abc123 def456
# Compare two branches
git diff main feature/new-section
4. Branches
Branches are parallel versions of your project. The main branch is the stable version — you work in feature branches and merge when ready.
4.1 Managing Branches
# Viewing all branches
git branch # local
git branch -r # remote
git branch -a # everything
# Creating a new branch
git branch feature/xss-section
# Switching to a branch
git checkout feature/xss-section
# Create + switch in one step (recommended)
git checkout -b feature/xss-section
# New syntax (Git 2.23+)
git switch -c feature/xss-section
# Renaming a branch
git branch -m old-name new-name
# Deleting a branch (locally)
git branch -d feature/xss-section # safe (only if merged)
git branch -D feature/xss-section # force
4.2 Merging
# Make sure you're on the target branch
git checkout main
# Merge the feature branch into main
git merge feature/xss-section
# Merge without fast-forward (preserves branch history)
git merge --no-ff feature/xss-section
# Squash — combine all commits from the branch into one
git merge --squash feature/xss-section
git commit -m "Add XSS section"
4.3 Rebase
Rebase replays your commits on top of another branch — results in a clean, linear history.
# Rebase a feature branch on top of main
git checkout feature/xss-section
git rebase main
# Interactive rebase (reorder, squash, edit commits)
git rebase -i HEAD~3 # Last 3 commits
Rebase vs Merge
Use merge for public branches that others also use. Use rebase on your own feature branches before merging — it makes the history cleaner.
Never rebase commits that have already been pushed to a shared remote.
4.4 Resolving Merge Conflicts
A conflict arises when the same line has been changed differently in two branches.
# Git marks conflicts in the file:
<<<<<<< HEAD
This is the version in main
=======
This is the version in the feature branch
>>>>>>> feature/xss-section
Steps:
- Open the file, choose which version you want (or combine them)
- Remove the conflict markers (
<<<<<<<,=======,>>>>>>>) - Stage the resolved file:
git add file.md - Commit:
git commit
5. Working Remotely — GitHub
5.1 Managing Remotes
# Which remotes are configured?
git remote -v
# Adding a remote
git remote add origin git@github.com:JohanBeysen/repo.git
# Changing the remote URL (e.g. from HTTPS to SSH)
git remote set-url origin git@github.com:JohanBeysen/repo.git
# Removing a remote
git remote remove origin
5.2 Push & Pull
# Push to the remote (first time: -u sets up upstream tracking)
git push -u origin main
# After that, simply
git push
# Pushing a specific branch
git push origin feature/xss-section
# Deleting a remote branch
git push origin --delete feature/xss-section
# Pull = fetch + merge
git pull
# Only fetch, don't merge yet
git fetch origin
# Fetch + rebase (cleaner than pull)
git pull --rebase
5.3 Pull Requests
A Pull Request (PR) is a request to merge your branch into another branch — the standard workflow for collaboration.
Workflow:
# 1. Create a branch
git checkout -b feature/bloodhound-section
# 2. Work and commit
git add .
git commit -m "Add BloodHound section"
# 3. Push to GitHub
git push -u origin feature/bloodhound-section
# 4. Create a PR on GitHub (or via CLI)
gh pr create --title "BloodHound section" --body "Description of changes"
# 5. After approval: merge on GitHub
# 6. Clean up locally
git checkout main
git pull
git branch -d feature/bloodhound-section
6. Undoing Things
6.1 Overview
| Situation | Command |
|---|---|
| Remove a file from staging | git restore --staged file.md |
| Undo changes in the working dir | git restore file.md |
| Undo the last commit (keep changes) | git reset HEAD~1 |
| Undo the last commit (discard changes) | git reset --hard HEAD~1 |
| Undo a commit via a new commit | git revert <commit-hash> |
| Restore a file to a specific commit | git checkout <hash> -- file.md |
6.2 Reset vs Revert
# Reset: rewrites history (dangerous on shared branches!)
git reset --soft HEAD~1 # Commit gone, changes in staging
git reset --mixed HEAD~1 # Commit gone, changes in the working dir (default)
git reset --hard HEAD~1 # Commit gone, changes gone
# Revert: creates a new commit that undoes the changes
# Safe on shared branches
git revert abc123
git revert HEAD
reset --hard
git reset --hard permanently discards changes. There's no undo. Use with care.
6.3 Reflog — The Safety Net
Git keeps track of what HEAD was, even after resets. reflog is your time machine.
# View all recent HEAD positions
git reflog
# Restore to a position from before a reset
git reset --hard HEAD@{3}
# Or via a hash from the reflog
git reset --hard abc123f
Recovering lost commits
Even after git reset --hard, commits are rarely truly gone — they still sit in the reflog until Git garbage-collects them (90 days by default).
7. Stash
Stash temporarily stores your uncommitted changes so you can switch branches.
# Stashing current changes
git stash
# With a description
git stash push -m "WIP: nmap section"
# Including untracked files
git stash -u
# Viewing all stashes
git stash list
# Restoring a stash (and removing it from the list)
git stash pop
# Restoring a specific stash
git stash pop stash@{2}
# Viewing a stash without applying it
git stash show stash@{0}
git stash show -p stash@{0} # with diff
# Removing a stash
git stash drop stash@{0}
git stash clear # all of them
8. Tags
Tags mark specific points in history — typically for releases.
# Lightweight tag
git tag v1.0
# Annotated tag (recommended — includes metadata)
git tag -a v1.0 -m "First stable release"
# Tag on a specific commit
git tag -a v0.9 abc123 -m "Beta release"
# Viewing all tags
git tag
git tag -l "v1.*" # filter
# Pushing a tag to the remote
git push origin v1.0
git push origin --tags # all tags
# Deleting a tag
git tag -d v1.0 # locally
git push origin --delete v1.0 # remote
9. .gitignore
The .gitignore file tells Git which files to ignore.
# Typical .gitignore for a Python project
__pycache__/
*.pyc
*.pyo
.env
.venv/
*.egg-info/
dist/
build/
.DS_Store
Credentials in Git
Never commit API keys, passwords or tokens. Always use .env files and put them in .gitignore. If it happens anyway, treat the credentials as compromised and rotate them immediately.
# Ignoring an already-tracked file
git rm --cached file.md
# Add it to .gitignore
# Commit
# Checking whether a file is ignored
git check-ignore -v file.md
# Viewing all ignored files
git status --ignored
Global gitignore (for all projects):
10. Advanced Commands
10.1 Cherry-Pick
Copy a specific commit from another branch.
# Copy commit abc123 to the current branch
git cherry-pick abc123
# Multiple commits
git cherry-pick abc123 def456
# A range
git cherry-pick abc123..def456
# Without committing immediately (puts changes in staging)
git cherry-pick --no-commit abc123
10.2 Bisect — Tracking Down Bugs
Bisect uses binary search to find the commit that introduced a bug.
# Start bisect
git bisect start
# The current version is broken
git bisect bad
# Tell it where it still worked
git bisect good v1.0
# Git now checks out a commit in the middle
# Test whether the bug is present, then:
git bisect bad # or
git bisect good
# Git keeps halving until the guilty commit is found
# Afterward:
git bisect reset
10.3 Blame
Who wrote which line (and in which commit)?
# Annotate every line with author + commit
git blame file.md
# With timing info
git blame -t file.md
# Specific lines
git blame -L 10,20 file.md
# Ignore whitespace changes
git blame -w file.md
10.4 Submodules
Embedding one repository inside another.
# Adding a submodule
git submodule add git@github.com:user/library.git libs/library
# When cloning a repo with submodules
git clone --recurse-submodules git@github.com:user/repo.git
# Or after cloning
git submodule init
git submodule update
# Updating submodules
git submodule update --remote
10.5 Worktrees
Checking out multiple branches at the same time in separate directories.
# Checking out a second branch in a separate directory
git worktree add ../project-hotfix hotfix/critical-bug
# Viewing all worktrees
git worktree list
# Removing a worktree
git worktree remove ../project-hotfix
11. GitHub CLI — gh
The official GitHub command-line tool.
# Installing
winget install GitHub.cli # Windows
brew install gh # macOS
sudo apt install gh # Linux
# Logging in
gh auth login
# Creating a repository
gh repo create my-repo --public
gh repo create my-repo --private
# Cloning a repository
gh repo clone JohanBeysen/my-repo
# Creating a Pull Request
gh pr create --title "Title" --body "Description"
# Viewing PRs
gh pr list
gh pr view 42
gh pr checkout 42
# Merging a PR
gh pr merge 42 --squash
# Issues
gh issue create --title "Bug found" --body "Description"
gh issue list
gh issue close 7
# Viewing GitHub Actions
gh run list
gh run view 12345678
gh run watch # live follow
# Creating a Gist
gh gist create file.md --public
12. GitHub Actions — CI/CD
GitHub Actions automates tasks on events (push, PR, schedule...).
12.1 Basic Workflow
# .github/workflows/deploy.yml
name: Deploy MkDocs to Cloudflare Pages
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install MkDocs
run: pip install mkdocs-material
- name: Build the site
run: mkdocs build
- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: knowledge-base
directory: site
12.2 Managing Secrets
12.3 Useful Triggers
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Every Monday at 6am
workflow_dispatch: # Trigger manually via the UI
13. Git Aliases — Shortcuts
# Add to ~/.gitconfig or via commands:
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.unstage "restore --staged"
git config --global alias.last "log -1 HEAD"
git config --global alias.aliases "config --get-regexp alias"
# Usage:
git st
git lg
git last
14. Git Internals — How It Really Works
14.1 The Four Object Types
| Type | Description |
|---|---|
| blob | The contents of a file |
| tree | Directory structure (references blobs and other trees) |
| commit | Snapshot + metadata (author, message, parent commit) |
| tag | A reference to a commit with metadata |
# Viewing the type of an object
git cat-file -t abc123
# Viewing its contents
git cat-file -p abc123
# Viewing all objects
find .git/objects -type f
14.2 HEAD, Index and Working Tree
Working Tree = the files you see and edit
Index = the staging area (.git/index)
HEAD = a reference to the current commit/branch
# What does HEAD point to?
cat .git/HEAD
# Which branch is active?
git symbolic-ref HEAD
# Hash of the current commit
git rev-parse HEAD
14.3 Refs
# Branches are just pointers to commits
cat .git/refs/heads/main
# Tags
cat .git/refs/tags/v1.0
# Remote tracking branches
cat .git/refs/remotes/origin/main
15. Workflow Strategies
15.1 GitHub Flow (simple)
Ideal for: small teams, continuous deployment.
15.2 Git Flow (complex)
main (production)
develop (integration)
feature/* (new features)
release/* (release preparation)
hotfix/* (urgent fixes on production)
Ideal for: versioned software with planned releases.
15.3 Trunk-Based Development
Ideal for: high deployment frequency, strong CI/CD.
16. Cheat Sheet
# === SETUP ===
git config --global user.name "Name"
git config --global user.email "email"
git init
git clone <url>
# === DAILY ===
git status
git add .
git commit -m "message"
git push
git pull
# === BRANCHES ===
git checkout -b feature/name
git merge feature/name
git branch -d feature/name
git push origin --delete feature/name
# === UNDOING ===
git restore file.md # undo in working dir
git restore --staged file.md # unstage
git reset HEAD~1 # undo the last commit
git revert <hash> # safe to undo on a remote
# === HISTORY ===
git log --oneline --graph --all
git diff
git blame file.md
git reflog
# === REMOTE ===
git remote -v
git fetch origin
git push -u origin main
git push origin --delete branch
# === STASH ===
git stash
git stash pop
git stash list