diff --git versioncontrol.module versioncontrol.module
index 8d90e67..e380c98 100644
--- versioncontrol.module
+++ versioncontrol.module
@@ -1009,3 +1009,84 @@ function versioncontrol_auth_handlers_get_names() {
   asort($names);
   return $names;
 }
+
+/**
+ * Implementation of hook_token_list().
+ */
+function versioncontrol_token_list($type = 'all') {
+  $tokens = array();
+
+  if ($type == 'versioncontrol_repository' || $type == 'all') {
+    $repo_name_mapping = array();
+    foreach (versioncontrol_repository_load_multiple(FALSE) as $repo_id => $repository) {
+      $repo_name_mapping[] = t('!id for @repo-name', array(
+        '!id' => $repo_id,
+        '@repo-name' => $repository['name'],
+      ));
+    }
+
+    $vcs_mapping = array();
+    foreach (versioncontrol_get_backends() as $vcs => $backend) {
+      $vcs_mapping[$vcs] = check_plain($backend->name);
+    }
+
+    $tokens['versioncontrol repository'] = array(
+      'id' => t('Repository identifier (known ids: !repo-mapping)', array(
+        '!repo-mapping' => implode(', ', $repo_name_mapping),
+      )),
+      'name' => t('Repository name, as listed in the above mapping'),
+      'vcs' => t('VCS backend identifier (known backend ids: !backends)', array(
+        '!backends' => implode(', ', array_keys($vcs_mapping)),
+      )),
+      'vcs-name' => t('VCS backend name (known backend names: !backends)', array(
+        '!backends' => implode(', ', $vcs_mapping),
+      )),
+      'root' => t('Repository root'),
+    );
+  }
+  if ($type == 'versioncontrol_operation' || $type == 'all') {
+    $tokens['versioncontrol operation'] = array(
+      'id' => t('Operation identifier (vc_op_id)'),
+      'date' => t('Commit date'),
+      'revision' => t('Global revision identifier'),
+      'vcs-user' => t('VCS specific account name'),
+      'vcs-user-raw' => t('VCS specific account name. WARNING - raw unfiltered message, not safe for HTML (fine for emails, though).'),
+      'message' => t('Commit/branch/tag message (might be empty for branches and tags)'),
+      'message-raw' => t('Commit/branch/tag message like above. WARNING - raw unfiltered message, not safe for HTML (fine for emails, though).'),
+    );
+  }
+  return $tokens;
+}
+
+/**
+ * Implementation of hook_token_values().
+ */
+function versioncontrol_token_values($type, $object = NULL) {
+  switch ($type) {
+    case 'versioncontrol_repository':
+      $repository = $object;
+      $values = array(
+        'id' => $repository['repo_id'],
+        'name' => check_plain($repository->name),
+        'vcs' => check_plain($repository->vcs),
+        'vcs-name' => check_plain($repository->backend->name),
+        'root' => check_plain($repository->root),
+      );
+      break;
+    case 'versioncontrol_operation':
+      $operation = $object;
+      $values = array(
+        'id' => $operation->vc_op_id,
+        'revision' => $operation->revision,
+        'vcs-user' => check_plain($operation->username),
+        'vcs-user-raw' => $operation->username,
+        'message' => check_plain($operation->message),
+        'message-raw' => $operation->message,
+        'date' => format_date($operation->date,
+          'short', '', variable_get('date_default_timezone', 0)
+        ),
+      );
+      break;
+  }
+  return $values;
+}
\ No newline at end of file
