diff --git includes/views/versioncontrol.views.inc includes/views/versioncontrol.views.inc
index f8a678e..b1103c5 100755
--- includes/views/versioncontrol.views.inc
+++ includes/views/versioncontrol.views.inc
@@ -429,10 +429,6 @@ function versioncontrol_views_data() {
       'left_field' => 'repo_id',
       'field' => 'repo_id',
     ),
-    'versioncontrol_source_items' => array(
-      'left_field' => 'item_revision_id',
-      'field' => 'item_revision_id',
-    ),
   );
   $data['versioncontrol_item_revisions']['path'] = array(
     'title' => t("File path"),
@@ -471,14 +467,9 @@ function versioncontrol_views_data() {
       'handler' => 'views_handler_field_numeric',
     ),
   );
-
-  // VersionControl Source Items
-  $data['versioncontrol_source_items']['table']['group'] = t("VersionControl Source Items");
-  // TODO: item_revision_id
-  $data['versioncontrol_source_items']['item_revision_id'] = array();
   // TODO: source_item_revision_id
-  $data['versioncontrol_source_items']['source_item_revision_id'] = array();
-  $data['versioncontrol_source_items']['action'] = array(
+  $data['versioncontrol_item_revisions']['source_item_revision_id'] = array();
+  $data['versioncontrol_item_revisions']['action'] = array(
     'title' => t('Action'),
     'help' => t('The action performed on this item'),
     'field' => array(
@@ -487,10 +478,10 @@ function versioncontrol_views_data() {
     ),
   );
   // TODO: line_changes_recorded
-  $data['versioncontrol_source_items']['line_changes_recorded'] = array();
-  $data['versioncontrol_source_items']['line_changes_added'] = array(
-    'title' => t("Lines Added"),
-    'help' => t("The number of lines added to this item"),
+  $data['versioncontrol_item_revisions']['line_changes_recorded'] = array();
+  $data['versioncontrol_item_revisions']['line_changes_added'] = array(
+    'title' => t('Lines Added'),
+    'help' => t('The number of lines added to this item'),
     'field' => array(
       'handler' => 'views_handler_field_numeric',
       'click sortable' => TRUE,
@@ -499,16 +490,16 @@ function versioncontrol_views_data() {
       'handler' => 'views_handler_sort',
     ),
   );
-  $data['versioncontrol_source_items']['line_changes_removed'] = array(
-    'title' => t("Lines Removed"),
-    'help' => t("The number of lines removed from this item"),
+  $data['versioncontrol_item_revisions']['line_changes_removed'] = array(
+    'title' => t('Lines Removed'),
+    'help' => t('The number of lines removed from this item'),
     'field' => array(
       'handler' => 'views_handler_field_numeric',
       'click sortable' => TRUE,
     ),
     'sort' => array(
       'handler' => 'views_handler_sort',
-    ), 
+    ),
   );
   return $data;
 }
diff --git versioncontrol.install versioncontrol.install
index a99fad6..f22f406 100644
--- versioncontrol.install
+++ versioncontrol.install
@@ -185,21 +185,59 @@ function versioncontrol_schema() {
     'primary key' => array('label_id'),
   );
 
-  $schema['versioncontrol_source_items'] = array(
+  $schema['versioncontrol_item_revisions'] = array(
     'description' =>
-      'This table stores item history, i.e. it relates an item to one or more direct predecessors (= source items). Likewise, a source item can also have multiple successors, for example if it\'s copied to one location and later (or at the same time) moved to another location.',
+      'This table contains all known different versions of a file or directory item. For version control systems using global revisions, only the revisions should be recorded in here when the item was actually changed, i.e. part of a commit operation. (Not every revision needs to have all associated items recorded in here, that would be insane.) Non-versioned items, such as directories in CVS or Git, should not be recorded in this table.',
     'fields' => array(
       'item_revision_id' => array(
         'description' =>
-          'Foreign key for the successor item, referring to {versioncontrol_item_revisions}.item_revision_id. This one is more recent in revision history than the source item.',
+          'Unique identifier for this item revision. The same item in a different revision gets a different item_revision_id. Equivalent to the (also unique) repo_id/path/revision combination in the same row.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'vc_op_id' => array(
+        'description' => 'Foreign key (referring to {versioncontrol_operations}.vc_op_id) for the operation that affected the given item(s).',
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
         'default' => 0,
       ),
+      'repo_id' => array(
+        'description' => 'Foreign key (referring to {versioncontrol_repositories}.repo_id) for the repository that this item is located in.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'path' => array(
+        'description' =>
+          'Path of the item, relative to the repository root. Always starts with a slash, and never ends with one (not even if the item is a directory). Examples: "/" (root directory), "/contributions", "/sandbox/jpetso/evil-plans.txt". The slash is only used for separating the parts of the path, so it is safe to use explode("/", $path).',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'revision' => array(
+        'description' =>
+          '(File-level) revision of the item, such as "1.12.4.3" for CVS. If the version control system supports global revisions, this should contain the same revision as the "revision" property of the associated commit operation. Contrary to {versioncontrol_operations}.revision which may be empty, this column must always contain a revision because every changed item has a revision assigned. (If it lacks a revision, it should not be recorded as operation item in the first place.)',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'type' => array(
+        'description' =>
+          'Specifies whether the item is a file or directory, and whether it exists or is deleted. Deleted items might exist for real, such as in CVS repositories (the "Attic") or they might just be recorded as part of a commit operation where the item was deleted, even though the version control system does not know about this revision. In Version Control API, deleted items only exist for display purposes, backends are expected not to retrieve information about them other than item history. Possible values for the item type are VERSIONCONTROL_ITEM_FILE, VERSIONCONTROL_ITEM_FILE_DELETED, VERSIONCONTROL_ITEM_DIRECTORY and VERSIONCONTROL_ITEM_DIRECTORY_DELETED. Usually though, API users should only use the functions VersioncontrolItem::isFile(), VersioncontrolItem::isDirectory() and VersioncontrolItem::isDeleted() for testing these constants.',
+        'type' => 'int',
+        'size' => 'tiny',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
       'source_item_revision_id' => array(
         'description' =>
-          'Foreign key for the source item - also referring to {versioncontrol_item_revisions}.item_revision_id, but to a different one than the above {versioncontrol_source_items}.item_revision_id. Contains 0 if the action is VERSIONCONTROL_ACTION_ADDED.',
+          'Foreign key for the source item - also referring to {versioncontrol_item_revisions}.item_revision_id, but to a different one than this {versioncontrol_item_revisions}.item_revision_id. Contains 0 if the action is VERSIONCONTROL_ACTION_ADDED.',
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
@@ -244,60 +282,6 @@ function versioncontrol_schema() {
         'default' => 0,
       ),
     ),
-    'primary key' => array('item_revision_id', 'source_item_revision_id'),
-  );
-
-  $schema['versioncontrol_item_revisions'] = array(
-    'description' =>
-      'This table contains all known different versions of a file or directory item. For version control systems using global revisions, only the revisions should be recorded in here when the item was actually changed, i.e. part of a commit operation. (Not every revision needs to have all associated items recorded in here, that would be insane.) Non-versioned items, such as directories in CVS or Git, should not be recorded in this table.',
-    'fields' => array(
-      'item_revision_id' => array(
-        'description' =>
-          'Unique identifier for this item revision. The same item in a different revision gets a different item_revision_id. Equivalent to the (also unique) repo_id/path/revision combination in the same row.',
-        'type' => 'serial',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-      ),
-      'vc_op_id' => array(
-        'description' => 'Foreign key (referring to {versioncontrol_operations}.vc_op_id) for the operation that affected the given item(s).',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'repo_id' => array(
-        'description' => 'Foreign key (referring to {versioncontrol_repositories}.repo_id) for the repository that this item is located in.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'path' => array(
-        'description' =>
-          'Path of the item, relative to the repository root. Always starts with a slash, and never ends with one (not even if the item is a directory). Examples: "/" (root directory), "/contributions", "/sandbox/jpetso/evil-plans.txt". The slash is only used for separating the parts of the path, so it is safe to use explode("/", $path).',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'revision' => array(
-        'description' =>
-          '(File-level) revision of the item, such as "1.12.4.3" for CVS. If the version control system supports global revisions, this should contain the same revision as the "revision" property of the associated commit operation. Contrary to {versioncontrol_operations}.revision which may be empty, this column must always contain a revision because every changed item has a revision assigned. (If it lacks a revision, it should not be recorded as operation item in the first place.)',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'type' => array(
-        'description' =>
-          'Specifies whether the item is a file or directory, and whether it exists or is deleted. Deleted items might exist for real, such as in CVS repositories (the "Attic") or they might just be recorded as part of a commit operation where the item was deleted, even though the version control system does not know about this revision. In Version Control API, deleted items only exist for display purposes, backends are expected not to retrieve information about them other than item history. Possible values for the item type are VERSIONCONTROL_ITEM_FILE, VERSIONCONTROL_ITEM_FILE_DELETED, VERSIONCONTROL_ITEM_DIRECTORY and VERSIONCONTROL_ITEM_DIRECTORY_DELETED. Usually though, API users should only use the functions VersioncontrolItem::isFile(), VersioncontrolItem::isDirectory() and VersioncontrolItem::isDeleted() for testing these constants.',
-        'type' => 'int',
-        'size' => 'tiny',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-    ),
     // Key too long, cannot create an index for this unique key.
     //'unique keys' => array(
     //  'repo_id_path_revision' => array('repo_id', 'path', 'revision'),
@@ -306,6 +290,7 @@ function versioncontrol_schema() {
     'indexes' => array(
       'repo_id_path' => array('repo_id', 'path'),
       'revision' => array('revision'),
+      'source_item_revision_id' => array('source_item_revision_id'),
     ),
     'primary key' => array('item_revision_id'),
   );
@@ -753,3 +738,77 @@ function versioncontrol_update_6305() {
   db_add_field($ret, 'versioncontrol_repositories', 'locked', $locked);
   return $ret;
 }
+
+/**
+ * Merge {versioncontrol_item_revisions} and {versioncontrol_source_items} tables.
+ *
+ * This is mainly to avoid unnecessary complexity.
+ * See #975864 for details.
+ */
+function versioncontrol_update_6306() {
+  $ret = array();
+  $fields = array(
+    'source_item_revision_id' => array(
+      'description' =>
+        'Foreign key for the source item - also referring to {versioncontrol_item_revisions}.item_revision_id, but to a different one than this {versioncontrol_item_revisions}.item_revision_id. Contains 0 if the action is VERSIONCONTROL_ACTION_ADDED.',
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'not null' => TRUE,
+      'default' => 0,
+    ),
+    'action' => array(
+      'description' =>
+        'Action that was performed while transforming the source item into the successor item. Can be one of the VERSIONCONTROL_ACTION_* values listed at the top of versioncontrol.module.
+
+        The VERSIONCONTROL_ACTION_DELETED and VERSIONCONTROL_ACTION_REPLACED actions are considered to be the end in the history of an item, no further successors than the current one should be retrieved. (For VERSIONCONTROL_ACTION_DELETED, item_revision_id links to a deleted item. For VERSIONCONTROL_ACTION_REPLACED, item_revision_id links to a different item at the same path that replaced the item specified by source_item_revision_id.
+
+        Likewise, the VERSIONCONTROL_ACTION_ADDED action is considered the beginning, with source_item_revision_id being 0 in that case.',
+      'type' => 'int',
+      'size' => 'tiny',
+      'unsigned' => TRUE,
+      'not null' => TRUE,
+      'default' => 0,
+    ),
+    'line_changes_recorded' => array(
+      'description' =>
+        'Specifies whether line-change information is available (1 as value) or not (0 as value). Naturally, this should only apply to file items, not to directory items. VERSIONCONTROL_ACTION_DELETED and VERSIONCONTROL_ACTION_REPLACED actions are also not supposed to contain line-change information.',
+      'type' => 'int',
+      'size' => 'tiny',
+      'unsigned' => TRUE,
+      'not null' => TRUE,
+      'default' => 0,
+    ),
+    'line_changes_added' => array(
+      'description' =>
+        'If the line_changes_recorded column is 1 then this column contains the amount of lines that was added to the file compared to its source revision. (Equivalent to the "plus" lines in a unified diff.)',
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'not null' => TRUE,
+      'default' => 0,
+    ),
+    'line_changes_removed' => array(
+      'description' =>
+        'If the line_changes_recorded column is 1 then this column contains the amount of lines that was removed from the file compared to its source revision. (Equivalent to the "minus" lines in a unified diff.)',
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'not null' => TRUE,
+      'default' => 0,
+    ),
+  );
+
+  foreach  ($fields as $field_name => $data_spec) {
+    db_add_field($ret, 'versioncontrol_item_revisions', $field_name, $data_spec);
+  }
+
+  db_add_index($ret, 'versioncontrol_item_revisions', 'source_item_revision_id', array('source_item_revision_id'));
+
+  $result = db_query("SELECT item_revision_id, source_item_revision_id, action, line_changes_recorded, line_changes_added, line_changes_removed FROM {versioncontrol_source_items}");
+
+  while ($row = db_fetch_object($result)) {
+    db_query('UPDATE {versioncontrol_item_revisions} SET source_item_revision_id = %d, action = %d, line_changes_recorded = %d, line_changes_added = %d, line_changes_removed WHERE item_revision_id = %d', $row->source_item_revision_id, $row->action, $row->line_changes_recorded, $row->line_changes_added, $row->line_changes_removed, $row->item_revision_id);
+  }
+
+  db_drop_table($ret, 'versioncontrol_source_items');
+
+  return $ret;
+}
