Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -2182,9 +2182,11 @@
     'PhragmentFragmentQuery' => 'applications/phragment/query/PhragmentFragmentQuery.php',
     'PhragmentFragmentVersion' => 'applications/phragment/storage/PhragmentFragmentVersion.php',
     'PhragmentFragmentVersionQuery' => 'applications/phragment/query/PhragmentFragmentVersionQuery.php',
+    'PhragmentHistoryController' => 'applications/phragment/controller/PhragmentHistoryController.php',
     'PhragmentPHIDTypeFragment' => 'applications/phragment/phid/PhragmentPHIDTypeFragment.php',
     'PhragmentPHIDTypeFragmentVersion' => 'applications/phragment/phid/PhragmentPHIDTypeFragmentVersion.php',
     'PhragmentPatchUtil' => 'applications/phragment/util/PhragmentPatchUtil.php',
+    'PhragmentUpdateController' => 'applications/phragment/controller/PhragmentUpdateController.php',
     'PhrequentController' => 'applications/phrequent/controller/PhrequentController.php',
     'PhrequentDAO' => 'applications/phrequent/storage/PhrequentDAO.php',
     'PhrequentListController' => 'applications/phrequent/controller/PhrequentListController.php',
@@ -4778,9 +4780,11 @@
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhragmentFragmentVersionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+    'PhragmentHistoryController' => 'PhragmentController',
     'PhragmentPHIDTypeFragment' => 'PhabricatorPHIDType',
     'PhragmentPHIDTypeFragmentVersion' => 'PhabricatorPHIDType',
     'PhragmentPatchUtil' => 'Phobject',
+    'PhragmentUpdateController' => 'PhragmentController',
     'PhrequentController' => 'PhabricatorController',
     'PhrequentDAO' => 'PhabricatorLiskDAO',
     'PhrequentListController' =>
Index: src/applications/phragment/application/PhabricatorApplicationPhragment.php
===================================================================
--- src/applications/phragment/application/PhabricatorApplicationPhragment.php
+++ src/applications/phragment/application/PhabricatorApplicationPhragment.php
@@ -36,6 +36,8 @@
         '' => 'PhragmentBrowseController',
         'browse/(?P<dblob>.*)' => 'PhragmentBrowseController',
         'create/(?P<dblob>.*)' => 'PhragmentCreateController',
+        'update/(?P<dblob>.*)' => 'PhragmentUpdateController',
+        'history/(?P<dblob>.*)' => 'PhragmentHistoryController',
       ),
     );
   }
Index: src/applications/phragment/controller/PhragmentBrowseController.php
===================================================================
--- src/applications/phragment/controller/PhragmentBrowseController.php
+++ src/applications/phragment/controller/PhragmentBrowseController.php
@@ -30,7 +30,7 @@
         ->setHref($this->getApplicationURI('/create/'.$path))
         ->setIcon('create'));
 
-    $current_box = $this->createCurrentFragmentView($current);
+    $current_box = $this->createCurrentFragmentView($current, false);
 
     $list = id(new PHUIObjectItemListView())
       ->setUser($viewer);
@@ -74,35 +74,8 @@
         $current_box,
         $list),
       array(
-        'title' => pht('Browse Phragments'),
+        'title' => pht('Browse Fragments'),
         'device' => true));
   }
 
-  private function createCurrentFragmentView($fragment) {
-    if ($fragment === null) {
-      return null;
-    }
-
-    $viewer = $this->getRequest()->getUser();
-
-    $header = id(new PHUIHeaderView())
-      ->setHeader($fragment->getName())
-      ->setPolicyObject($fragment)
-      ->setUser($viewer);
-    $properties = new PHUIPropertyListView();
-
-    $phids = array();
-    $phids[] = $fragment->getLatestVersionPHID();
-
-    $this->loadHandles($phids);
-
-    $properties->addProperty(
-      pht('Latest Version'),
-      $this->renderHandlesForPHIDs(array($fragment->getLatestVersionPHID())));
-
-    return id(new PHUIObjectBoxView())
-      ->setHeader($header)
-      ->addPropertyList($properties);
-  }
-
 }
Index: src/applications/phragment/controller/PhragmentController.php
===================================================================
--- src/applications/phragment/controller/PhragmentController.php
+++ src/applications/phragment/controller/PhragmentController.php
@@ -20,6 +20,7 @@
     $fragments = array();
     $results = id(new PhragmentFragmentQuery())
       ->setViewer($this->getRequest()->getUser())
