Repository: 11ty/eleventy (js)

Issue:
Use first commit as a `date` front matter option
Like a "last commit" is [now available](https://github.com/11ty/eleventy/issues/142#ref-commit-8f35e55) now supported to use last git commit as `page.date` variable, I would need a "first commit" option, for when the file was first commited (added) to the repository.

Here's how I currently get it in a Bash script:

```bash
fileDate=$(git log --all --diff-filter=A --pretty=%x0a%ci --name-only | awk '
/^$/        { dateline=!dateline; next }
dateline    { date=$0; next }
!seen[$0]++ { print date,$0 }
' | grep "$fileBasename" | head -1)
```

Found it in https://stackoverflow.com/a/32894198/717195


Pull request:
#2224 git created option for date
This change allows to use "git created" as a magic string to use the first appearance in git as the date of a template.

This uses gits feature to also track the file across renames.

If a file isn't yet tracked, it uses the current date.

It uses "git created" instead of "git first added", to keep closer to the already existing "created" option.

fixes #2224

Patch:
diff --git a/src/Template.js b/src/Template.js
index ff9425bd..b6f5f68e 100755
--- a/src/Template.js
+++ b/src/Template.js
@@ -13,6 +13,7 @@ const { TemplatePath, isPlainObject } = require("@11ty/eleventy-utils");
 
 const ConsoleLogger = require("./Util/ConsoleLogger");
 const getDateFromGitLastUpdated = require("./Util/DateGitLastUpdated");
+const getDateFromGitFirstAdded = require("./Util/DateGitFirstAdded");
 
 const TemplateData = require("./TemplateData");
 const TemplateContent = require("./TemplateContent");
@@ -949,6 +950,15 @@ class Template extends TemplateContent {
       if (data.date.toLowerCase() === "last modified") {
         return this._getDateInstance("ctimeMs");
       }
+      if (data.date.toLowerCase() === "git created") {
+        let d = getDateFromGitFirstAdded(this.inputPath);
+        if (d) {
+          return d;
+        }
+
+        // return now if this file is not yet available in `git`
+        return new Date();
+      }
       if (data.date.toLowerCase() === "created") {
         return this._getDateInstance("birthtimeMs");
       }
diff --git a/src/Util/DateGitFirstAdded.js b/src/Util/DateGitFirstAdded.js
new file mode 100644
index 00000000..ea944750
--- /dev/null
+++ b/src/Util/DateGitFirstAdded.js
@@ -0,0 +1,24 @@
+const spawn = require("cross-spawn");
+
+function getGitFirstAddedTimeStamp(filePath) {
+  return (
+    parseInt(
+      spawn
+        .sync(
+          "git",
+          // Formats https://www.git-scm.com/docs/git-log#_pretty_formats
+          // %at author date, UNIX timestamp
+          ["log", "--diff-filter=A", "--follow", "-1", "--format=%at", filePath]
+        )
+        .stdout.toString("utf-8")
+    ) * 1000
+  );
+}
+
+// return a Date
+module.exports = function (inputPath) {
+  let timestamp = getGitFirstAddedTimeStamp(inputPath);
+  if (timestamp) {
+    return new Date(timestamp);
+  }
+};


Test patch:
diff --git a/test/EleventyTest.js b/test/EleventyTest.js
index e5ac27c8..2360a590 100644
--- a/test/EleventyTest.js
+++ b/test/EleventyTest.js
@@ -2,6 +2,7 @@ const test = require("ava");
 const Eleventy = require("../src/Eleventy");
 const EleventyWatchTargets = require("../src/EleventyWatchTargets");
 const TemplateConfig = require("../src/TemplateConfig");
+const DateGitFirstAdded = require("../src/Util/DateGitFirstAdded.js");
 const DateGitLastUpdated = require("../src/Util/DateGitLastUpdated");
 const normalizeNewLines = require("./Util/normalizeNewLines");
 
@@ -548,3 +549,14 @@ ${JSON.stringify(arr)}`);
   t.is(normalizeNewLines(content[0]), str);
   t.is(normalizeNewLines(content[1]), str);
 });
+
+test("#2224: date 'git created' populates page.date", async (t) => {
+  let elev = new Eleventy("./test/stubs-2224/", "./test/stubs-2224/_site");
+
+  let results = await elev.toJSON();
+  let [result] = results;
+
+  // This doesn’t test the validity of the function, only that it populates page.date.
+  let comparisonDate = DateGitFirstAdded("./test/stubs-2224/index.njk");
+  t.is(result.content.trim(), "" + comparisonDate.getTime());
+});
diff --git a/test/stubs-2224/index.njk b/test/stubs-2224/index.njk
new file mode 100644
index 00000000..1c990071
--- /dev/null
+++ b/test/stubs-2224/index.njk
@@ -0,0 +1,4 @@
+---
+date: git created
+---
+{{ page.date.getTime() }}
\ No newline at end of file