CREATE CONSTRAINT ON (c:Commit) ASSERT c.sha1 IS UNIQUE; CREATE INDEX ON :Commit(hash); CREATE INDEX ON :Commit(date); CREATE CONSTRAINT ON (u:User) ASSERT u.email IS UNIQUE; CREATE INDEX ON :User(name); CREATE CONSTRAINT ON (y:Year) ASSERT y.year IS UNIQUE; USING PERIODIC COMMIT 1000 // change the path to the correct one, for windows like this // LOAD CSV WITH headers FROM "file://c:/path/to/cloned/repo/git_log.csv" as line LOAD CSV WITH headers FROM "file:///Users//path/to/cloned/repo/git_log.csv" as line CREATE (c:Commit {sha1: line.sha1, hash:line.hash, subject:line.subject, date_time:line.date_time, date:substring(line.date_time,0,10), timestamp:toInt(line.timestamp), parents:split(line.parents," "), refs:case when size(line.refs) > 0 then split(substring(line.refs,2,length(line.refs)-3),", ") else null end}) MERGE (u:User:Author {email:line.author_email}) ON CREATE SET u.name = line.author_name CREATE (u)-[:AUTHORED]->(c) MERGE (y:Year {year:substring(line.date_time,0,4)}) MERGE (m:Month {month:substring(line.date_time,5,2)})-[:IN_YEAR]->(y) MERGE (d:Day {date:substring(line.date_time,0,10), day:substring(line.date_time,8,2)})-[:IN_MONTH]->(m) CREATE (c)-[:ON_DAY]->(d) WITH c,line WHERE line.parents <> "" FOREACH (parent_sha1 in split(line.parents," ") | MERGE (parent:Commit {sha1 : parent_sha1}) CREATE (c)-[:PARENT]->(parent));