Introduction
I made this research to help myself and fellow developers quickly get up to speed with Git and GitHub. It covers essential commands and workflows for local and remote version control, collaboration, and best practices.
Multiplatform Software Developer — Git & GitHub: Complete Command Guide
I made this research to help myself and fellow developers quickly get up to speed with Git and GitHub. It covers essential commands and workflows for local and remote version control, collaboration, and best practices.
Install Git on your machine and configure your identity (login) and preferred editor. (Not sure? try VSCode)
# macOS (Homebrew)
brew install git
# Ubuntu / Debian, (update helps get the latest packages)
sudo apt update && sudo apt install git -y
# Windows
# Install Git for Windows from Link
# set your name and email (used in commits)
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
# set default branch name (optional) but recommended
git config --global init.defaultBranch main
# set your preferred editor (vim, code, nano, etc.)
git config --global core.editor "code --wait"
# view config
git config --list
Tip: use --global for machine-wide
settings; omit it to set values per-repo.
Create repos, track files, commit changes, and inspect history.
# create a local repo in the current directory
git init
# create a new directory and initialize
mkdir myproject && cd myproject
git init
# clone a GitHub repository
git clone git@github.com:username/repo.git
# or via HTTPS
git clone https://github.com/username/repo.git
# see changed files in your workflow (selected folder)
git status
# add a file to staging (waiting to be committed)
git add README.md
# add everything (careful)
git add .
# commit with a message 💆
git commit -m "feature: done adding something cool"
# remember if you don't want a certain file to be pushed to github,
simply add it to a .gitignore file in the root of your project
example of unneded files to add to .gitignore
# .build
# .some big assets you don't want to push to github
#
# see all commits in one simple line per commit, with a mini branch graph
git log --oneline --graph --decorate --all
# see the full history of a single file (even if it was renamed)
git log --follow -- README.md
# see details of a specific commit (what exactly changed)
git show
Think of branches like different versions of your project. They let you work on a new feature or bug fix safely, without touching your main code at all 🐐😎. When you are done, you can merge (combine) your code back into the main branch.
# create a new branch and move into it
# (like making a safe workspace for a new feature)
git checkout -b feature/login
# same as above, using the newer 'switch' command
git switch -c feature/login
# see all branches you have (local and online)
git branch --all
# go back to the main branch
git switch main
# combine your branch changes into the main branch
git merge feature/login
# delete your branch after merging (clean up)
git branch -d feature/login
# force delete a branch (if it wasn't merged yet)
git branch -D feature/login
When you merge a branch, Git has two main ways of doing it:
If you want to always create a merge commit (even when Git could fast-forward), use:
git merge --no-ff feature/login -m "Merge feature/login"
Sometimes Git can't automatically merge two branches because both changed the same lines of code. This is called a merge conflict. You'll see conflict markers in the file like this:
<<<<<<< HEAD
your version of the code
=======
the version from the other branch
>>>>>>> feature/login
To fix it:
<<<<<<< and
>>>>>>>).git add conflicted-file.ext
git commit
💡 Tip: Use VS Code or GitHub Desktop to make resolving conflicts easier, they highlight changes visually so you can pick what to keep.
Connect your local repo to GitHub, push, pull, and manage remotes.
# add a remote (name: origin)
git remote add origin git@github.com:username/repo.git
# view remotes
git remote -v
# rename remote
git remote rename origin upstream
# remove remote
git remote remove upstream
# push current branch and set upstream (first push)
git push -u origin main
# push later
git push
# pull remote changes (merge)
git pull
# fetch only (doesn't merge)
git fetch origin
# fetch + prune deleted remote branches
git fetch --prune origin
git push --set-upstream origin feature/login
# short form (if upstream exists)
git push -u origin feature/login
On GitHub you typically push a branch and open a Pull Request (PR) for review and CI.
# typical flow
1. git checkout -b feature/x
2. work & commit locally
3. git push -u origin feature/x
4. open PR on GitHub (website) from feature/x into main
5. address review comments by pushing more commits
6. when approved, merge on GitHub (or via CLI)
Merge commit ✔️ keeps all commits and creates a
merge commit.Squash and merge ✔️ squashes branch commits to one
commit on target.Rebase and merge ✔️ rebases branch commits onto
base
without merge commit.Common safe ways to undo mistakes. Always be careful with commands that rewrite history (push --force).
# undo local changes (unstaged)
git restore file.txt
# unstage a staged file
git restore --staged file.txt
# change last commit message
git commit --amend -m "chore: improved message"
# reset to previous commit (soft keeps changes staged)
git reset --soft HEAD~1
# hard reset discards working tree changes (danger)
git reset --hard HEAD~1
# recover a deleted branch (if recent)
git reflog
# find HEAD@{N} then
git checkout -b recovered
If you amend or rebase and already pushed, you'll
need git push --force-with-lease to update remote
safely. Avoid --force unless you understand
consequences.
# rebase the last N commits interactively
git rebase -i HEAD~4
git fetch origin
git switch feature/x
git rebase origin/main
# resolve conflicts, then continue
git rebase --continue
# apply a single commit from another branch
git cherry-pick
# pick a range
git cherry-pick A..B
# stash changes
git stash push -m "WIP: login form"
# list stashes
git stash list
# apply most recent stash (keep in stash)
git stash apply
# pop (apply + drop)
git stash pop
# apply a named stash
git stash apply stash@{2}
# drop a stash
git stash drop stash@{2}
Prefer SSH keys for convenience or use a Personal Access Token (PAT) for HTTPS in scripts/CI.
# generate SSH key (ed25519 recommended)
ssh-keygen -t ed25519 -C "you@example.com"
# start ssh agent and add key
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# copy to clipboard (macOS)
pbcopy < ~/.ssh/id_ed25519.pub
# then paste into GitHub > Settings > SSH and GPG keys
If using HTTPS in scripts, create a PAT on GitHub with minimum scopes and store it securely (use your OS keyring or GitHub CLI).
# GitHub CLI install
# macOS
brew install gh
# login
gh auth login
# create a PR from terminal
gh pr create --title "feat: add login" --body "details" --base main --head feature/login
# merge PR from terminal
gh pr merge 123 --merge
GitHub Actions are CI/CD workflows stored in
.github/workflows/. Use actions to run tests, linters,
builds, and deploys on push or PR events.
type(scope): short description.
main always
deployable.git commit -S).# test SSH connection
eval "$(ssh-agent -s)"
ssh -T git@github.com
# if asked to login via browser, follow the link displayed by gh auth login
# common cause: remote has new commits
git pull --rebase origin main
# then resolve conflicts, push
git push
# if you rebased and need to overwrite remote (use with caution)
git push --force-with-lease origin your-branch
# basic
git init
git clone
git status
git add .
git commit -m "message"
git push -u origin main
git pull
# branching
git checkout -b feature/x
git switch feature/x
git merge main
# undo
git restore file
git restore --staged file
git reset --soft HEAD~1
git reset --hard HEAD~1
# history
git log --oneline --graph --decorate --all
# stash
git stash push -m "wip"
git stash pop
# fetch & prune
git fetch --prune origin
# reflog
git reflog
# push force safely
git push --force-with-lease