Old vs New Git & Git 3.0

Git · Lesson 27 of 28 7 min read Updated

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 wayModern wayWhy the new one is better
git checkout featuregit switch featureswitch only changes branches
git checkout -b featuregit switch -c featureSame job, clearer name
git checkout <commit>git switch --detach <commit>Makes detached HEAD an explicit choice
git checkout -- file.txtgit restore file.txtrestore only restores files
git reset HEAD file.txtgit restore --staged file.txtUnstaging without the scary word "reset"
git checkout v1.0 -- file.txtgit restore --source=v1.0 file.txtThe source is named explicitly
git stash save "msg"git stash push -m "msg"push also accepts file paths
git push --forcegit push --force-with-leaseWill 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 whatchangedgit log --rawwhatchanged 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:

Terminal
git checkout -b biology
git checkout main
git checkout -- physics.md
Output
Switched 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:

Terminal
git switch physics.md
Output
fatal: 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:

Terminal
git whatchanged -1
Output
'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:

Terminal
git log --raw -1
Output
commit 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.md

From 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:

Terminal
git branch -m master main
git push -u origin main
git push origin --delete master
Output
To 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:

Terminal
git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -a
Output
From 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 config subcommands (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; and git log --graph now 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.
  • main as 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.bareRepository default: 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 by git replace), and the name-rev --stdin option (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 checkout to switch or restore with the table above.
  • Renaming master without telling the team. Their pushes fail or recreate master. 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 switch and git restore (Git 2.23+) replace the two jobs of git checkout; old forms still work.
  • Prefer git restore --staged over git reset HEAD <file>, stash push over stash save, and --force-with-lease over --force.
  • Deprecated commands such as git whatchanged now refuse to run and suggest replacements.
  • Rename master to main with git branch -m, push, change the default on GitHub, then delete master; teammates rename and re-track.
  • Git 3.0 plans SHA-256, reftable and main as 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
Terminal
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-project

Each 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?

2. What happens when you run git whatchanged in Git 2.56?

3. Which change is planned for Git 3.0 according to the official Breaking Changes document?

4. When was Git 3.0 scheduled for release according to that document?

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