More WIP on reflog commands

This commit is contained in:
Chris Penner 2024-07-03 12:05:45 -07:00
parent 7148685951
commit 7f57612f90
10 changed files with 178 additions and 105 deletions

View File

@ -1493,24 +1493,34 @@ getDeprecatedRootReflog numEntries = do
traverse (bitraverse Q.expectCausalHash pure) entries
-- | Gets the specified number of reflog entries for the given project in chronological order, most recent first.
getProjectReflog :: Int -> Db.ProjectId -> Transaction [ProjectReflog.Entry CausalHash]
getProjectReflog :: Int -> Db.ProjectId -> Transaction [ProjectReflog.Entry Project ProjectBranch CausalHash]
getProjectReflog numEntries projectId = do
entries <- Q.getProjectReflog numEntries projectId
(traverse . traverse) Q.expectCausalHash entries
traverse hydrateProjectReflogEntry entries
-- | Gets the specified number of reflog entries for the specified ProjectBranch in chronological order, most recent first.
getProjectBranchReflog :: Int -> Db.ProjectBranchId -> Transaction [ProjectReflog.Entry CausalHash]
getProjectBranchReflog :: Int -> Db.ProjectBranchId -> Transaction [ProjectReflog.Entry Project ProjectBranch CausalHash]
getProjectBranchReflog numEntries projectBranchId = do
entries <- Q.getProjectBranchReflog numEntries projectBranchId
(traverse . traverse) Q.expectCausalHash entries
traverse hydrateProjectReflogEntry entries
-- | Gets the specified number of reflog entries in chronological order, most recent first.
getGlobalReflog :: Int -> Transaction [ProjectReflog.Entry CausalHash]
getGlobalReflog :: Int -> Transaction [ProjectReflog.Entry Project ProjectBranch CausalHash]
getGlobalReflog numEntries = do
entries <- Q.getGlobalReflog numEntries
(traverse . traverse) Q.expectCausalHash entries
traverse hydrateProjectReflogEntry entries
appendProjectReflog :: ProjectReflog.Entry CausalHash -> Transaction ()
hydrateProjectReflogEntry :: ProjectReflog.Entry Db.ProjectId Db.ProjectBranchId Db.CausalHashId -> Transaction (ProjectReflog.Entry Project ProjectBranch CausalHash)
hydrateProjectReflogEntry entry = do
traverse Q.expectCausalHash entry
>>= ProjectReflog.projectAndBranch_
%%~ ( \(projId, branchId) -> do
proj <- Q.expectProject projId
branch <- Q.expectProjectBranch projId branchId
pure (proj, branch)
)
appendProjectReflog :: ProjectReflog.Entry Db.ProjectId Db.ProjectBranchId CausalHash -> Transaction ()
appendProjectReflog entry = do
dbEntry <- traverse Q.saveCausalHash entry
Q.appendProjectBranchReflog dbEntry

View File

