In my opinion, this command can be somewhat surprising. There are two
very different expectations that you might have for this command:
- Fresh start with a truncated history (same tree)
- Completely fresh start (new tree; you have to add files from scratch)
1: What it actually does
As JB. has explained, git checkout --orphan <branch name>
will:
- Put you on an orphan branch, which is a branch that does not have
any commits yet
- Stage the tree that you came from (
master^{tree}
if you were on
master
)
- Leave whatever unstaged and untracked files as-is
This means that the trees of the previous commit that you were on and
the commit that you create immediately after will be equal:[1]
$ # Let’s say that you’re currently on `master`
$ git checkout --orphan orphan
$ git commit --message 'A new start'
$ git diff master
The diff gives no output because the trees are equal.
This effectively truncates all the commits that you have on
master
. (Of course master
is still there.)
2: What you might expect it to do
Here’s what I expected it to do:
- Put you on an orphan branch
- Give you an empty tree
The use-case might be to add some files that document some
repository-wide metadata, e.g. branch metadata.[2]
It turns out that you can use git switch --orphan <branch name>
to
accomplish this task, since it almost does what I expected git checkout --orphan <branch name>
to do:
- Put you on an orphan branch
- Remove all tracked files from the tree but leave the untracked ones
- This means your new tree will contain all of the stuff that you
ignored through things like
.gitignore
- Use
git clean --force -d
if you want to remove all those
untracked files
But do note that this command is marked “EXPERIMENTAL” as of the time of
writing (Git 2.40.0).
Accomplishing the same thing with git checkout --orphan <branch name>
Maybe you don’t want to use an experimental command. This is the command
circumlocution that man git checkout
recommends that you do if you
want to start with a fresh tree:
git checkout --orphan orphan
git rm -rf .
And then you can also do (added by me):
git clean --force -d
Notes
Well, I guess it will in practice be exactly the same tree, since
they have the same hash. :)
Say:
$ <make orphan branch>
$ vim branch-descriptions.txt
$ git add branch-descriptions.txt
$ git commit --message "Init: descriptions"