+      ->needLatestVersion(true)
       ->withPaths($combinations)
       ->execute();
     foreach ($combinations as $combination) {
@@ -53,4 +54,74 @@
     return $crumbs;
   }
 
+  protected function createCurrentFragmentView($fragment, $is_history_view) {
+    if ($fragment === null) {
+      return null;
+    }
+
+    $viewer = $this->getRequest()->getUser();
+
+    $phids = array();
+    $phids[] = $fragment->getLatestVersionPHID();
+
+    $this->loadHandles($phids);
+
+    $file = id(new PhabricatorFileQuery())
+      ->setViewer($viewer)
+      ->withPHIDs(array($fragment->getLatestVersion()->getFilePHID()))
+      ->executeOne();
+    $file_uri = null;
+    if ($file !== null) {
+      $file_uri = $file->getBestURI();
+    }
+
+    $header = id(new PHUIHeaderView())
+      ->setHeader($fragment->getName())
+      ->setPolicyObject($fragment)
+      ->setUser($viewer);
+
+    $actions = id(new PhabricatorActionListView())
+      ->setUser($viewer)
+      ->setObject($fragment)
+      ->setObjectURI($fragment->getURI());
+    $actions->addAction(
+      id(new PhabricatorActionView())
+        ->setName(pht('Download Fragment'))
+        ->setHref($file_uri)
+        ->setDisabled($file === null)
+        ->setIcon('download'));
+    $actions->addAction(
+      id(new PhabricatorActionView())
+        ->setName(pht('Update Fragment'))
+        ->setHref($this->getApplicationURI("update/".$fragment->getPath()))
+        ->setDisabled(false) // TODO: Policy
+        ->setIcon('edit'));
+    if ($is_history_view) {
+      $actions->addAction(
+        id(new PhabricatorActionView())
+          ->setName(pht('View Child Fragments'))
+          ->setHref($this->getApplicationURI("browse/".$fragment->getPath()))
+          ->setIcon('browse'));
+    } else {
+      $actions->addAction(
+        id(new PhabricatorActionView())
+          ->setName(pht('View History'))
+          ->setHref($this->getApplicationURI("history/".$fragment->getPath()))
+          ->setIcon('history'));
+    }
+
+    $properties = id(new PHUIPropertyListView())
+      ->setUser($viewer)
+      ->setObject($fragment)
+      ->setActionList($actions);
+
+    $properties->addProperty(
+      pht('Latest Version'),
+      $this->renderHandlesForPHIDs(array($fragment->getLatestVersionPHID())));
+
+    return id(new PHUIObjectBoxView())
+      ->setHeader($header)
+      ->addPropertyList($properties);
+  }
+
 }
Index: src/applications/phragment/controller/PhragmentCreateController.php
===================================================================
--- src/applications/phragment/controller/PhragmentCreateController.php
+++ src/applications/phragment/controller/PhragmentCreateController.php
@@ -134,7 +134,7 @@
         $crumbs,
         $box),
       array(
-        'title' => pht('Create Phragment'),
+        'title' => pht('Create Fragment'),
         'device' => true));
   }
 
