I have an existing repo with some branches. I want to create a new branch without any history on that repo. I'm trying to do this using Dulwich, which supports most git operations, though not the orphan flag.
What are the equivalent Git operations to create an orphan branch without actually using that flag? Ideally i'd like to:
Is this possible or do I need to create a new branch that's empty, clone to a separate directory and copy the contents back?
Note: I don't use Dulwich and cannot say for sure anything about it. Depending on how much of Git it re-implements from scratch, what Git does may be irrelevant.
An orphan branch, in Git, is actually a branch that doesn't exist. What git checkout --orphan newbranch
does is to write the name newbranch
into HEAD
, without actually creating newbranch
.
More specifically, aside from consistency and error checking,1 the difference between:
git checkout -b newbranch
and:
git checkout --orphan newbranch
is that the former runs:
git update-ref refs/heads/newbranch HEAD && \
git symbolic-ref HEAD refs/heads/newbranch
and the latter runs:
git symbolic-ref HEAD refs/heads/newbranch
The first step, git update-ref
, actually creates the branch.
The second step, git symbolic-ref
, sets us up to be "on" the branch.
An orphan branch, then, is one that we are "on" that does not exist.
The actual branch creation happens later, when we make a new commit. So it's not git checkout
that creates these; it's git commit
! The commit operation fundamentally consists of:
git write-tree
);HEAD
and check for pending merges);HEAD
into the current branch name (or directly into HEAD
if HEAD
is detached).Step 5 is where the branch gets created. During step 2, if HEAD
names a branch that does not exist, it contributes no parent hash ID, so that the new commit has no parents (presumably there are no recorded additional parents for merges at this time).
If Dulwich behaves the same as Git here—it very well might, because this peculiar state, of being on a branch that does not exist, is how Git bootstraps an empty repository, and it's the obvious way to do it—then all you have to do to implement what you want directly is to rewrite the HEAD
information (however Dulwich stores it) so that it points to this non-existent branch.
1git checkout -b newbranch
also offers git checkout -b newbranch startpoint
. Using a different starting point has a whole cascade of side effects: Git first attempts to do git checkout startpoint
internally, which may make arbitrary modifications to index and work-tree.