In a git repository everything normally starts with an initial commit and all other commits are ancestors of this first commit. But is it possible to create a second initial commit or even a third? Another initial commit with a complete different working directory? Yes it is.
Git provides a convenience command to create an independent branch.
git checkout --orphan <BRANCH_NAME>
Even if a simple git command exists I want to dive into the depth of git now and use low-level commands to do the same in order to show you how git works internally.
Create an independent branch step by step
Lets assume you have checked out some branch, e.g. the master branch. The symbolic ref HEAD will point to ref: refs/heads/master and refs/heads/master is just a file that contains the commit id of the master branch.
Now if you just do a git commit, git will
- create a new commit object
- set the parent to the commit object that HEAD points to (master)
- update the ref that the symbolic ref HEAD points to (master)
So if you want to create a another initial commit you must update the symbolic-ref HEAD and point it to something else.
$ git symbolic-ref HEAD refs/heads/secondMaster
Note: Since the ref secondMaster does not exist yet it is displayed transparent.
Now that you have changed the symbolic ref HEAD to point to the nonexistent ref refs/heads/secondMaster you are ready to create a new initial commit. But changing the symbolic ref HEAD does not change the staging area. Since you were on master before you changed the symbolic-ref HEAD, the staging area still contains the tree object of the master branch. You can see this if we do a git status.
$ git status On branch secondMaster Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: ..... new file: ..... new file: ..... ......
At this point you can just take the tree object of the master and commit it as a new initial commit or you can clear the staging area and working direcotry to begin a new working directory structure.
If you want a clean staging area and working directory you can do a simple git reset, because HEAD does not point to any commit and therefore git reset will clear the staging area.
$ git reset
Now that the staging area is cleared you can also clear the working directory.
$ git clean -d -f
The working directory is clean now and you can create new files, add them to the staging area and finally commit them.
$ mkdir someExampleDir $ touch someExampleDir/exampleFile $ git add . $ git commit -m 'Another initial commit'
The commit that is created is completely independet of all other commits in the current repository and you can see this in the log.
$ git log commit aa6179787e85c7bad6a00db3b0a41a98fbdccda3 Author: René Link <email@example.com> Date: Sun Nov 23 09:45:19 2014 +0100 Another initial commit