Index: src/applications/phragment/controller/PhragmentHistoryController.php
===================================================================
--- /dev/null
+++ src/applications/phragment/controller/PhragmentHistoryController.php
@@ -0,0 +1,77 @@
+<?php
+
+final class PhragmentHistoryController extends PhragmentController {
+
+  private $dblob;
+
+  public function willProcessRequest(array $data) {
+    $this->dblob = idx($data, "dblob", "");
+  }
+
+  public function processRequest() {
+    $request = $this->getRequest();
+    $viewer = $request->getUser();
+
+    $parents = $this->loadParentFragments($this->dblob);
+    if ($parents === null) {
+      return new Aphront404Response();
+    }
+    $current = idx($parents, count($parents) - 1, null);
+
+    $path = $current->getPath();
+
+    $crumbs = $this->buildApplicationCrumbsWithPath($parents);
+    $crumbs->addAction(
+      id(new PHUIListItemView())
+        ->setName(pht('Create Fragment'))
+        ->setHref($this->getApplicationURI('/create/'.$path))
+        ->setIcon('create'));
+
+    $current_box = $this->createCurrentFragmentView($current, true);
+
+    $versions = id(new PhragmentFragmentVersionQuery())
+      ->setViewer($viewer)
+      ->withFragmentPHIDs(array($current->getPHID()))
+      ->execute();
+
+    $list = id(new PHUIObjectItemListView())
+      ->setUser($viewer);
+
+    $file_phids = mpull($versions, 'getFilePHID');
+    $files = id(new PhabricatorFileQuery())
+      ->setViewer($viewer)
+      ->withPHIDs($file_phids)
+      ->execute();
+    $files = mpull($files, null, 'getPHID');
+
+    foreach ($versions as $version) {
+      $item = id(new PHUIObjectItemView());
+      $item->setHeader('Version '.$version->getSequence());
+      $item->addAttribute(phabricator_datetime(
+        $version->getDateCreated(),
+        $viewer));
+
+      $disabled = !isset($files[$version->getFilePHID()]);
+      $action = id(new PHUIListItemView())
+        ->setIcon('download')
+        ->setDisabled($disabled)
+        ->setRenderNameAsTooltip(true)
+        ->setName(pht("Download"));
+      if (!$disabled) {
+        $action->setHref($files[$version->getFilePHID()]->getBestURI());
+      }
+      $item->addAction($action);
+      $list->addItem($item);
+    }
+
+    return $this->buildApplicationPage(
+      array(
+        $crumbs,
+        $current_box,
+        $list),
+      array(
+        'title' => pht('Fragment History'),
+        'device' => true));
+  }
+
+}
Index: src/applications/phragment/controller/PhragmentUpdateController.php
===================================================================
--- /dev/null
+++ src/applications/phragment/controller/PhragmentUpdateController.php
@@ -0,0 +1,91 @@
+<?php
+
+final class PhragmentUpdateController extends PhragmentController {
+
+  private $dblob;
+
+  public function willProcessRequest(array $data) {
+    $this->dblob = idx($data, "dblob", "");
+  }
+
+  public function processRequest() {
+    $request = $this->getRequest();
+    $viewer = $request->getUser();
+
+    $parents = $this->loadParentFragments($this->dblob);
+    if ($parents === null) {
+      return new Aphront404Response();
+    }
+    $fragment = idx($parents, count($parents) - 1, null);
+
+    $error_view = null;
+
+    if ($request->isFormPost()) {
+      $errors = array();
+
+      $v_fileid = $request->getInt('fileID');
+
+      $file = id(new PhabricatorFile())->load($v_fileid);
+      if ($file === null) {
+        $errors[] = pht('The specified file doesn\'t exist.');
+      }
+
+      if (!count($errors)) {
+        $existing = id(new PhragmentFragmentVersionQuery())
+          ->setViewer($viewer)
+          ->withFragmentPHIDs(array($fragment->getPHID()))
+          ->execute();
+        $sequence = count($existing);
+
+        $fragment->openTransaction();
+          $version = id(new PhragmentFragmentVersion());
+          $version->setSequence($sequence);
+          $version->setFragmentPHID($fragment->getPHID());
+          $version->setFilePHID($file->getPHID());
+          $version->save();
+
+          $fragment->setLatestVersionPHID($version->getPHID());
+          $fragment->save();
+        $fragment->saveTransaction();
+
+        return id(new AphrontRedirectResponse())
+          ->setURI('/phragment/browse/'.$fragment->getPath());
+      } else {
+        $error_view = id(new AphrontErrorView())
+          ->setErrors($errors)
+          ->setTitle(pht('Errors while updating fragment'));
+      }
+    }
+
+    $form = id(new AphrontFormView())
+      ->setUser($viewer)
+      ->appendChild(
+        id(new AphrontFormTextControl())
+          ->setLabel(pht('File ID'))
+          ->setName('fileID'))
+      ->appendChild(
+        id(new AphrontFormSubmitControl())
+          ->setValue(pht('Update Fragment'))
+          ->addCancelButton(
+            $this->getApplicationURI('browse/'.$fragment->getPath())));
+
+    $crumbs = $this->buildApplicationCrumbsWithPath($parents);
+    $crumbs->addCrumb(
+      id(new PhabricatorCrumbView())
+        ->setName(pht('Update Fragment')));
+
+    $box = id(new PHUIObjectBoxView())
+      ->setHeaderText(pht('Update Fragment: %s', $fragment->getPath()))
+      ->setValidationException(null)
+      ->setForm($form);
+
+    return $this->buildApplicationPage(
+      array(
+        $crumbs,
+        $box),
+      array(
+        'title' => pht('Update Fragment'),
+        'device' => true));
+  }
+
+}