@ -1,28 +1,45 @@
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
module U.Codebase.Sqlite.ProjectReflog where
module U.Codebase.Sqlite.ProjectReflog
( Entry (..),
project_,
branch_,
projectAndBranch_,
)
where
import Control.Lens
import Data.Text (Text)
import Data.Time (UTCTime)
import U.Codebase.Sqlite.DbId (CausalHashId, ProjectBranchId, ProjectId)
import Unison.Sqlite (FromRow (..), ToRow (..), field)
data Entry causal = Entry
{ project :: ProjectId,
branch :: ProjectBranchId,
data Entry project branch causal = Entry
{ project :: project,
branch :: branch,
time :: UTCTime,
fromRootCausalHash :: Maybe causal,
toRootCausalHash :: causal,
reason :: Text
}
deriving stock (Show, Functor, Foldable, Traversable)
deriving stock (Eq, Show, Functor, Foldable, Traversable)
instance ToRow (Entry CausalHashId) where
project_ :: Lens (Entry project branch causal) (Entry project' branch causal) project project'
project_ = lens project (\e p -> e {project = p})
branch_ :: Lens (Entry project branch causal) (Entry project branch' causal) branch branch'
branch_ = lens branch (\e b -> e {branch = b})
-- | Both Project and Branch Ids are required to load a branch, so this is often more useful.
projectAndBranch_ :: Lens (Entry project branch causal) (Entry project' branch' causal) (project, branch) (project', branch')
projectAndBranch_ = lens (\Entry {..} -> (project, branch)) (\e (project, branch) -> e {project = project, branch = branch})
instance ToRow (Entry ProjectId ProjectBranchId CausalHashId) where
toRow (Entry proj branch time fromRootCausalHash toRootCausalHash reason) =
toRow (proj, branch, time, fromRootCausalHash, toRootCausalHash, reason)
instance FromRow (Entry CausalHashId) where
instance FromRow (Entry ProjectId ProjectBranchId CausalHashId) where
fromRow = do
project <- field
branch <- field

View File

@ -3483,7 +3483,7 @@ getDeprecatedRootReflog numEntries =
LIMIT :numEntries
|]
appendProjectBranchReflog :: ProjectReflog.Entry CausalHashId -> Transaction ()
appendProjectBranchReflog :: ProjectReflog.Entry ProjectId ProjectBranchId CausalHashId -> Transaction ()
appendProjectBranchReflog entry =
execute
[sql|
@ -3492,7 +3492,7 @@ appendProjectBranchReflog entry =
|]
-- | Get x number of entries from the project reflog for the provided project
getProjectReflog :: Int -> ProjectId -> Transaction [ProjectReflog.Entry CausalHashId]
getProjectReflog :: Int -> ProjectId -> Transaction [ProjectReflog.Entry ProjectId ProjectBranchId CausalHashId]
getProjectReflog numEntries projectId =
queryListRow
[sql|
@ -3504,7 +3504,7 @@ getProjectReflog numEntries projectId =
|]
-- | Get x number of entries from the project reflog for the provided branch.
getProjectBranchReflog :: Int -> ProjectBranchId -> Transaction [ProjectReflog.Entry CausalHashId]
getProjectBranchReflog :: Int -> ProjectBranchId -> Transaction [ProjectReflog.Entry ProjectId ProjectBranchId CausalHashId]
getProjectBranchReflog numEntries projectBranchId =
queryListRow
[sql|
@ -3516,7 +3516,7 @@ getProjectBranchReflog numEntries projectBranchId =
|]
-- | Get x number of entries from the global reflog spanning all projects
getGlobalReflog :: Int -> Transaction [ProjectReflog.Entry CausalHashId]
getGlobalReflog :: Int -> Transaction [ProjectReflog.Entry ProjectId ProjectBranchId CausalHashId]
getGlobalReflog numEntries =
queryListRow
[sql|

View File

@ -76,6 +76,9 @@ module Unison.Codebase
-- * Reflog
Operations.getDeprecatedRootReflog,
Operations.getProjectBranchReflog,
Operations.getProjectReflog,
Operations.getGlobalReflog,
-- * Unambiguous hash length
SqliteCodebase.Operations.hashLength,

View File

@ -79,6 +79,7 @@ import Unison.Codebase.Editor.HandleInput.ProjectSwitch (projectSwitch)
import Unison.Codebase.Editor.HandleInput.Projects (handleProjects)
import Unison.Codebase.Editor.HandleInput.Pull (handlePull, mergeBranchAndPropagateDefaultPatch)
import Unison.Codebase.Editor.HandleInput.Push (handlePushRemoteBranch)
import Unison.Codebase.Editor.HandleInput.Reflogs qualified as Reflogs
import Unison.Codebase.Editor.HandleInput.ReleaseDraft (handleReleaseDraft)
import Unison.Codebase.Editor.HandleInput.Run (handleRun)
import Unison.Codebase.Editor.HandleInput.RuntimeUtils qualified as RuntimeUtils
@ -243,6 +244,14 @@ loop e = do
-- No expectation, either because this is the most recent entry or
-- because we're recovering from a discontinuity
Nothing -> ((Just time, toRootCausalHash, reason), (rest, Just fromRootCausalHash, moreEntriesToLoad))
ShowProjectBranchReflogI mayProjBranch -> do
Reflogs.showProjectBranchReflog mayProjBranch
ShowGlobalReflogI -> do
Reflogs.showGlobalReflog
ShowProjectReflogI mayProj -> do
Reflogs.showProjectReflog mayProj
ShowProjectReflogI mayProj -> do
Reflogs.showProjectReflog mayProj
ResetI newRoot mtarget -> do
newRoot <-
case newRoot of
@ -1045,11 +1054,11 @@ inputDescription input =
EditNamespaceI paths ->
pure $ Text.unwords ("edit.namespace" : (Path.toText <$> paths))
ShowRootReflogI {} -> pure "deprecated.root-reflog"
ShowProjectReflog mayProjName -> do
ShowProjectReflogI mayProjName -> do
case mayProjName of
Nothing -> pure "project.reflog"
Just projName -> pure $ "project.reflog" <> into @Text projName
ShowProjectBranchReflog mayProjBranch -> do
ShowProjectBranchReflogI mayProjBranch -> do
case mayProjBranch of
Nothing -> pure "branch.reflog"
Just (PP.ProjectAndBranch Nothing branchName) -> pure $ "branch.reflog" <> into @Text branchName

View File

@ -1,85 +1,75 @@
-- | Helpers for working with various kinds of reflogs.
module Unison.Codebase.Editor.HandleInput.Reflogs (showProjectBranchReflog) where
module Unison.Codebase.Editor.HandleInput.Reflogs
( showProjectBranchReflog,
)
where
import Control.Arrow ((&&&))
import Data.List qualified as List
import Data.Time (UTCTime)
import U.Codebase.HashTags (CausalHash)
import U.Codebase.Reflog qualified as Reflog
import Unison.Cli.Monad (Cli)
import Unison.Cli.Monad qualified as Cli
import Unison.Cli.MonadUtils qualified as Cli
import Unison.Cli.ProjectUtils qualified as ProjectUtils
import Unison.Codebase qualified as Codebase
import Unison.Codebase.Editor.Output (Output (..))
import Unison.Codebase.Editor.Output qualified as Output
import Unison.Codebase.Editor.StructuredArgument qualified as SA
import Unison.Prelude
import Unison.Codebase.ShortCausalHash qualified as SCH
import Unison.Core.Project (ProjectAndBranch (..), ProjectBranchName, ProjectName)
import Unison.Prelude
showRootReflog :: Cli ()
showRootReflog = do
let numEntriesToShow = 500
(schLength, entries) <-
Cli.runTransaction $
(,) <$> Codebase.branchHashLength <*> Codebase.getDeprecatedRootReflog numEntriesToShow
let moreEntriesToLoad = length entries == numEntriesToShow
let expandedEntries = List.unfoldr expandEntries (entries, Nothing, moreEntriesToLoad)
let (shortEntries, numberedEntries) =
unzip $
expandedEntries <&> \(time, hash, reason) ->
let (exp, sa) = (SCH.fromHash schLength &&& SA.Namespace) hash
in ((time, exp, reason), sa)
Cli.setNumberedArgs numberedEntries
Cli.respond $ ShowReflog shortEntries
where
expandEntries ::
([Reflog.Entry CausalHash Text], Maybe CausalHash, Bool) ->
Maybe ((Maybe UTCTime, CausalHash, Text), ([Reflog.Entry CausalHash Text], Maybe CausalHash, Bool))
expandEntries ([], Just expectedHash, moreEntriesToLoad) =
if moreEntriesToLoad
then Nothing
else Just ((Nothing, expectedHash, "history starts here"), ([], Nothing, moreEntriesToLoad))
expandEntries ([], Nothing, _moreEntriesToLoad) = Nothing
expandEntries (entries@(Reflog.Entry {time, fromRootCausalHash, toRootCausalHash, reason} : rest), mayExpectedHash, moreEntriesToLoad) =
Just $
case mayExpectedHash of
Just expectedHash
| expectedHash == toRootCausalHash -> ((Just time, toRootCausalHash, reason), (rest, Just fromRootCausalHash, moreEntriesToLoad))
-- Historical discontinuity, insert a synthetic entry
| otherwise -> ((Nothing, toRootCausalHash, "(external change)"), (entries, Nothing, moreEntriesToLoad))
-- No expectation, either because this is the most recent entry or
-- because we're recovering from a discontinuity
Nothing -> ((Just time, toRootCausalHash, reason), (rest, Just fromRootCausalHash, moreEntriesToLoad))
-- showRootReflog :: Cli ()
-- showRootReflog = do
-- let numEntriesToShow = 500
-- (schLength, entries) <-
-- Cli.runTransaction $
-- (,) <$> Codebase.branchHashLength <*> Codebase.getDeprecatedRootReflog numEntriesToShow
-- let moreEntriesToLoad = length entries == numEntriesToShow
-- let expandedEntries = List.unfoldr expandEntries (entries, Nothing, moreEntriesToLoad)
-- let (shortEntries, numberedEntries) =
-- unzip $
-- expandedEntries <&> \(time, hash, reason) ->
-- let (exp, sa) = (SCH.fromHash schLength &&& SA.Namespace) hash
-- in ((time, exp, reason), sa)
-- Cli.setNumberedArgs numberedEntries
-- Cli.respond $ ShowReflog shortEntries
-- where
-- expandEntries ::
-- ([Reflog.Entry CausalHash Text], Maybe CausalHash, Bool) ->
-- Maybe ((Maybe UTCTime, CausalHash, Text), ([Reflog.Entry CausalHash Text], Maybe CausalHash, Bool))
-- expandEntries ([], Just expectedHash, moreEntriesToLoad) =
-- if moreEntriesToLoad
-- then Nothing
-- else Just ((Nothing, expectedHash, "history starts here"), ([], Nothing, moreEntriesToLoad))
-- expandEntries ([], Nothing, _moreEntriesToLoad) = Nothing
-- expandEntries (entries@(Reflog.Entry {time, fromRootCausalHash, toRootCausalHash, reason} : rest), mayExpectedHash, moreEntriesToLoad) =
-- Just $
-- case mayExpectedHash of
-- Just expectedHash
-- | expectedHash == toRootCausalHash -> ((Just time, toRootCausalHash, reason), (rest, Just fromRootCausalHash, moreEntriesToLoad))
-- -- Historical discontinuity, insert a synthetic entry
-- | otherwise -> ((Nothing, toRootCausalHash, "(external change)"), (entries, Nothing, moreEntriesToLoad))
-- -- No expectation, either because this is the most recent entry or
-- -- because we're recovering from a discontinuity
-- Nothing -> ((Just time, toRootCausalHash, reason), (rest, Just fromRootCausalHash, moreEntriesToLoad))
showProjectBranchReflog :: Maybe (ProjectAndBranch (Maybe ProjectName) ProjectBranchName) -> Cli ()
showProjectBranchReflog = do
showProjectBranchReflog mayProjectAndBranch = do
ProjectAndBranch project branch <- case mayProjectAndBranch of
Nothing -> Cli.getCurrentProjectAndBranch
Just pab -> ProjectUtils.resolveProjectBranch (second Just pab)
let numEntriesToShow = 500
(schLength, entries) <-
Cli.runTransaction $
(,) <$> Codebase.branchHashLength <*> Codebase.getDeprecatedRootReflog numEntriesToShow
let moreEntriesToLoad = length entries == numEntriesToShow
let expandedEntries = List.unfoldr expandEntries (entries, Nothing, moreEntriesToLoad)
let (shortEntries, numberedEntries) =
unzip $
expandedEntries <&> \(time, hash, reason) ->
let (exp, sa) = (SCH.fromHash schLength &&& SA.Namespace) hash
in ((time, exp, reason), sa)
Cli.setNumberedArgs numberedEntries
Cli.respond $ ShowReflog shortEntries
where
expandEntries ::
([Reflog.Entry CausalHash Text], Maybe CausalHash, Bool) ->
Maybe ((Maybe UTCTime, CausalHash, Text), ([Reflog.Entry CausalHash Text], Maybe CausalHash, Bool))
expandEntries ([], Just expectedHash, moreEntriesToLoad) =
if moreEntriesToLoad
then Nothing
else Just ((Nothing, expectedHash, "history starts here"), ([], Nothing, moreEntriesToLoad))
expandEntries ([], Nothing, _moreEntriesToLoad) = Nothing
expandEntries (entries@(Reflog.Entry {time, fromRootCausalHash, toRootCausalHash, reason} : rest), mayExpectedHash, moreEntriesToLoad) =
Just $
case mayExpectedHash of
Just expectedHash
| expectedHash == toRootCausalHash -> ((Just time, toRootCausalHash, reason), (rest, Just fromRootCausalHash, moreEntriesToLoad))
-- Historical discontinuity, insert a synthetic entry
| otherwise -> ((Nothing, toRootCausalHash, "(external change)"), (entries, Nothing, moreEntriesToLoad))
-- No expectation, either because this is the most recent entry or
-- because we're recovering from a discontinuity
Nothing -> ((Just time, toRootCausalHash, reason), (rest, Just fromRootCausalHash, moreEntriesToLoad))
entries <-
Cli.runTransaction $ do
schLength <- Codebase.branchHashLength
entries <- Codebase.getProjectBranchReflog numEntriesToShow branch.branchId
entries
& (fmap . fmap) SCH.fromHash schLength
& pure
let moreEntriesToLoad =
if length entries == numEntriesToShow
then Output.MoreEntriesThanShown
else Output.AllEntriesShown
Cli.respondNumbered $ ShowProjectBranchReflog moreEntriesToLoad shortEntries

View File

@ -192,8 +192,9 @@ data Input
| -- Show provided definitions.
ShowDefinitionI OutputLocation ShowDefinitionScope (NonEmpty (HQ.HashQualified Name))
| ShowRootReflogI {- Deprecated -}
| ShowProjectReflog (Maybe ProjectName)
| ShowProjectBranchReflog (Maybe (ProjectAndBranch (Maybe ProjectName) ProjectBranchName))
| ShowGlobalReflogI
| ShowProjectReflogI (Maybe ProjectName)
| ShowProjectBranchReflogI (Maybe (ProjectAndBranch (Maybe ProjectName) ProjectBranchName))
| UpdateBuiltinsI
| MergeBuiltinsI (Maybe Path)
| MergeIOBuiltinsI (Maybe Path)

View File

@ -10,6 +10,7 @@ module Unison.Codebase.Editor.Output
TestReportStats (..),
TodoOutput (..),
todoOutputIsEmpty,
MoreEntriesThanShown (..),
UndoFailureReason (..),
ShareError (..),
UpdateOrUpgrade (..),
@ -29,6 +30,7 @@ import U.Codebase.Branch.Diff (NameChanges)
import U.Codebase.HashTags (CausalHash)
import U.Codebase.Sqlite.Project qualified as Sqlite
import U.Codebase.Sqlite.ProjectBranch qualified as Sqlite
import U.Codebase.Sqlite.ProjectReflog qualified as ProjectReflog
import Unison.Auth.Types (CredentialFailure)
import Unison.Cli.MergeTypes (MergeSourceAndTarget, MergeSourceOrTarget)
import Unison.Cli.Share.Projects.Types qualified as Share
@ -43,7 +45,7 @@ import Unison.Codebase.Editor.StructuredArgument (StructuredArgument)
import Unison.Codebase.IntegrityCheck (IntegrityResult (..))
import Unison.Codebase.Path (Path')
import Unison.Codebase.Path qualified as Path
import Unison.Codebase.ProjectPath (ProjectPath)
import Unison.Codebase.ProjectPath (Project, ProjectBranch, ProjectPath)
import Unison.Codebase.Runtime qualified as Runtime
import Unison.Codebase.ShortCausalHash (ShortCausalHash)
import Unison.Codebase.ShortCausalHash qualified as SCH
@ -57,6 +59,7 @@ import Unison.LabeledDependency (LabeledDependency)
import Unison.Name (Name)
import Unison.NameSegment (NameSegment)
import Unison.Names (Names)
import Unison.Names qualified as Names
import Unison.Names.ResolutionResult qualified as Names
import Unison.NamesWithHistory qualified as Names
import Unison.Parser.Ann (Ann)
@ -83,7 +86,6 @@ import Unison.Util.Defns (DefnsF, defnsAreEmpty)
import Unison.Util.Pretty qualified as P
import Unison.Util.Relation (Relation)
import Unison.WatchKind qualified as WK
import qualified Unison.Names as Names
type ListDetailed = Bool
@ -152,6 +154,7 @@ data NumberedOutput
PPE.PrettyPrintEnv -- PPE containing names for everything from the root namespace.
ProjectPath -- The namespace we're checking dependencies for.
(Map LabeledDependency (Set Name)) -- Mapping of external dependencies to their local dependents.
| ShowProjectBranchReflog UTCTime {- current time -} MoreEntriesThanShown [ProjectReflog.Entry Project ProjectBranch (CausalHash, SCH.ShortCausalHash)]
data TodoOutput = TodoOutput
{ dependentsOfTodo :: !(Set TermReferenceId),
@ -187,15 +190,15 @@ data Output
| -- | Function found, but has improper type
-- Note: the constructor name is misleading here; we weren't necessarily looking for a "main".
BadMainFunction
-- | what we were trying to do (e.g. "run", "io.test")
Text
-- ^ what we were trying to do (e.g. "run", "io.test")
-- | name of function
(HQ.HashQualified Name)
-- ^ name of function
-- | bad type of function
(Type Symbol Ann)
-- ^ bad type of function
PPE.PrettyPrintEnv
-- | acceptable type(s) of function
[Type Symbol Ann]
-- ^ acceptable type(s) of function
| BranchEmpty WhichBranchEmpty
| LoadPullRequest (ReadRemoteNamespace Void) (ReadRemoteNamespace Void) Path' Path' Path' Path'
| CreatedNewBranch Path.Absolute
@ -232,12 +235,12 @@ data Output
-- for terms. This additional info is used to provide an enhanced
-- error message.
SearchTermsNotFoundDetailed
-- | @True@ if we are searching for a term, @False@ if we are searching for a type
Bool
-- ^ @True@ if we are searching for a term, @False@ if we are searching for a type
-- | Misses (search terms that returned no hits for terms or types)
[HQ.HashQualified Name]
-- ^ Misses (search terms that returned no hits for terms or types)
-- | Hits for types if we are searching for terms or terms if we are searching for types
[HQ.HashQualified Name]
-- ^ Hits for types if we are searching for terms or terms if we are searching for types
| -- ask confirmation before deleting the last branch that contains some defns
-- `Path` is one of the paths the user has requested to delete, and is paired
-- with whatever named definitions would not have any remaining names if
@ -379,8 +382,8 @@ data Output
| CalculatingDiff
| -- | The `local` in a `clone remote local` is ambiguous
AmbiguousCloneLocal
-- | Treating `local` as a project. We may know the branch name, if it was provided in `remote`.
(ProjectAndBranch ProjectName ProjectBranchName)
-- ^ Treating `local` as a project. We may know the branch name, if it was provided in `remote`.
(ProjectAndBranch ProjectName ProjectBranchName)
| -- | The `remote` in a `clone remote local` is ambiguous
AmbiguousCloneRemote ProjectName (ProjectAndBranch ProjectName ProjectBranchName)
@ -420,6 +423,9 @@ data Output
| PullIntoMissingBranch !(ReadRemoteNamespace Share.RemoteProjectBranch) !(ProjectAndBranch (Maybe ProjectName) ProjectBranchName)
| NoMergeInProgress
data MoreEntriesThanShown = MoreEntriesThanShown | AllEntriesShown
deriving (Eq, Show)
data UpdateOrUpgrade = UOUUpdate | UOUUpgrade
-- | What did we create a project branch from?
@ -677,3 +683,4 @@ isNumberedFailure = \case
ListNamespaceDependencies {} -> False
TestResults _ _ _ _ _ fails -> not (null fails)
Output'Todo {} -> False
ShowProjectBranchReflog {} -> False

View File

@ -2279,8 +2279,8 @@ branchReflog =
]
)
( \case
[] -> pure $ Input.ShowProjectBranchReflog Nothing
[branchRef] -> Input.ShowProjectBranchReflog <$> (Just <$> handleMaybeProjectBranchArg branchRef)
[] -> pure $ Input.ShowProjectBranchReflogI Nothing
[branchRef] -> Input.ShowProjectBranchReflogI <$> (Just <$> handleMaybeProjectBranchArg branchRef)
_ -> Left (I.help branchReflog)
)
@ -2297,8 +2297,8 @@ projectReflog =
]
)
( \case
[] -> pure $ Input.ShowProjectReflog Nothing
[projectRef] -> Input.ShowProjectReflog <$> (Just <$> handleProjectArg projectRef)
[] -> pure $ Input.ShowProjectReflogI Nothing
[projectRef] -> Input.ShowProjectReflogI <$> (Just <$> handleProjectArg projectRef)
_ -> Left (I.help projectReflog)
)

View File

@ -37,6 +37,7 @@ import U.Codebase.HashTags (CausalHash (..))
import U.Codebase.Reference qualified as Reference
import U.Codebase.Sqlite.Project (Project (..))
import U.Codebase.Sqlite.ProjectBranch (ProjectBranch (..))
import U.Codebase.Sqlite.ProjectReflog qualified as ProjectReflog
import Unison.ABT qualified as ABT
import Unison.Auth.Types qualified as Auth
import Unison.Builtin.Decls qualified as DD
@ -553,6 +554,7 @@ notifyNumbered = \case
& Set.toList
& fmap (\name -> formatNum (getNameNumber name) <> prettyName name)
& P.lines
ShowProjectBranchReflog now moreToShow entries -> displayProjectBranchReflogEntries now moreToShow entries
where
absPathToBranchId = BranchAtPath
@ -3375,3 +3377,37 @@ listDependentsOrDependencies ppe labelStart label lds types terms =
P.indentN 2 . P.numberedListFrom (length types) $ c . prettyHashQualified <$> terms
]
c = P.syntaxToColor
displayProjectBranchReflogEntries ::
UTCTime ->
E.MoreEntriesThanShown ->
[ProjectReflog.Entry Project ProjectBranch (CausalHash, ShortCausalHash)] ->
(Pretty, NumberedArgs)
displayProjectBranchReflogEntries _ _ [] =
(P.warnCallout "The reflog is empty", mempty)
displayProjectBranchReflogEntries now _ entries =
let (entryRows, numberedArgs) = foldMap renderEntry entries
rendered =
P.lines
[ header,
"",
P.numberedColumnNHeader ["Branch", "When", "Hash", "Description"] entryRows
]
in (rendered, numberedArgs)
where
header =
P.lines
[ P.wrap $
"Below is a record of recent changes, you can use "
<> IP.makeExample IP.reset ["#abcdef"]
<> " to reset the current branch to a previous state.",
"",
tip $ "Use " <> IP.makeExample IP.diffNamespace ["1", "7"] <> " to compare between points in history."
]
renderEntry :: ProjectReflog.Entry Project ProjectBranch (CausalHash, SCH.ShortCausalHash) -> ([[Pretty]], NumberedArgs)
renderEntry ProjectReflog.Entry {time, project, branch, toRootCausalHash = (toCH, toSCH), reason} =
([[prettyProjectAndBranchName $ ProjectAndBranch project.name branch.name, prettyHumanReadableTime now time, P.blue (prettySCH toSCH), P.text $ truncateReason reason]], [SA.Namespace toCH])
truncateReason :: Text -> Text
truncateReason txt = case Text.splitAt 60 txt of
(short, "") -> short
(short, _) -> short <> "..."