Old vs New Git & Git 3.0
Git is twenty years old, and the internet is full of advice written for older versions. You will meet git checkout for everything, master branches, git stash save and many more in tutorials, Stack Overflow answers, company scripts and interview questions. The old commands mostly still work, but newer ones are clearer and safer.
This lesson is a translation guide from old to new, shows how to rename master to main in an existing project, and summarises what recent Git versions added and what the Git project has announced for Git 3.0.
Old commands and their modern versions
| Older way | Modern way | Why the new one is better |
|---|---|---|
git checkout feature | git switch feature | switch only changes branches |
git checkout -b feature | git switch -c feature | Same job, clearer name |
git checkout <commit> | git switch --detach <commit> | Makes detached HEAD an explicit choice |
git checkout -- file.txt | git restore file.txt | restore only restores files |
git reset HEAD file.txt | git restore --staged file.txt | Unstaging without the scary word "reset" |
git checkout v1.0 -- file.txt | git restore --source=v1.0 file.txt | The source is named explicitly |
git stash save "msg" | git stash push -m "msg" | push also accepts file paths |
git push --force | git push --force-with-lease | Will not overwrite commits you have not seen |
git config --global user.name "x" | git config set --global user.name "x" | Subcommands added in Git 2.46 |
git whatchanged | git log --raw | whatchanged is being removed |
git switch and git restore arrived in Git 2.23 (2019) to split the overloaded git checkout into two focused commands. They were marked experimental at first; that warning is no longer in the current manual, and they are the commands Git itself suggests in its hints.
Why checkout was confusing
git checkout did two unrelated jobs: switching branches and overwriting files. The same word with a different argument could either move you safely to another branch or silently throw away your edits. Both still work in Git 2.56:
git checkout -b biology
git checkout main
git checkout -- physics.mdSwitched to a new branch 'biology' Switched to branch 'main'
The third command discarded every uncommitted change in physics.md without a word. The new commands refuse to guess. If you give git switch a file name by mistake, it stops instead of touching the file:
git switch physics.mdfatal: invalid reference: physics.md
You should still recognise checkout, because many scripts, CI files and older teammates use it. In your own work, prefer switch and restore.
Removed and deprecated commands
The Git project removes old commands slowly, with warnings first. git whatchanged, an old way to list commits with their changed files, now refuses to run and explains what to use instead:
git whatchanged -1'git whatchanged' will be removed soon. hint: You can replace 'git whatchanged <opts>' with: hint: git log <opts> --raw --no-merges hint: Or make an alias: hint: git config set --global alias.whatchanged 'log --raw --no-merges'
(The full message also points to the Git mailing list for people who still need it, and ends with fatal: refusing to run without --i-still-use-this.) The modern equivalent, git log --raw, shows the same information:
git log --raw -1commit 5de7c609a59b1e56a706f05a3e27cba029a48e43 (HEAD -> main)
Author: Priya Sharma <priya@example.com>
Date: Fri Oct 30 15:15:20 2026 +0530
Add notes: Chapter 4
:100644 100644 e04d255 82c6893 M physics.mdFrom master to main
For most of Git's life, the first branch was called master. In 2020 Git added the init.defaultBranch setting, and GitHub switched new repositories to main; most of the industry followed. Git 2.56 still defaults to master but warns about it every time you run git init without the setting (see Install & Configure Git).
To rename the branch in an existing project, the owner renames it locally, pushes main, and deletes master on the remote:
git branch -m master main
git push -u origin main
git push origin --delete masterTo github.com:priya-sharma/old-shop.git * [new branch] main -> main branch 'main' set up to track 'origin/main'. To github.com:priya-sharma/old-shop.git - [deleted] master
On GitHub, a repository's default branch cannot be deleted, so do it in a different order there: push main, change the default branch in Settings (GitHub's branch rename button does this and updates open pull requests for you), and only then delete master. Teammates who cloned earlier update their copies with four commands:
git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -aFrom github.com:priya-sharma/old-shop * [new branch] main -> origin/main branch 'main' set up to track 'origin/main'. 'origin/HEAD' has changed from 'master' and now points to 'main'
Finally, git fetch --prune removes their stale origin/master bookmark. Remember to update CI files, deployment scripts and documentation that mention master.
What recent versions added
A few additions from recent releases that this course uses:
- Git 2.46:
git configsubcommands (set,get,list,unset). - Git 2.45: the reftable format for refs, available with
git init --ref-format=reftable. - Git 2.56:
git add --resolved, which stages only conflicted files and refuses those still containing conflict markers;git bisect run --reset-when-found; andgit log --graphnow indents unrelated histories so they do not look connected.
Git 2.56 also includes an experimental git history command with subcommands such as reword, split, fixup and drop, for editing a commit without starting an interactive rebase. Its manual says the behaviour may change, so learn interactive rebase first.
What is planned for Git 3.0
The Git project keeps a public document, Breaking Changes, listing changes that are too disruptive for a normal 2.x release and are saved for Git 3.0. It states there is no planned release date yet. The changes it lists include:
- SHA-256 by default: new repositories will use SHA-256 object names instead of SHA-1 (see How Git Stores Data). This depends on the wider ecosystem, such as hosting services and other Git tools, supporting SHA-256.
- reftable by default: new repositories will store branches and tags in the reftable format instead of one file per ref.
mainas the default branch name for new repositories.- Rust becomes a required part of building Git from source. This affects people who compile Git, not everyday users.
- A safer
safe.bareRepositorydefault: Git will stop automatically using bare repositories it finds inside other folders, which blocks an attack using hidden repositories with malicious hooks. - Removals of long-deprecated features, including
git whatchanged,git pack-redundant, grafts (replaced bygit replace), and thename-rev --stdinoption (use--annotate-stdin).
The project also says the last version before 3.0 will be a long-term support release that keeps receiving important fixes for a while, giving everyone time to move.
Common mistakes
- Copying an old tutorial line by line. Translate
checkouttoswitchorrestorewith the table above. - Renaming
masterwithout telling the team. Their pushes fail or recreatemaster. Share the four update commands. - Forgetting CI and deployment settings that name the old branch.
- Believing rumours about Git 3.0. Only the official Breaking Changes document is reliable.
Key points
git switchandgit restore(Git 2.23+) replace the two jobs ofgit checkout; old forms still work.- Prefer
git restore --stagedovergit reset HEAD <file>,stash pushoverstash save, and--force-with-leaseover--force. - Deprecated commands such as
git whatchangednow refuse to run and suggest replacements. - Rename
mastertomainwithgit branch -m, push, change the default on GitHub, then deletemaster; teammates rename and re-track. - Git 3.0 plans SHA-256, reftable and
mainas defaults, plus some removals; there is no release date yet.
Exercise
Translate this old instruction list into modern Git commands: (1) git checkout -b login-page; (2) git checkout -- index.html; (3) git reset HEAD style.css; (4) git checkout main; (5) git stash save "half done"; (6) git push --force. Then set up a new repository that starts on main without the master hint.
Show solution
git switch -c login-page
git restore index.html
git restore --staged style.css
git switch main
git stash push -m "half done"
git push --force-with-lease
git config set --global init.defaultBranch main
git init new-projectEach modern command does exactly one job. With init.defaultBranch set, git init creates main and prints no hint.
Quick Quiz
1. What is the modern replacement for git checkout -- file.txt?
restore handles files; switch handles branches.
2. What happens when you run git whatchanged in Git 2.56?
The command is scheduled for removal in Git 3.0.
3. Which change is planned for Git 3.0 according to the official Breaking Changes document?
The document lists SHA-256, reftable and main as new defaults.
4. When was Git 3.0 scheduled for release according to that document?
The document states that no release date has been set.
Learn Git with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
