diff --git .changelog.php .changelog.php
index e69de29..315f202 100644
--- .changelog.php
+++ .changelog.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Tool to generate the BP Legacy's changelog
+ */
+
+// Major releases
+$releases = array(
+	"1.7.0" => 6899,
+	"1.8.0" => 7280,
+	"1.9.0" => 7683,
+	"2.0.0" => 8278,
+	"2.1.0" => 9031,
+	"2.2.0" => 9440,
+	"2.3.0" => 9911,
+);
+
+// Building the changelog
+$changelog = new stdClass;
+$changelog->author = 'The BuddyPress Contributors';
+$changelog->vesion = '2.4.0';
+$changelog->templates = array();
+
+// To strip legacy path from templates
+$bp_legacy_path = 'src/bp-templates/bp-legacy/buddypress/';
+$output         = 'src/bp-templates/bp-legacy/changelog.json';
+$changes        = array();
+
+$git_commits = shell_exec( 'git log --name-only --pretty=format:"||%s|%b|" src/bp-templates/bp-legacy/buddypress' );
+
+$commits = explode( '||', $git_commits );
+
+if ( ! is_array( $commits ) ) {
+	fwrite( STDOUT, "Error: could not generate the changelog, are you using git?\n" );
+	exit( 2 );
+}
+
+// Remove the old file
+if ( file_exists( $output ) ) {
+	@unlink( $output );
+}
+
+foreach( $commits as $commit ) {
+	$parts = explode( '|', $commit );
+	$log = $parts[0];
+
+	preg_match( '/trunk@(\d*)/', $parts[1], $match );
+
+	if ( ! $match[1] ) {
+		continue;
+	}
+
+	$revision = $match[1];
+
+	// Defaults to release if nothing found in releases
+	// It has been introduced in current release
+	$version  = $changelog->vesion;
+
+	foreach ( $releases as $key => $changeset ) {
+		if ( $changeset > $revision ) {
+			$version = $key;
+			break;
+		}
+	}
+
+	$files = explode( "\n", trim( $parts[2], "\n" ) );
+
+	foreach ( $files as $file ) {
+		$changes[ str_replace( $bp_legacy_path, '', $file ) ][] = (object) array(
+			'version'  => $version,
+			'revision' => $revision,
+			'log'      => $log,
+		);
+	}
+}
+
+if ( empty( $changes ) ) {
+	fwrite( STDOUT, "Error: could not generate the changelog.\n" );
+	exit( 2 );
+}
+
+ksort( $changes );
+
+foreach ( $changes as $template => $logs )  {
+	$entry = new stdClass;
+
+	$entry->template = $template;
+
+	// Get version when the template was last edited
+	$edited = reset( $logs );
+	$entry->edited = $edited->version;
+
+	// Attach logs
+	$entry->changes = $logs;
+
+	$changelog->templates[] = $entry;
+}
+
+$created = file_put_contents( $output, json_encode( $changelog, JSON_PRETTY_PRINT ) );
+
+if ( ! $created ) {
+	fwrite( STDOUT, "Error: could not generate the changelog.\n" );
+	exit( 2 );
+} else {
+	fwrite( STDOUT, "Success: Changelog generated.\n" );
+	exit( 0 );
+}
diff --git Gruntfile.js Gruntfile.js
index 0445052..469f4ba 100644
--- Gruntfile.js
+++ Gruntfile.js
@@ -222,6 +222,9 @@ module.exports = function( grunt ) {
 				command: 'svn export --force https://github.com/buddypress/BP-Default.git/trunk bp-themes/bp-default',
 				cwd: BUILD_DIR,
 				stdout: false
+			},
+			templates_changelog: {
+				command: 'php .changelog.php'
 			}
 		},
 		jsvalidate:{
@@ -278,4 +281,7 @@ module.exports = function( grunt ) {
 
 	// Default task.
 	grunt.registerTask( 'default', ['src'] );
+
+	// Patch task.
+	grunt.registerTask( 'templates_changelog', 'exec:templates_changelog' );
 };
