The first few days I used Git, I messed up my repository. I had to reset and recreate it from scratch several times. With enough trials and errors, I came up with an idea of how I should initialize my repositories. Let me explain in this post why git init is not enough to me.
To create a Git repository, nothing else is absolutely necessary than these few trivial commands:
$ mkdir kev-code $ cd kev-code/ $ git init
But after reading some documentation and user experiences on the web, it looks like Git has some limitations when dealing with the root of a repository history. As I plan to heavily manipulate the commit history (to do some kind of code archaeology and history reconstruction), I need to have the widest time latitude to play with commits.
In this situation, I came to the conclusion that it’s a good idea to create an empty commit at the start of your repository life, and date it to the start of epoch. In the future, I’ll be able to leverage this intial commit as an ordinary history point from which I can start a branch. Then in this branch I’ll be free to mess up the history, until merging my changes back in the mainline tree.
So, let’s create an empty commit:
$ git commit --allow-empty -m 'Initial commit'
Then get the commit hash:
$ git log
commit 395290bcdb8ffccfbff89e42cb976077fbd3c1b7
Author: Kevin Deldycke <kevin@deldycke.com>
Date: Tue Dec 1 15:37:49 2009 +0100
Initial commit
We now change the commit date of our first commit to epoch start:
$ git filter-branch --env-filter ' > if [ $GIT_COMMIT = 395290bcdb8ffccfbff89e42cb976077fbd3c1b7 ] > then > export GIT_AUTHOR_DATE="Thu, 01 Jan 1970 00:00:00 +0000" > export GIT_COMMITTER_DATE="Thu, 01 Jan 1970 00:00:00 +0000" > fi' -- --all Rewrite 395290bcdb8ffccfbff89e42cb976077fbd3c1b7 (1/1) Ref 'refs/heads/master' was rewritten
And check that the previous operation did what we expected:
$ git log
commit 8fe2934d1552c97246836987f0ea08e10ba749ae
Author: Kevin Deldycke <kevin@deldycke.com>
Date: Thu Jan 1 00:00:00 1970 +0000
Initial commit
Looks good !
For convenience, we’ll now attach a tag to this initial commit. Let’s call it init:
$ git tag "init"
This will came handy later when we’ll need to create a branch from here.
It’s time to push all changes to our brand new public repository:
$ git remote add origin git@github.com:kdeldycke/kev-code.git $ git status # On branch master nothing to commit (working directory clean) $ git push origin master --force Counting objects: 2, done. Writing objects: 100% (2/2), 159 bytes, done. Total 2 (delta 0), reused 0 (delta 0) To git@github.com:kdeldycke/kev-code.git + 86bd2c7...8fe2934 master -> master (forced update)
And here is the result on GitHub:

Maybe this “first commit” trick is unnecessary. So, if you have a better understanding of the issue, or can explain me why this is stupid, please tell me ! ![]()
Pingback: Commit history reconstruction with Git | Kev's blog
I’m starting to get an idea of the initial commit problem. And according Brandon Dimcheff, it looks like a
--rootoption was added to Git to address this issue.And here is an example I found on Stack Overflow on how to use it:
Pingback: Moving a Git sub-tree to its own repository | Kevin Deldycke
If you need to automate the setting of the initial commit’s date, then add the
inittag just after thegit commitcommand.This will let you get the hash of the first commit dynamically:
$ git commit --allow-empty -m 'Initial commit' $ git tag "init" $ export GIT_TMP_INIT_HASH=`git show-ref init | cut -d ' ' -f 1` $ git filter-branch --env-filter ' if [ $GIT_COMMIT = $GIT_TMP_INIT_HASH ] then export GIT_AUTHOR_DATE="Thu, 01 Jan 1970 00:00:00 +0000" export GIT_COMMITTER_DATE="Thu, 01 Jan 1970 00:00:00 +0000" fi' -- --all $ unset GIT_TMP_INIT_HASHPingback: FTT Migration from Subversion to Git | Kevin Deldycke
Pingback: Pushing Git to Subversion: the case of WordPress plugin repository | Kevin Deldycke