Git basics — commits, branches, remotes, and safe recovery
What Git does
Git records snapshots of a project
Git is a distributed version control system. It records named snapshots of a project so you can compare changes, return to an earlier state, and combine work from different branches. A Git repository contains the project files you can see plus a hidden .git directory that stores commits, branch references, configuration, and recovery history.
Git and GitHub are not the same thing. Git is the version control software that runs on your computer. GitHub, GitLab, and Bitbucket host Git repositories and add collaboration features such as pull requests, issue tracking, and access control. You can use Git without any hosting service, and the same Git commands work with different hosts.
Core model
Working tree, staging area, and repository
Most everyday Git operations move changes through three places. The working tree is the files currently checked out on disk. The staging area, also called the index, is the exact set of changes prepared for the next commit. The repository is the permanent commit history stored under .git.
This separation is useful because you can edit several files but commit only the related changes. Run git status before and after each operation: it tells you which branch is checked out, which files are staged, and which changes are still only in the working tree.
git diffshows unstaged changes in the working tree.git diff --stagedshows what the next commit will contain.git add pathcopies the selected change into the staging area.git commitrecords the staged snapshot and points the current branch at it.
Daily workflow
A small, inspectable commit cycle
A reliable workflow is to inspect, stage, inspect again, then commit. Avoid starting with git add . when the working tree contains unrelated edits: stage paths intentionally so each commit describes one change. The final git status confirms whether anything was left behind.
git status
git diff
git add src/app.js tests/app.test.js
git diff --staged
git commit -m "Handle empty API responses"
git status
Branches and HEAD
Branches are movable names for commits
A commit has an identifier and points to its parent commit. A branch such as main is a movable name that normally points to the newest commit in one line of development. HEAD identifies what is currently checked out. In normal work, HEAD points to a branch; when it points directly to a commit, Git reports a detached HEAD.
Creating a branch does not copy the whole project. Git creates another lightweight reference to a commit. New commits move only the checked-out branch. Switching branches updates the working tree to match the selected commit, so commit or stash work that would be overwritten before switching.
git switch -c fix/api-timeout
# edit, test, stage, and commit
git switch main
git merge fix/api-timeout
Remotes
fetch, pull, and push move information between repositories
A remote is a saved name and URL for another Git repository. The conventional name origin has no special network behavior; it is simply the default name created by git clone. Remote-tracking names such as origin/main record the last remote state your local repository has fetched.
git fetch downloads commits and updates remote-tracking names without changing your working branch. git pull fetches and then integrates the upstream branch by merge or rebase. git push asks the remote to move one of its branch names to a commit you have locally. A non-fast-forward rejection protects remote commits that your local branch has not integrated.
git remote -v
git fetch origin
git log --oneline --decorate --graph --all -n 15
git pull --rebase origin main
git push origin main
Safe recovery
Inspect before rewriting or deleting
Git retains more recovery information than the visible branch list suggests. Before using reset --hard, clean, or force push, create a temporary branch or stash if the current work may matter. Prefer git restore for a file, git revert for a shared commit, and --force-with-lease instead of plain --force when rewriting a branch is genuinely required.
The reflog records recent movements of local references and HEAD. It can often recover a commit after an accidental reset, rebase, or branch deletion. Reflog is local to one repository and is eventually expired, so create a branch at the recovered commit as soon as you find it.
git status
git branch backup-before-recovery
git reflog --date=local
git switch -c recovered-work <commit-id>
Troubleshooting order
Identify the layer before applying a fix
Start with the exact error text and git status. Authentication errors occur before repository history can be exchanged; fix the remote URL, account, or SSH key first. Non-fast-forward errors mean authentication succeeded but histories differ. Merge conflicts mean Git downloaded both histories but could not combine particular lines automatically.
- Cannot read from remote or publickey error: inspect
git remote -vand test host authentication. - Push rejected as non-fast-forward: fetch, compare the histories, then rebase or merge.
- Conflict during merge or rebase: resolve the marked files, stage them, and continue or abort.
- Commit or branch appears lost: stop rewriting history and inspect
git reflog.
Related