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
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 <firstname.lastname@example.org> 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 <email@example.com> Date: Thu Jan 1 00:00:00 1970 +0000 Initial commit
For convenience, we’ll now attach a tag to this initial commit. Let’s call it
$ 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 firstname.lastname@example.org: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 email@example.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! :)