diff --git a/modules/simpletest/tests/upgrade/drupal-6.upload.database.php b/modules/simpletest/tests/upgrade/drupal-6.upload.database.php
index 46ebe2c..3617c16 100644
--- a/modules/simpletest/tests/upgrade/drupal-6.upload.database.php
+++ b/modules/simpletest/tests/upgrade/drupal-6.upload.database.php
@@ -127,6 +127,38 @@ db_insert('files')->fields(array(
   'status' => '1',
   'timestamp' => '1285708958',
 ))
+// On some Drupal 6 sites, more than one file can have the same filepath.
+// @see https://www.drupal.org/node/1260938.
+->values(array(
+  'fid' => '12',
+  'uid' => '1',
+  'filename' => 'duplicate-name.png',
+  'filepath' => 'sites/default/files/duplicate-name.png',
+  'filemime' => 'image/png',
+  'filesize' => '314',
+  'status' => '1',
+  'timestamp' => '1285708958',
+))
+->values(array(
+  'fid' => '13',
+  'uid' => '1',
+  'filename' => 'duplicate-name.png',
+  'filepath' => 'sites/default/files/duplicate-name.png',
+  'filemime' => 'image/png',
+  'filesize' => '315',
+  'status' => '1',
+  'timestamp' => '1285708958',
+))
+->values(array(
+  'fid' => '14',
+  'uid' => '1',
+  'filename' => 'duplicate-name.png',
+  'filepath' => 'sites/default/files/duplicate-name.png',
+  'filemime' => 'image/png',
+  'filesize' => '316',
+  'status' => '1',
+  'timestamp' => '1285708958',
+))
 ->execute();
 
 db_insert('node')->fields(array(
@@ -197,6 +229,23 @@ db_insert('node')->fields(array(
   'tnid' => '0',
   'translate' => '0',
 ))
+->values(array(
+  'nid' => '41',
+  'vid' => '55',
+  'type' => 'page',
+  'language' => '',
+  'title' => 'node title 41 revision 55',
+  'uid' => '1',
+  'status' => '1',
+  'created' => '1285709012',
+  'changed' => '1285709012',
+  'comment' => '0',
+  'promote' => '0',
+  'moderate' => '0',
+  'sticky' => '0',
+  'tnid' => '0',
+  'translate' => '0',
+))
  ->execute();
 
 db_insert('node_revisions')->fields(array(
@@ -254,6 +303,28 @@ db_insert('node_revisions')->fields(array(
   'timestamp' => '1285709012',
   'format' => '1',
 ))
+->values(array(
+  'nid' => '41',
+  'vid' => '54',
+  'uid' => '1',
+  'title' => 'node title 41 revision 54',
+  'body' => "Attachments:\r\nduplicate-name.png",
+  'teaser' => "Attachments:\r\nduplicate-name.png",
+  'log' => '',
+  'timestamp' => '1285709012',
+  'format' => '1',
+))
+->values(array(
+  'nid' => '41',
+  'vid' => '55',
+  'uid' => '1',
+  'title' => 'node title 41 revision 55',
+  'body' => "Attachments:\r\nduplicate-name.png\r\nduplicate-name.png",
+  'teaser' => "Attachments:\r\nduplicate-name.png\r\nduplicate-name.png",
+  'log' => '',
+  'timestamp' => '1285709012',
+  'format' => '1',
+))
  ->execute();
 
 db_create_table('upload', array(
@@ -415,6 +486,30 @@ db_insert('upload')->fields(array(
   'list' => '1',
   'weight' => '0',
 ))
+->values(array(
+  'fid' => '12',
+  'nid' => '41',
+  'vid' => '54',
+  'description' => 'duplicate-name.png',
+  'list' => '1',
+  'weight' => '0',
+))
+->values(array(
+  'fid' => '13',
+  'nid' => '41',
+  'vid' => '55',
+  'description' => 'first description',
+  'list' => '0',
+  'weight' => '0',
+))
+->values(array(
+  'fid' => '14',
+  'nid' => '41',
+  'vid' => '55',
+  'description' => 'second description',
+  'list' => '1',
+  'weight' => '0',
+))
 ->execute();
 
 // Add series of entries for invalid node vids to the {upload} table.
@@ -431,7 +526,7 @@ for ($i = 30; $i < 250; $i += 2) {
   ->values(array(
     'fid' => $i,
     'nid' => '40',
-    'vid' => 24 + $i,
+    'vid' => 26 + $i,
     'description' => 'crazy-basename.png',
     'list' => '1',
     'weight' => '0',
@@ -440,7 +535,7 @@ for ($i = 30; $i < 250; $i += 2) {
   ->values(array(
     'fid' => 2,
     'nid' => '40',
-    'vid' => 24 + $i + 1,
+    'vid' => 26 + $i + 1,
     'description' => 'crazy-basename.png',
     'list' => '1',
     'weight' => '0',
diff --git a/modules/simpletest/tests/upgrade/upgrade.upload.test b/modules/simpletest/tests/upgrade/upgrade.upload.test
index be352bd..dfa94a0 100644
--- a/modules/simpletest/tests/upgrade/upgrade.upload.test
+++ b/modules/simpletest/tests/upgrade/upgrade.upload.test
@@ -64,12 +64,35 @@ class UploadUpgradePathTestCase extends UpgradePathTestCase {
       }
       $this->assertIdentical($filenames, $recorded_filenames, 'The uploaded files are present in the same order after the upgrade.');
     }
+
     // Test for the file with repeating basename to only have the streaming
     // path replaced.
     $node = node_load(40, 53);
     $repeated_basename_file = $node->upload[LANGUAGE_NONE][4];
     $this->assertEqual($repeated_basename_file['uri'], 'private://drupal-6/file/directory/path/crazy-basename.png', "The file with the repeated basename path only had the stream portion replaced");
 
+    // Ensure that filepaths are deduplicated.
+    $node0 = node_load(41, 54);
+    $node1 = node_load(41, 55);
+    // Ensure that both revisions point to the same file ID.
+    $items0 = field_get_items('node', $node0, 'upload');
+    $this->assertEqual(count($items0), 1);
+    $items1 = field_get_items('node', $node1, 'upload');
+    $this->assertEqual(count($items1), 2);
+    $this->assertEqual($items0[0]['fid'], $items1[0]['fid']);
+    $this->assertEqual($items0[0]['fid'], $items1[1]['fid']);
+    // The revision with more than one reference to the same file should retain
+    // the original settings for each reference.
+    $this->assertEqual($items1[0]['description'], 'first description');
+    $this->assertEqual($items1[0]['display'], 0);
+    $this->assertEqual($items1[1]['description'], 'second description');
+    $this->assertEqual($items1[1]['display'], 1);
+    // Ensure that the latest version of the files are used.
+    $this->assertEqual($items1[0]['filesize'], 316);
+    $this->assertEqual($items1[1]['filesize'], 316);
+    // No duplicate files should remain on the Drupal 7 site.
+    $this->assertEqual(0, db_query("SELECT COUNT(*) FROM {file_managed} GROUP BY uri HAVING COUNT(fid) > 1")->fetchField());
+
     // Make sure the file settings were properly migrated.
     $d6_file_directory_temp = '/drupal-6/file/directory/temp';
     $d6_file_directory_path = '/drupal-6/file/directory/path';
diff --git a/modules/system/system.install b/modules/system/system.install
index 64c989a..e5cc5d2 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -2803,6 +2803,17 @@ function system_update_7061(&$sandbox) {
       ->from($query)
       ->execute();
 
+    // Retrieve a list of duplicate files with the same filepath. Only the
+    // first of these will be moved to the new {file_managed} table (and all
+    // references will be updated to point to it), since duplicate file URIs
+    // are not allowed in Drupal 7.
+    // Since the Drupal 6 to 7 upgrade path leaves the {files} table behind
+    // after it's done, custom or contributed modules which need to migrate
+    // file references of their own can use a similar query to determine the
+    // file IDs that duplicate filepaths were mapped to.
+    // We use MAX(fid) to retrieve the latest filesize and timestamp.
+    $sandbox['duplicate_filepath_fids_to_use'] = db_query("SELECT filepath, MAX(fid) FROM {files} GROUP BY filepath HAVING COUNT(*) > 1")->fetchAllKeyed();
+
     // Initialize batch update information.
     $sandbox['progress'] = 0;
     $sandbox['last_vid_processed'] = -1;
@@ -2832,6 +2843,16 @@ function system_update_7061(&$sandbox) {
         continue;
       }
 
+      // If this file has a duplicate filepath, replace it with the first file
+      // that has the same filepath.
+      if (isset($sandbox['duplicate_filepath_fids_to_use'][$file['filepath']]) && $record->fid != $sandbox['duplicate_filepath_fids_to_use'][$file['filepath']]) {
+        $file = db_select('files', 'f')
+          ->fields('f', array('fid', 'uid', 'filename', 'filepath', 'filemime', 'filesize', 'status', 'timestamp'))
+          ->condition('f.fid', $sandbox['duplicate_filepath_fids_to_use'][$file['filepath']])
+          ->execute()
+          ->fetchAssoc();
+      }
+
       // Add in the file information from the upload table.
       $file['description'] = $record->description;
       $file['display'] = $record->list;
