mirror of
https://github.com/unisonweb/unison.git
synced 2024-09-11 02:25:39 +03:00
delete a bunch of patch manipulation commands
This commit is contained in:
parent
8a27961e9a
commit
6adb88f5b3
@ -15,8 +15,6 @@ module Unison.Codebase.BranchUtil
|
||||
makeAddTermName,
|
||||
makeDeleteTermName,
|
||||
makeAnnihilateTermName,
|
||||
makeDeletePatch,
|
||||
makeReplacePatch,
|
||||
)
|
||||
where
|
||||
|
||||
@ -24,7 +22,6 @@ import Data.Map qualified as Map
|
||||
import Data.Set qualified as Set
|
||||
import Unison.Codebase.Branch (Branch, Branch0)
|
||||
import Unison.Codebase.Branch qualified as Branch
|
||||
import Unison.Codebase.Patch (Patch)
|
||||
import Unison.Codebase.Path (Path)
|
||||
import Unison.Codebase.Path qualified as Path
|
||||
import Unison.HashQualified' (HashQualified (HashQualified, NameOnly))
|
||||
@ -83,12 +80,6 @@ makeAnnihilateTermName (p, name) = (p, Branch.annihilateTermName name)
|
||||
makeAnnihilateTypeName :: Path.Split -> (Path, Branch0 m -> Branch0 m)
|
||||
makeAnnihilateTypeName (p, name) = (p, Branch.annihilateTypeName name)
|
||||
|
||||
makeReplacePatch :: (Applicative m) => Path.Split -> Patch -> (Path, Branch0 m -> Branch0 m)
|
||||
makeReplacePatch (p, name) patch = (p, Branch.replacePatch name patch)
|
||||
|
||||
makeDeletePatch :: Path.Split -> (Path, Branch0 m -> Branch0 m)
|
||||
makeDeletePatch (p, name) = (p, Branch.deletePatch name)
|
||||
|
||||
makeAddTypeName :: Path.Split -> Reference -> (Path, Branch0 m -> Branch0 m)
|
||||
makeAddTypeName (p, name) r = (p, Branch.addTypeName r name)
|
||||
|
||||
|
@ -67,9 +67,6 @@ module Unison.Cli.MonadUtils
|
||||
|
||||
-- ** Getting patches
|
||||
getPatchAt,
|
||||
getMaybePatchAt,
|
||||
expectPatchAt,
|
||||
assertNoPatchAt,
|
||||
|
||||
-- * Latest touched Unison file
|
||||
getLatestFile,
|
||||
@ -514,16 +511,6 @@ getMaybePatchAt path0 = do
|
||||
branch <- getBranch0At path
|
||||
liftIO (Branch.getMaybePatch name branch)
|
||||
|
||||
-- | Get the patch at a path, or return early if there's no such patch.
|
||||
expectPatchAt :: Path.Split' -> Cli Patch
|
||||
expectPatchAt path =
|
||||
getMaybePatchAt path & onNothingM (Cli.returnEarly (Output.PatchNotFound path))
|
||||
|
||||
-- | Assert that there's no patch at a path, or return early if there is one.
|
||||
assertNoPatchAt :: Path.Split' -> Cli ()
|
||||
assertNoPatchAt path = do
|
||||
whenJustM (getMaybePatchAt path) \_ -> Cli.returnEarly (Output.PatchAlreadyExists path)
|
||||
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
-- Latest (typechecked) unison file utils
|
||||
|
||||
|
@ -27,7 +27,6 @@ import Text.Megaparsec qualified as Megaparsec
|
||||
import U.Codebase.Branch.Diff qualified as V2Branch.Diff
|
||||
import U.Codebase.Causal qualified as V2Causal
|
||||
import U.Codebase.HashTags (CausalHash (..))
|
||||
import U.Codebase.Reference qualified as V2 (Reference)
|
||||
import U.Codebase.Reflog qualified as Reflog
|
||||
import U.Codebase.Sqlite.Project qualified as Sqlite
|
||||
import U.Codebase.Sqlite.ProjectBranch qualified as Sqlite
|
||||
@ -78,7 +77,7 @@ import Unison.Codebase.Editor.HandleInput.ProjectCreate (projectCreate)
|
||||
import Unison.Codebase.Editor.HandleInput.ProjectRename (handleProjectRename)
|
||||
import Unison.Codebase.Editor.HandleInput.ProjectSwitch (projectSwitch)
|
||||
import Unison.Codebase.Editor.HandleInput.Projects (handleProjects)
|
||||
import Unison.Codebase.Editor.HandleInput.Pull (handlePull, mergeBranchAndPropagateDefaultPatch, propagatePatch)
|
||||
import Unison.Codebase.Editor.HandleInput.Pull (handlePull, mergeBranchAndPropagateDefaultPatch)
|
||||
import Unison.Codebase.Editor.HandleInput.Push (handleGist, handlePushRemoteBranch)
|
||||
import Unison.Codebase.Editor.HandleInput.ReleaseDraft (handleReleaseDraft)
|
||||
import Unison.Codebase.Editor.HandleInput.Run (handleRun)
|
||||
@ -106,15 +105,8 @@ import Unison.Codebase.Patch qualified as Patch
|
||||
import Unison.Codebase.Path (Path, Path' (..))
|
||||
import Unison.Codebase.Path qualified as HQSplit'
|
||||
import Unison.Codebase.Path qualified as Path
|
||||
import Unison.Codebase.Path.Parse qualified as Path
|
||||
import Unison.Codebase.Runtime qualified as Runtime
|
||||
import Unison.Codebase.ShortCausalHash qualified as SCH
|
||||
import Unison.Codebase.SqliteCodebase.Conversions qualified as Conversions
|
||||
import Unison.Codebase.TermEdit (TermEdit (..))
|
||||
import Unison.Codebase.TermEdit qualified as TermEdit
|
||||
import Unison.Codebase.TermEdit.Typing qualified as TermEdit
|
||||
import Unison.Codebase.TypeEdit (TypeEdit)
|
||||
import Unison.Codebase.TypeEdit qualified as TypeEdit
|
||||
import Unison.CommandLine.BranchRelativePath (BranchRelativePath)
|
||||
import Unison.CommandLine.Completion qualified as Completion
|
||||
import Unison.CommandLine.DisplayValues qualified as DisplayValues
|
||||
@ -132,7 +124,6 @@ import Unison.LabeledDependency qualified as LD
|
||||
import Unison.LabeledDependency qualified as LabeledDependency
|
||||
import Unison.Name (Name)
|
||||
import Unison.Name qualified as Name
|
||||
import Unison.NameSegment (NameSegment (..))
|
||||
import Unison.NameSegment qualified as NameSegment
|
||||
import Unison.Names (Names (Names))
|
||||
import Unison.Names qualified as Names
|
||||
@ -148,7 +139,7 @@ import Unison.PrettyPrintEnvDecl qualified as PPED
|
||||
import Unison.PrettyPrintEnvDecl.Names qualified as PPED
|
||||
import Unison.Project (ProjectAndBranch (..))
|
||||
import Unison.Project.Util (projectContextFromPath)
|
||||
import Unison.Reference (Reference, TermReference)
|
||||
import Unison.Reference (Reference)
|
||||
import Unison.Reference qualified as Reference
|
||||
import Unison.Referent (Referent)
|
||||
import Unison.Referent qualified as Referent
|
||||
@ -159,7 +150,6 @@ import Unison.Server.CodebaseServer qualified as Server
|
||||
import Unison.Server.Doc.Markdown.Render qualified as Md
|
||||
import Unison.Server.Doc.Markdown.Types qualified as Md
|
||||
import Unison.Server.NameSearch.FromNames qualified as NameSearch
|
||||
import Unison.Server.QueryResult
|
||||
import Unison.Server.SearchResult (SearchResult)
|
||||
import Unison.Server.SearchResult qualified as SR
|
||||
import Unison.Share.Codeserver qualified as Codeserver
|
||||
@ -207,60 +197,7 @@ loop e = do
|
||||
Just (_, True) -> (#latestFile . _Just . _2) .= False
|
||||
_ -> loadUnisonFile sourceName text
|
||||
Right input ->
|
||||
let typeReferences :: [SearchResult] -> [Reference]
|
||||
typeReferences rs =
|
||||
[r | SR.Tp (SR.TypeResult _ r _) <- rs]
|
||||
termReferences :: [SearchResult] -> [Reference]
|
||||
termReferences rs =
|
||||
[r | SR.Tm (SR.TermResult _ (Referent.Ref r) _) <- rs]
|
||||
termResults rs = [r | SR.Tm r <- rs]
|
||||
typeResults rs = [r | SR.Tp r <- rs]
|
||||
doRemoveReplacement :: HQ.HashQualified Name -> Maybe PatchPath -> Bool -> Cli ()
|
||||
doRemoveReplacement from patchPath isTerm = do
|
||||
let patchPath' = fromMaybe Cli.defaultPatchPath patchPath
|
||||
patch <- Cli.getPatchAt patchPath'
|
||||
QueryResult misses allHits <- hqNameQuery Names.IncludeSuffixes [from]
|
||||
let tpRefs = Set.fromList $ typeReferences allHits
|
||||
tmRefs = Set.fromList $ termReferences allHits
|
||||
(hits, opHits) =
|
||||
let tmResults = Set.fromList $ SR.termName <$> termResults allHits
|
||||
tpResults = Set.fromList $ SR.typeName <$> typeResults allHits
|
||||
in case isTerm of
|
||||
True -> (tmResults, tpResults)
|
||||
False -> (tpResults, tmResults)
|
||||
go :: Text -> Reference -> Cli ()
|
||||
go description fr = do
|
||||
let termPatch = over Patch.termEdits (R.deleteDom fr) patch
|
||||
typePatch = over Patch.typeEdits (R.deleteDom fr) patch
|
||||
(patchPath'', patchName) <- Cli.resolveSplit' patchPath'
|
||||
-- Save the modified patch
|
||||
Cli.stepAtM
|
||||
description
|
||||
( Path.unabsolute patchPath'',
|
||||
Branch.modifyPatches
|
||||
patchName
|
||||
(const (if isTerm then termPatch else typePatch))
|
||||
)
|
||||
-- Say something
|
||||
Cli.respond Success
|
||||
when (Set.null hits) do
|
||||
Cli.respond (SearchTermsNotFoundDetailed isTerm misses (Set.toList opHits))
|
||||
description <- inputDescription input
|
||||
traverse_ (go description) (if isTerm then tmRefs else tpRefs)
|
||||
saveAndApplyPatch :: Path -> NameSegment -> Patch -> Cli ()
|
||||
saveAndApplyPatch patchPath'' patchName patch' = do
|
||||
description <- inputDescription input
|
||||
Cli.stepAtM
|
||||
(description <> " (1/2)")
|
||||
( patchPath'',
|
||||
Branch.modifyPatches patchName (const patch')
|
||||
)
|
||||
-- Apply the modified patch to the current path
|
||||
-- since we might be able to propagate further.
|
||||
currentPath <- Cli.getCurrentPath
|
||||
void $ propagatePatch description patch' currentPath
|
||||
Cli.respond Success
|
||||
previewResponse sourceName sr uf = do
|
||||
let previewResponse sourceName sr uf = do
|
||||
names <- Cli.currentNames
|
||||
let namesWithDefinitionsFromFile = UF.addNamesFromTypeCheckedUnisonFile uf names
|
||||
filePPED <- Cli.prettyPrintEnvDeclFromNames namesWithDefinitionsFromFile
|
||||
@ -463,27 +400,6 @@ loop e = do
|
||||
hasConfirmed <- confirmedCommand input
|
||||
description <- inputDescription input
|
||||
doMoveBranch description hasConfirmed src' dest'
|
||||
MovePatchI src' dest' -> do
|
||||
description <- inputDescription input
|
||||
p <- Cli.expectPatchAt src'
|
||||
Cli.assertNoPatchAt dest'
|
||||
src <- Cli.resolveSplit' src'
|
||||
dest <- Cli.resolveSplit' dest'
|
||||
Cli.stepManyAt
|
||||
description
|
||||
[ BranchUtil.makeDeletePatch (Path.convert src),
|
||||
BranchUtil.makeReplacePatch (Path.convert dest) p
|
||||
]
|
||||
Cli.respond Success
|
||||
CopyPatchI src dest' -> do
|
||||
description <- inputDescription input
|
||||
p <- Cli.expectPatchAt src
|
||||
Cli.assertNoPatchAt dest'
|
||||
dest <- Cli.resolveSplit' dest'
|
||||
Cli.stepAt
|
||||
description
|
||||
(BranchUtil.makeReplacePatch (Path.convert dest) p)
|
||||
Cli.respond Success
|
||||
SwitchBranchI path' -> do
|
||||
path <- Cli.resolvePath' path'
|
||||
branchExists <- Cli.branchExistsAtPath' path'
|
||||
@ -727,14 +643,6 @@ loop e = do
|
||||
DeleteTarget'TermOrType doutput hqs -> delete input doutput Cli.getTermsAt Cli.getTypesAt hqs
|
||||
DeleteTarget'Type doutput hqs -> delete input doutput (const (pure Set.empty)) Cli.getTypesAt hqs
|
||||
DeleteTarget'Term doutput hqs -> delete input doutput Cli.getTermsAt (const (pure Set.empty)) hqs
|
||||
DeleteTarget'Patch src' -> do
|
||||
_ <- Cli.expectPatchAt src'
|
||||
description <- inputDescription input
|
||||
src <- Cli.resolveSplit' src'
|
||||
Cli.stepAt
|
||||
description
|
||||
(BranchUtil.makeDeletePatch (Path.convert src))
|
||||
Cli.respond Success
|
||||
DeleteTarget'Namespace insistence Nothing -> do
|
||||
hasConfirmed <- confirmedCommand input
|
||||
if hasConfirmed || insistence == Force
|
||||
@ -777,15 +685,6 @@ loop e = do
|
||||
traverse_ (displayI outputLoc) namesToDisplay
|
||||
ShowDefinitionI outputLoc showDefinitionScope query -> handleShowDefinition outputLoc showDefinitionScope query
|
||||
EditNamespaceI paths -> handleEditNamespace LatestFileLocation paths
|
||||
FindPatchI -> do
|
||||
branch <- Cli.getCurrentBranch0
|
||||
let patches =
|
||||
[ Path.unsafeToName $ Path.snoc p seg
|
||||
| (p, b) <- Branch.toList0 branch,
|
||||
(seg, _) <- Map.toList (Branch._edits b)
|
||||
]
|
||||
Cli.respond $ ListOfPatches $ Set.fromList patches
|
||||
Cli.setNumberedArgs $ fmap (Text.unpack . Name.toText) patches
|
||||
FindShallowI pathArg -> do
|
||||
Cli.Env {codebase} <- ask
|
||||
|
||||
@ -818,98 +717,6 @@ loop e = do
|
||||
FindI isVerbose fscope ws -> handleFindI isVerbose fscope ws input
|
||||
StructuredFindI _fscope ws -> handleStructuredFindI ws
|
||||
StructuredFindReplaceI ws -> handleStructuredFindReplaceI ws
|
||||
ReplaceI from to patchPath -> do
|
||||
Cli.Env {codebase} <- ask
|
||||
hqLength <- Cli.runTransaction Codebase.hashLength
|
||||
|
||||
let patchPath' = fromMaybe Cli.defaultPatchPath patchPath
|
||||
patch <- Cli.getPatchAt patchPath'
|
||||
QueryResult fromMisses' fromHits <- hqNameQuery Names.IncludeSuffixes [from]
|
||||
QueryResult toMisses' toHits <- hqNameQuery Names.IncludeSuffixes [to]
|
||||
let termsFromRefs = termReferences fromHits
|
||||
termsToRefs = termReferences toHits
|
||||
typesFromRefs = typeReferences fromHits
|
||||
typesToRefs = typeReferences toHits
|
||||
--- Here are all the kinds of misses
|
||||
--- [X] [X]
|
||||
--- [Type] [Term]
|
||||
--- [Term] [Type]
|
||||
--- [Type] [X]
|
||||
--- [Term] [X]
|
||||
--- [X] [Type]
|
||||
--- [X] [Term]
|
||||
-- Type hits are term misses
|
||||
termFromMisses = fromMisses' <> (SR.typeName <$> typeResults fromHits)
|
||||
termToMisses = toMisses' <> (SR.typeName <$> typeResults toHits)
|
||||
-- Term hits are type misses
|
||||
typeFromMisses = fromMisses' <> (SR.termName <$> termResults fromHits)
|
||||
typeToMisses = toMisses' <> (SR.termName <$> termResults toHits)
|
||||
|
||||
termMisses = termFromMisses <> termToMisses
|
||||
typeMisses = typeFromMisses <> typeToMisses
|
||||
|
||||
replaceTerms :: Reference -> Reference -> Cli ()
|
||||
replaceTerms fr tr = do
|
||||
(mft, mtt) <-
|
||||
Cli.runTransaction do
|
||||
mft <- Codebase.getTypeOfTerm codebase fr
|
||||
mtt <- Codebase.getTypeOfTerm codebase tr
|
||||
pure (mft, mtt)
|
||||
let termNotFound =
|
||||
Cli.returnEarly
|
||||
. TermNotFound'
|
||||
. SH.shortenTo hqLength
|
||||
. Reference.toShortHash
|
||||
ft <- mft & onNothing (termNotFound fr)
|
||||
tt <- mtt & onNothing (termNotFound tr)
|
||||
let patch' =
|
||||
-- The modified patch
|
||||
over
|
||||
Patch.termEdits
|
||||
( R.insert fr (Replace tr (TermEdit.typing tt ft))
|
||||
. R.deleteDom fr
|
||||
)
|
||||
patch
|
||||
(patchPath'', patchName) <- Cli.resolveSplit' patchPath'
|
||||
saveAndApplyPatch (Path.convert patchPath'') patchName patch'
|
||||
|
||||
replaceTypes :: Reference -> Reference -> Cli ()
|
||||
replaceTypes fr tr = do
|
||||
let patch' =
|
||||
-- The modified patch
|
||||
over
|
||||
Patch.typeEdits
|
||||
(R.insert fr (TypeEdit.Replace tr) . R.deleteDom fr)
|
||||
patch
|
||||
(patchPath'', patchName) <- Cli.resolveSplit' patchPath'
|
||||
saveAndApplyPatch (Path.convert patchPath'') patchName patch'
|
||||
|
||||
ambiguous :: HQ.HashQualified Name -> [TermReference] -> Cli a
|
||||
ambiguous t rs =
|
||||
Cli.returnEarly case t of
|
||||
HQ.HashOnly h -> HashAmbiguous h rs'
|
||||
(Path.parseHQSplit' . Text.unpack . HQ.toText -> Right n) -> DeleteNameAmbiguous hqLength n rs' Set.empty
|
||||
_ -> BadName (HQ.toText t)
|
||||
where
|
||||
rs' = Set.map Referent.Ref $ Set.fromList rs
|
||||
|
||||
mismatch typeName termName = Cli.respond $ TypeTermMismatch typeName termName
|
||||
|
||||
case (termsFromRefs, termsToRefs, typesFromRefs, typesToRefs) of
|
||||
([], [], [], []) -> Cli.respond $ SearchTermsNotFound termMisses
|
||||
([_], [], [], [_]) -> mismatch to from
|
||||
([], [_], [_], []) -> mismatch from to
|
||||
([_], [], _, _) -> Cli.respond $ SearchTermsNotFound termMisses
|
||||
([], [_], _, _) -> Cli.respond $ SearchTermsNotFound termMisses
|
||||
(_, _, [_], []) -> Cli.respond $ SearchTermsNotFound typeMisses
|
||||
(_, _, [], [_]) -> Cli.respond $ SearchTermsNotFound typeMisses
|
||||
([fr], [tr], [], []) -> replaceTerms fr tr
|
||||
([], [], [fr], [tr]) -> replaceTypes fr tr
|
||||
(froms, [_], [], []) -> ambiguous from froms
|
||||
([], [], froms, [_]) -> ambiguous from froms
|
||||
([_], tos, [], []) -> ambiguous to tos
|
||||
([], [], [_], tos) -> ambiguous to tos
|
||||
(_, _, _, _) -> error "unpossible"
|
||||
LoadI maybePath -> handleLoad maybePath
|
||||
ClearI -> Cli.respond ClearScreen
|
||||
AddI requestedNames -> do
|
||||
@ -949,12 +756,6 @@ loop e = do
|
||||
branchPath <- Cli.resolvePath' branchPath'
|
||||
doShowTodoOutput patch branchPath
|
||||
TestI testInput -> Tests.handleTest testInput
|
||||
PropagatePatchI patchPath scopePath' -> do
|
||||
description <- inputDescription input
|
||||
patch <- Cli.getPatchAt patchPath
|
||||
scopePath <- Cli.resolvePath' scopePath'
|
||||
updated <- propagatePatch description patch scopePath
|
||||
when (not updated) (Cli.respond $ NothingToPatch patchPath scopePath')
|
||||
ExecuteI main args -> handleRun False main args
|
||||
MakeStandaloneI output main -> doCompile False output main
|
||||
CompileSchemeI output main ->
|
||||
@ -1015,11 +816,6 @@ loop e = do
|
||||
_ <- Cli.updateAtM description destPath \destb ->
|
||||
liftIO (Branch.merge'' (Codebase.lca codebase) Branch.RegularMerge srcb destb)
|
||||
Cli.respond Success
|
||||
ListEditsI maybePath -> do
|
||||
patch <- Cli.getPatchAt (fromMaybe Cli.defaultPatchPath maybePath)
|
||||
pped <- Cli.currentPrettyPrintEnvDecl
|
||||
let suffixifiedPPE = PPED.suffixifiedPPE pped
|
||||
Cli.respondNumbered $ ListEdits patch suffixifiedPPE
|
||||
PullI sourceTarget pullMode -> handlePull sourceTarget pullMode
|
||||
PushRemoteBranchI pushRemoteBranchInput -> handlePushRemoteBranch pushRemoteBranchInput
|
||||
ListDependentsI hq -> handleDependents hq
|
||||
@ -1160,10 +956,6 @@ loop e = do
|
||||
nameChanges <- V2Branch.Diff.allNameChanges Nothing treeDiff
|
||||
pure (DisplayDebugNameDiff nameChanges)
|
||||
Cli.respond output
|
||||
DeprecateTermI {} -> Cli.respond NotImplemented
|
||||
DeprecateTypeI {} -> Cli.respond NotImplemented
|
||||
RemoveTermReplacementI from patchPath -> doRemoveReplacement from patchPath True
|
||||
RemoveTypeReplacementI from patchPath -> doRemoveReplacement from patchPath False
|
||||
UpdateBuiltinsI -> Cli.respond NotImplemented
|
||||
QuitI -> Cli.haltRepl
|
||||
GistI input -> handleGist input
|
||||
@ -1171,9 +963,6 @@ loop e = do
|
||||
VersionI -> do
|
||||
Cli.Env {ucmVersion} <- ask
|
||||
Cli.respond $ PrintVersion ucmVersion
|
||||
DiffNamespaceToPatchI diffNamespaceToPatchInput -> do
|
||||
description <- inputDescription input
|
||||
handleDiffNamespaceToPatch description diffNamespaceToPatchInput
|
||||
ProjectRenameI name -> handleProjectRename name
|
||||
ProjectSwitchI name -> projectSwitch name
|
||||
ProjectCreateI tryDownloadingBase name -> projectCreate tryDownloadingBase name
|
||||
@ -1244,14 +1033,6 @@ inputDescription input =
|
||||
src <- p' src0
|
||||
dest <- p' dest0
|
||||
pure ("move " <> src <> " " <> dest)
|
||||
MovePatchI src0 dest0 -> do
|
||||
src <- ps' src0
|
||||
dest <- ps' dest0
|
||||
pure ("move.patch " <> src <> " " <> dest)
|
||||
CopyPatchI src0 dest0 -> do
|
||||
src <- ps' src0
|
||||
dest <- ps' dest0
|
||||
pure ("copy.patch " <> src <> " " <> dest)
|
||||
DeleteI dtarget -> do
|
||||
case dtarget of
|
||||
DeleteTarget'TermOrType DeleteOutput'NoDiff things0 -> do
|
||||
@ -1278,20 +1059,8 @@ inputDescription input =
|
||||
DeleteTarget'Namespace Force opath0 -> do
|
||||
opath <- ops opath0
|
||||
pure ("delete.namespace.force " <> opath)
|
||||
DeleteTarget'Patch path0 -> do
|
||||
path <- ps' path0
|
||||
pure ("delete.patch " <> path)
|
||||
DeleteTarget'ProjectBranch _ -> wat
|
||||
DeleteTarget'Project _ -> wat
|
||||
ReplaceI src target p0 -> do
|
||||
p <- opatch p0
|
||||
pure $
|
||||
"replace "
|
||||
<> HQ.toText src
|
||||
<> " "
|
||||
<> HQ.toText target
|
||||
<> " "
|
||||
<> p
|
||||
AddI _selection -> pure "add"
|
||||
UpdateI p0 _selection -> do
|
||||
p <-
|
||||
@ -1301,10 +1070,6 @@ inputDescription input =
|
||||
UsePatch p0 -> (" " <>) <$> ps' p0
|
||||
pure ("update.old" <> p)
|
||||
Update2I -> pure ("update")
|
||||
PropagatePatchI p0 scope0 -> do
|
||||
p <- ps' p0
|
||||
scope <- p' scope0
|
||||
pure ("patch " <> p <> " " <> scope)
|
||||
UndoI {} -> pure "undo"
|
||||
ExecuteI s args -> pure ("execute " <> Text.unwords (s : fmap Text.pack args))
|
||||
IOTestI hq -> pure ("io.test " <> HQ.toText hq)
|
||||
@ -1319,17 +1084,6 @@ inputDescription input =
|
||||
pure $ "run.native " <> Text.unwords (nm : fmap Text.pack args)
|
||||
CompileSchemeI fi nm -> pure ("compile.native " <> HQ.toText nm <> " " <> fi)
|
||||
CreateAuthorI id name -> pure ("create.author " <> NameSegment.toEscapedText id <> " " <> name)
|
||||
RemoveTermReplacementI src p0 -> do
|
||||
p <- opatch p0
|
||||
pure ("delete.term-replacement" <> HQ.toText src <> " " <> p)
|
||||
RemoveTypeReplacementI src p0 -> do
|
||||
p <- opatch p0
|
||||
pure ("delete.type-replacement" <> HQ.toText src <> " " <> p)
|
||||
DiffNamespaceToPatchI input -> do
|
||||
branchId1 <- hp' (input ^. #branchId1)
|
||||
branchId2 <- hp' (input ^. #branchId2)
|
||||
patch <- ps' (input ^. #patch)
|
||||
pure (Text.unwords ["diff.namespace.to-patch", branchId1, branchId2, patch])
|
||||
ClearI {} -> pure "clear"
|
||||
DocToMarkdownI name -> pure ("debug.doc-to-markdown " <> Name.toText name)
|
||||
--
|
||||
@ -1356,14 +1110,11 @@ inputDescription input =
|
||||
DebugFuzzyOptionsI cmd input -> pure . Text.pack $ "debug.fuzzy-completions " <> unwords (cmd : toList input)
|
||||
DebugFormatI -> pure "debug.format"
|
||||
DebugTypecheckedUnisonFileI {} -> wat
|
||||
DeprecateTermI {} -> wat
|
||||
DeprecateTypeI {} -> wat
|
||||
DiffNamespaceI {} -> wat
|
||||
DisplayI {} -> wat
|
||||
DocsI {} -> wat
|
||||
DocsToHtmlI {} -> wat
|
||||
FindI {} -> wat
|
||||
FindPatchI {} -> wat
|
||||
FindShallowI {} -> wat
|
||||
StructuredFindI {} -> wat
|
||||
StructuredFindReplaceI {} -> wat
|
||||
@ -1372,7 +1123,6 @@ inputDescription input =
|
||||
LibInstallI {} -> wat
|
||||
ListDependenciesI {} -> wat
|
||||
ListDependentsI {} -> wat
|
||||
ListEditsI {} -> wat
|
||||
LoadI {} -> wat
|
||||
MergeI {} -> wat
|
||||
NamesI {} -> wat
|
||||
@ -1411,8 +1161,6 @@ inputDescription input =
|
||||
brp = fmap from . ProjectUtils.resolveBranchRelativePath
|
||||
ops :: Maybe Path.Split -> Cli Text
|
||||
ops = maybe (pure ".") ps
|
||||
opatch :: Maybe Path.Split' -> Cli Text
|
||||
opatch = ps' . fromMaybe Cli.defaultPatchPath
|
||||
wat = error $ show input ++ " is not expected to alter the branch"
|
||||
hhqs' :: Either SH.ShortHash Path.HQSplit' -> Cli Text
|
||||
hhqs' = \case
|
||||
@ -1592,73 +1340,6 @@ handleDependents hq = do
|
||||
Cli.setNumberedArgs $ map (Text.unpack . Reference.toText . view _2) (types <> terms)
|
||||
Cli.respond (ListDependents ppe lds (fst <$> types) (fst <$> terms))
|
||||
|
||||
handleDiffNamespaceToPatch :: Text -> DiffNamespaceToPatchInput -> Cli ()
|
||||
handleDiffNamespaceToPatch description input = do
|
||||
Cli.Env {codebase} <- ask
|
||||
|
||||
absBranchId1 <- Cli.resolveBranchIdToAbsBranchId (input ^. #branchId1)
|
||||
absBranchId2 <- Cli.resolveBranchIdToAbsBranchId (input ^. #branchId2)
|
||||
|
||||
patch <- do
|
||||
Cli.runTransactionWithRollback \rollback -> do
|
||||
branch1 <- Cli.resolveAbsBranchIdV2 rollback absBranchId1
|
||||
branch2 <- Cli.resolveAbsBranchIdV2 rollback absBranchId2
|
||||
branchDiff <- V2Branch.Diff.diffBranches branch1 branch2 >>= V2Branch.Diff.nameBasedDiff
|
||||
termEdits <-
|
||||
(branchDiff ^. #terms)
|
||||
& Relation.domain
|
||||
& Map.toList
|
||||
& traverse \(oldRef, newRefs) -> makeTermEdit codebase oldRef newRefs
|
||||
pure
|
||||
Patch
|
||||
{ _termEdits =
|
||||
termEdits
|
||||
& catMaybes
|
||||
& Relation.fromList,
|
||||
_typeEdits =
|
||||
(branchDiff ^. #types)
|
||||
& Relation.domain
|
||||
& Map.toList
|
||||
& mapMaybe (\(oldRef, newRefs) -> makeTypeEdit oldRef newRefs)
|
||||
& Relation.fromList
|
||||
}
|
||||
|
||||
-- Display the patch that we are about to create.
|
||||
suffixifiedPPE <- PPED.suffixifiedPPE <$> Cli.currentPrettyPrintEnvDecl
|
||||
Cli.respondNumbered (ListEdits patch suffixifiedPPE)
|
||||
|
||||
(patchPath, patchName) <- Cli.resolveSplit' (input ^. #patch)
|
||||
|
||||
-- Add the patch to the in-memory root branch and flush it all to SQLite.
|
||||
-- If there's already a patch at the given path, overwrite it.
|
||||
Cli.stepAtM
|
||||
description
|
||||
(Path.unabsolute patchPath, Branch.modifyPatches patchName (const patch))
|
||||
where
|
||||
-- Given {old reference} and {new references}, create term edit patch entries as follows:
|
||||
--
|
||||
-- * If the {new references} is a singleton set {new reference}, proceed. (Otherwise, the patch we might create
|
||||
-- would not be a function, which is a bogus/conflicted patch).
|
||||
-- * Look up {old reference} and {new reference} types in the codebase (which can technically fail, due to
|
||||
-- non-transactionality of this command, though we don't typically delete anything from SQLite), and create a
|
||||
-- patch entry that maps {old reference} to {new reference} with the typing relationship.
|
||||
makeTermEdit ::
|
||||
Codebase m Symbol Ann ->
|
||||
V2.Reference ->
|
||||
Set V2.Reference ->
|
||||
Sqlite.Transaction (Maybe (Reference, TermEdit))
|
||||
makeTermEdit codebase (Conversions.reference2to1 -> oldRef) newRefs =
|
||||
runMaybeT do
|
||||
newRef <- Conversions.reference2to1 <$> MaybeT (pure (Set.asSingleton newRefs))
|
||||
oldRefType <- MaybeT (Codebase.getTypeOfTerm codebase oldRef)
|
||||
newRefType <- MaybeT (Codebase.getTypeOfTerm codebase newRef)
|
||||
pure (oldRef, TermEdit.Replace newRef (TermEdit.typing oldRefType newRefType))
|
||||
|
||||
-- Same idea as 'makeTermEdit', but simpler, because there's nothing to look up in the database.
|
||||
makeTypeEdit :: V2.Reference -> Set V2.Reference -> Maybe (Reference, TypeEdit)
|
||||
makeTypeEdit (Conversions.reference2to1 -> oldRef) newRefs =
|
||||
Set.asSingleton newRefs <&> \newRef -> (oldRef, TypeEdit.Replace (Conversions.reference2to1 newRef))
|
||||
|
||||
-- | Handle a @ShowDefinitionI@ input command, i.e. `view` or `edit`.
|
||||
handleShowDefinition :: OutputLocation -> ShowDefinitionScope -> NonEmpty (HQ.HashQualified Name) -> Cli ()
|
||||
handleShowDefinition outputLoc showDefinitionScope query = do
|
||||
@ -2205,15 +1886,6 @@ addWatch watchName (Just uf) = do
|
||||
)
|
||||
_ -> addWatch watchName Nothing
|
||||
|
||||
hqNameQuery :: Names.SearchType -> [HQ.HashQualified Name] -> Cli QueryResult
|
||||
hqNameQuery searchType query = do
|
||||
Cli.Env {codebase} <- ask
|
||||
names <- Cli.currentNames
|
||||
Cli.runTransaction do
|
||||
hqLength <- Codebase.hashLength
|
||||
let nameSearch = NameSearch.makeNameSearch hqLength names
|
||||
Backend.hqNameQuery codebase nameSearch searchType query
|
||||
|
||||
looseCodeOrProjectToPath :: Either Path' (ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch) -> Path'
|
||||
looseCodeOrProjectToPath = \case
|
||||
Left pth -> pth
|
||||
|
@ -1,7 +1,6 @@
|
||||
module Unison.Codebase.Editor.Input
|
||||
( Input (..),
|
||||
BranchSourceI (..),
|
||||
DiffNamespaceToPatchInput (..),
|
||||
GistInput (..),
|
||||
PullSourceTarget (..),
|
||||
PushRemoteBranchInput (..),
|
||||
@ -142,8 +141,6 @@ data Input
|
||||
MoveTermI Path.HQSplit' Path.Split'
|
||||
| MoveTypeI Path.HQSplit' Path.Split'
|
||||
| MoveBranchI Path.Path' Path.Path'
|
||||
| MovePatchI Path.Split' Path.Split'
|
||||
| CopyPatchI Path.Split' Path.Split'
|
||||
| -- delete = unname
|
||||
DeleteI DeleteTarget
|
||||
| -- edits stuff:
|
||||
@ -155,14 +152,6 @@ data Input
|
||||
| Update2I
|
||||
| PreviewUpdateI (Set Name)
|
||||
| TodoI (Maybe PatchPath) Path'
|
||||
| PropagatePatchI PatchPath Path'
|
||||
| ListEditsI (Maybe PatchPath)
|
||||
| -- -- create and remove update directives
|
||||
DeprecateTermI PatchPath Path.HQSplit'
|
||||
| DeprecateTypeI PatchPath Path.HQSplit'
|
||||
| ReplaceI (HQ.HashQualified Name) (HQ.HashQualified Name) (Maybe PatchPath)
|
||||
| RemoveTermReplacementI (HQ.HashQualified Name) (Maybe PatchPath)
|
||||
| RemoveTypeReplacementI (HQ.HashQualified Name) (Maybe PatchPath)
|
||||
| UndoI
|
||||
| -- First `Maybe Int` is cap on number of results, if any
|
||||
-- Second `Maybe Int` is cap on diff elements shown, if any
|
||||
@ -190,7 +179,6 @@ data Input
|
||||
| -- other
|
||||
FindI Bool FindScope [String] -- FindI isVerbose findScope query
|
||||
| FindShallowI Path'
|
||||
| FindPatchI
|
||||
| StructuredFindI FindScope (HQ.HashQualified Name) -- sfind findScope query
|
||||
| StructuredFindReplaceI (HQ.HashQualified Name) -- sfind.replace rewriteQuery
|
||||
| -- Show provided definitions.
|
||||
@ -225,7 +213,6 @@ data Input
|
||||
| GistI GistInput
|
||||
| AuthLoginI
|
||||
| VersionI
|
||||
| DiffNamespaceToPatchI DiffNamespaceToPatchInput
|
||||
| ProjectCreateI Bool {- try downloading base? -} (Maybe ProjectName)
|
||||
| ProjectRenameI ProjectName
|
||||
| ProjectSwitchI ProjectAndBranchNames
|
||||
@ -252,16 +239,6 @@ data BranchSourceI
|
||||
BranchSourceI'LooseCodeOrProject LooseCodeOrProject
|
||||
deriving stock (Eq, Show)
|
||||
|
||||
data DiffNamespaceToPatchInput = DiffNamespaceToPatchInput
|
||||
{ -- The first/earlier namespace.
|
||||
branchId1 :: BranchId,
|
||||
-- The second/later namespace.
|
||||
branchId2 :: BranchId,
|
||||
-- Where to store the patch that corresponds to the diff between the namespaces.
|
||||
patch :: Path.Split'
|
||||
}
|
||||
deriving stock (Eq, Generic, Show)
|
||||
|
||||
-- | @"push.gist repo"@ pushes the contents of the current namespace to @repo@.
|
||||
data GistInput = GistInput
|
||||
{ repo :: WriteGitRepo
|
||||
@ -332,7 +309,6 @@ data DeleteTarget
|
||||
| DeleteTarget'Term DeleteOutput [Path.HQSplit']
|
||||
| DeleteTarget'Type DeleteOutput [Path.HQSplit']
|
||||
| DeleteTarget'Namespace Insistence (Maybe Path.Split)
|
||||
| DeleteTarget'Patch Path.Split'
|
||||
| DeleteTarget'ProjectBranch (ProjectAndBranch (Maybe ProjectName) ProjectBranchName)
|
||||
| DeleteTarget'Project ProjectName
|
||||
deriving stock (Eq, Show)
|
||||
|
@ -17,7 +17,6 @@ module Unison.Codebase.Editor.Output
|
||||
where
|
||||
|
||||
import Data.List.NonEmpty (NonEmpty)
|
||||
import Data.Set qualified as Set
|
||||
import Data.Set.NonEmpty (NESet)
|
||||
import Data.Time (UTCTime)
|
||||
import Network.URI (URI)
|
||||
@ -39,7 +38,6 @@ import Unison.Codebase.Editor.SlurpResult (SlurpResult (..))
|
||||
import Unison.Codebase.Editor.SlurpResult qualified as SR
|
||||
import Unison.Codebase.Editor.TodoOutput qualified as TO
|
||||
import Unison.Codebase.IntegrityCheck (IntegrityResult (..))
|
||||
import Unison.Codebase.Patch (Patch)
|
||||
import Unison.Codebase.Path (Path')
|
||||
import Unison.Codebase.Path qualified as Path
|
||||
import Unison.Codebase.PushBehavior (PushBehavior)
|
||||
@ -128,7 +126,6 @@ data NumberedOutput
|
||||
HashLength
|
||||
[(CausalHash, Names.Diff)]
|
||||
HistoryTail -- 'origin point' of this view of history.
|
||||
| ListEdits Patch PPE.PrettyPrintEnv
|
||||
| ListProjects [Sqlite.Project]
|
||||
| ListBranches ProjectName [(ProjectBranchName, [(URI, ProjectName, ProjectBranchName)])]
|
||||
| AmbiguousSwitch ProjectName (ProjectAndBranch ProjectName ProjectBranchName)
|
||||
@ -173,7 +170,6 @@ data Output
|
||||
| CreatedNewBranch Path.Absolute
|
||||
| BranchAlreadyExists Path'
|
||||
| FindNoLocalMatches
|
||||
| PatchAlreadyExists Path.Split'
|
||||
| NoExactTypeMatches
|
||||
| TypeAlreadyExists Path.Split' (Set Reference)
|
||||
| TypeParseError String (Parser.Err Symbol)
|
||||
@ -192,13 +188,11 @@ data Output
|
||||
| EmptyProjectBranchPush (ProjectAndBranch ProjectName ProjectBranchName)
|
||||
| NameNotFound Path.HQSplit'
|
||||
| NamesNotFound [Name]
|
||||
| PatchNotFound Path.Split'
|
||||
| TypeNotFound Path.HQSplit'
|
||||
| TermNotFound Path.HQSplit'
|
||||
| MoveNothingFound Path'
|
||||
| TypeNotFound' ShortHash
|
||||
| TermNotFound' ShortHash
|
||||
| TypeTermMismatch (HQ.HashQualified Name) (HQ.HashQualified Name)
|
||||
| NoLastRunResult
|
||||
| SaveTermNameConflict Name
|
||||
| SearchTermsNotFound [HQ.HashQualified Name]
|
||||
@ -231,7 +225,6 @@ data Output
|
||||
-- list of all the definitions within this branch
|
||||
| ListOfDefinitions FindScope PPE.PrettyPrintEnv ListDetailed [SearchResult' Symbol Ann]
|
||||
| ListShallow (IO PPE.PrettyPrintEnv) [ShallowListEntry Symbol Ann]
|
||||
| ListOfPatches (Set Name)
|
||||
| ListStructuredFind [HQ.HashQualified Name]
|
||||
| -- ListStructuredFind patternMatchingUsages termBodyUsages
|
||||
-- show the result of add/update
|
||||
@ -275,8 +268,6 @@ data Output
|
||||
| ConfiguredRemoteMappingParseError PushPull Path.Absolute Text String
|
||||
| TermMissingType Reference
|
||||
| AboutToPropagatePatch
|
||||
| -- todo: tell the user to run `todo` on the same patch they just used
|
||||
NothingToPatch PatchPath Path'
|
||||
| PatchNeedsToBeConflictFree
|
||||
| PatchInvolvesExternalDependents PPE.PrettyPrintEnv (Set Reference)
|
||||
| StartOfCurrentPathHistory
|
||||
@ -488,7 +479,6 @@ isFailure o = case o of
|
||||
BranchAlreadyExists {} -> True
|
||||
-- we do a global search after finding no local matches, so let's not call this a failure yet
|
||||
FindNoLocalMatches {} -> False
|
||||
PatchAlreadyExists {} -> True
|
||||
NoExactTypeMatches -> True
|
||||
BranchEmpty {} -> True
|
||||
EmptyLooseCodePush {} -> True
|
||||
@ -508,13 +498,11 @@ isFailure o = case o of
|
||||
BranchNotFound {} -> True
|
||||
NameNotFound {} -> True
|
||||
NamesNotFound _ -> True
|
||||
PatchNotFound {} -> True
|
||||
TypeNotFound {} -> True
|
||||
TypeNotFound' {} -> True
|
||||
TermNotFound {} -> True
|
||||
MoveNothingFound {} -> True
|
||||
TermNotFound' {} -> True
|
||||
TypeTermMismatch {} -> True
|
||||
SearchTermsNotFound ts -> not (null ts)
|
||||
SearchTermsNotFoundDetailed _ misses otherHits -> not (null misses && null otherHits)
|
||||
DeleteBranchConfirmation {} -> False
|
||||
@ -524,7 +512,6 @@ isFailure o = case o of
|
||||
DeletedEverything -> False
|
||||
ListNames _ _ tys tms -> null tms && null tys
|
||||
ListOfDefinitions _ _ _ ds -> null ds
|
||||
ListOfPatches s -> Set.null s
|
||||
ListStructuredFind tms -> null tms
|
||||
SlurpOutput _ _ sr -> not $ SR.isOk sr
|
||||
ParseErrors {} -> True
|
||||
@ -549,7 +536,6 @@ isFailure o = case o of
|
||||
PatchNeedsToBeConflictFree {} -> True
|
||||
PatchInvolvesExternalDependents {} -> True
|
||||
AboutToPropagatePatch {} -> False
|
||||
NothingToPatch {} -> False
|
||||
StartOfCurrentPathHistory -> True
|
||||
NotImplemented -> True
|
||||
DumpNumberedArgs {} -> False
|
||||
@ -662,7 +648,6 @@ isNumberedFailure = \case
|
||||
DeletedDespiteDependents {} -> False
|
||||
History {} -> False
|
||||
ListBranches {} -> False
|
||||
ListEdits {} -> False
|
||||
ListProjects {} -> False
|
||||
ShowDiffAfterCreateAuthor {} -> False
|
||||
ShowDiffAfterDeleteBranch {} -> False
|
||||
|
@ -19,7 +19,6 @@ module Unison.CommandLine.InputPatterns
|
||||
clear,
|
||||
clone,
|
||||
compileScheme,
|
||||
copyPatch,
|
||||
createAuthor,
|
||||
debugClearWatchCache,
|
||||
debugDoctor,
|
||||
@ -39,19 +38,15 @@ module Unison.CommandLine.InputPatterns
|
||||
deleteBranch,
|
||||
deleteNamespace,
|
||||
deleteNamespaceForce,
|
||||
deletePatch,
|
||||
deleteProject,
|
||||
deleteTerm,
|
||||
deleteTermReplacement,
|
||||
deleteTermVerbose,
|
||||
deleteType,
|
||||
deleteTypeReplacement,
|
||||
deleteTypeVerbose,
|
||||
deleteVerbose,
|
||||
dependencies,
|
||||
dependents,
|
||||
diffNamespace,
|
||||
diffNamespaceToPatch,
|
||||
display,
|
||||
displayTo,
|
||||
docToMarkdown,
|
||||
@ -65,7 +60,6 @@ module Unison.CommandLine.InputPatterns
|
||||
findGlobal,
|
||||
findIn,
|
||||
findInAll,
|
||||
findPatch,
|
||||
findShallow,
|
||||
findVerbose,
|
||||
findVerboseAll,
|
||||
@ -88,7 +82,6 @@ module Unison.CommandLine.InputPatterns
|
||||
moveAll,
|
||||
names,
|
||||
namespaceDependencies,
|
||||
patch,
|
||||
previewAdd,
|
||||
previewUpdate,
|
||||
printVersion,
|
||||
@ -106,10 +99,8 @@ module Unison.CommandLine.InputPatterns
|
||||
quit,
|
||||
releaseDraft,
|
||||
renameBranch,
|
||||
renamePatch,
|
||||
renameTerm,
|
||||
renameType,
|
||||
replace,
|
||||
reset,
|
||||
resetRoot,
|
||||
runScheme,
|
||||
@ -129,12 +120,9 @@ module Unison.CommandLine.InputPatterns
|
||||
upgrade,
|
||||
view,
|
||||
viewGlobal,
|
||||
viewPatch,
|
||||
viewReflog,
|
||||
|
||||
-- * Misc
|
||||
deleteTermReplacementCommand,
|
||||
deleteTypeReplacementCommand,
|
||||
helpFor,
|
||||
makeExample',
|
||||
makeExample,
|
||||
@ -495,45 +483,6 @@ previewUpdate =
|
||||
)
|
||||
\ws -> pure $ Input.PreviewUpdateI (Set.fromList $ map (Name.unsafeParseText . Text.pack) ws)
|
||||
|
||||
patch :: InputPattern
|
||||
patch =
|
||||
InputPattern
|
||||
"patch"
|
||||
[]
|
||||
I.Visible
|
||||
[("patch", Required, patchArg), ("namespace", Optional, namespaceArg)]
|
||||
( P.lines
|
||||
[ P.wrap $
|
||||
makeExample' patch
|
||||
<> "rewrites any definitions that depend on "
|
||||
<> "definitions with type-preserving edits to use the updated versions of"
|
||||
<> "these dependencies.",
|
||||
"",
|
||||
P.wrapColumn2
|
||||
[ ( makeExample patch ["<patch>", "[path]"],
|
||||
"applies the given patch"
|
||||
<> "to the given namespace"
|
||||
),
|
||||
( makeExample patch ["<patch>"],
|
||||
"applies the given patch"
|
||||
<> "to the current namespace"
|
||||
)
|
||||
]
|
||||
]
|
||||
)
|
||||
\case
|
||||
patchStr : ws -> first P.text do
|
||||
patch <- Path.parseSplit' patchStr
|
||||
branch <- case ws of
|
||||
[pathStr] -> Path.parsePath' pathStr
|
||||
_ -> pure Path.relativeEmpty'
|
||||
pure $ Input.PropagatePatchI patch branch
|
||||
[] ->
|
||||
Left $
|
||||
warn $
|
||||
makeExample' patch
|
||||
<> "takes a patch and an optional namespace."
|
||||
|
||||
view :: InputPattern
|
||||
view =
|
||||
InputPattern
|
||||
@ -852,18 +801,6 @@ findVerboseAll =
|
||||
)
|
||||
(pure . Input.FindI True (Input.FindLocalAndDeps Path.empty))
|
||||
|
||||
findPatch :: InputPattern
|
||||
findPatch =
|
||||
InputPattern
|
||||
"find.patch"
|
||||
["list.patch", "ls.patch"]
|
||||
I.Visible
|
||||
[]
|
||||
( P.wrapColumn2
|
||||
[("`find.patch`", "lists all patches in the current namespace.")]
|
||||
)
|
||||
(pure . const Input.FindPatchI)
|
||||
|
||||
renameTerm :: InputPattern
|
||||
renameTerm =
|
||||
InputPattern
|
||||
@ -989,54 +926,6 @@ deleteType = deleteGen (Just "type") exactDefinitionTypeQueryArg "type" (DeleteT
|
||||
deleteTypeVerbose :: InputPattern
|
||||
deleteTypeVerbose = deleteGen (Just "type.verbose") exactDefinitionTypeQueryArg "type" (DeleteTarget'Type DeleteOutput'Diff)
|
||||
|
||||
deleteTermReplacementCommand :: String
|
||||
deleteTermReplacementCommand = "delete.term-replacement"
|
||||
|
||||
deleteTypeReplacementCommand :: String
|
||||
deleteTypeReplacementCommand = "delete.type-replacement"
|
||||
|
||||
deleteReplacement :: Bool -> InputPattern
|
||||
deleteReplacement isTerm =
|
||||
InputPattern
|
||||
commandName
|
||||
[]
|
||||
I.Visible
|
||||
[("definition", Required, if isTerm then exactDefinitionTermQueryArg else exactDefinitionTypeQueryArg), ("patch", Optional, patchArg)]
|
||||
( P.string $
|
||||
commandName
|
||||
<> " <foo> <patch>` removes any edit of the "
|
||||
<> str
|
||||
<> " `foo` from the patch `patch`, "
|
||||
<> "or from the default patch if none is specified. Note that `foo` refers to the "
|
||||
<> "original name for the "
|
||||
<> str
|
||||
<> " - not the one in place after the edit."
|
||||
)
|
||||
( \case
|
||||
query : patch -> do
|
||||
patch <- first P.text . traverse Path.parseSplit' $ listToMaybe patch
|
||||
q <- parseHashQualifiedName query
|
||||
pure $ input q patch
|
||||
_ ->
|
||||
Left
|
||||
. P.warnCallout
|
||||
. P.wrapString
|
||||
$ commandName
|
||||
<> " needs arguments. See `help "
|
||||
<> commandName
|
||||
<> "`."
|
||||
)
|
||||
where
|
||||
input =
|
||||
if isTerm
|
||||
then Input.RemoveTermReplacementI
|
||||
else Input.RemoveTypeReplacementI
|
||||
str = if isTerm then "term" else "type"
|
||||
commandName =
|
||||
if isTerm
|
||||
then deleteTermReplacementCommand
|
||||
else deleteTypeReplacementCommand
|
||||
|
||||
deleteProject :: InputPattern
|
||||
deleteProject =
|
||||
InputPattern
|
||||
@ -1082,12 +971,6 @@ deleteBranch =
|
||||
branchInclusion = AllBranches
|
||||
}
|
||||
|
||||
deleteTermReplacement :: InputPattern
|
||||
deleteTermReplacement = deleteReplacement True
|
||||
|
||||
deleteTypeReplacement :: InputPattern
|
||||
deleteTypeReplacement = deleteReplacement False
|
||||
|
||||
aliasTerm :: InputPattern
|
||||
aliasTerm =
|
||||
InputPattern
|
||||
@ -1243,56 +1126,6 @@ deleteNamespaceParser helpText insistence = \case
|
||||
pure $ Input.DeleteI (DeleteTarget'Namespace insistence (Just p))
|
||||
_ -> Left helpText
|
||||
|
||||
deletePatch :: InputPattern
|
||||
deletePatch =
|
||||
InputPattern
|
||||
"delete.patch"
|
||||
[]
|
||||
I.Visible
|
||||
[("patch to delete", Required, patchArg)]
|
||||
"`delete.patch <foo>` deletes the patch `foo`"
|
||||
\case
|
||||
[p] -> first P.text do
|
||||
p <- Path.parseSplit' p
|
||||
pure . Input.DeleteI $ DeleteTarget'Patch p
|
||||
_ -> Left (I.help deletePatch)
|
||||
|
||||
movePatch :: String -> String -> Either (P.Pretty CT.ColorText) Input
|
||||
movePatch src dest = first P.text do
|
||||
src <- Path.parseSplit' src
|
||||
dest <- Path.parseSplit' dest
|
||||
pure $ Input.MovePatchI src dest
|
||||
|
||||
copyPatch' :: String -> String -> Either (P.Pretty CT.ColorText) Input
|
||||
copyPatch' src dest = first P.text do
|
||||
src <- Path.parseSplit' src
|
||||
dest <- Path.parseSplit' dest
|
||||
pure $ Input.CopyPatchI src dest
|
||||
|
||||
copyPatch :: InputPattern
|
||||
copyPatch =
|
||||
InputPattern
|
||||
"copy.patch"
|
||||
[]
|
||||
I.Visible
|
||||
[("patch to copy", Required, patchArg), ("copy destination", Required, newNameArg)]
|
||||
"`copy.patch foo bar` copies the patch `foo` to `bar`."
|
||||
\case
|
||||
[src, dest] -> copyPatch' src dest
|
||||
_ -> Left (I.help copyPatch)
|
||||
|
||||
renamePatch :: InputPattern
|
||||
renamePatch =
|
||||
InputPattern
|
||||
"move.patch"
|
||||
["rename.patch"]
|
||||
I.Visible
|
||||
[("patch", Required, patchArg), ("new location", Required, newNameArg)]
|
||||
"`move.patch foo bar` renames the patch `foo` to `bar`."
|
||||
\case
|
||||
[src, dest] -> movePatch src dest
|
||||
_ -> Left (I.help renamePatch)
|
||||
|
||||
renameBranch :: InputPattern
|
||||
renameBranch =
|
||||
InputPattern
|
||||
@ -2012,45 +1845,6 @@ mergeOldPreviewInputPattern =
|
||||
branchInclusion = AllBranches
|
||||
}
|
||||
|
||||
replaceEdit ::
|
||||
( HQ.HashQualified Name ->
|
||||
HQ.HashQualified Name ->
|
||||
Maybe Input.PatchPath ->
|
||||
Input
|
||||
) ->
|
||||
InputPattern
|
||||
replaceEdit f = self
|
||||
where
|
||||
self =
|
||||
InputPattern
|
||||
"replace"
|
||||
[]
|
||||
I.Visible
|
||||
[ ("definition to replace", Required, definitionQueryArg),
|
||||
("definition replacement", Required, definitionQueryArg),
|
||||
("patch", Optional, patchArg)
|
||||
]
|
||||
( P.wrapColumn2
|
||||
[ ( makeExample self ["<from>", "<to>", "<patch>"],
|
||||
"Replace the term/type <from> in the given patch with the term/type <to>."
|
||||
),
|
||||
( makeExample self ["<from>", "<to>"],
|
||||
"Replace the term/type <from> with <to> in the default patch."
|
||||
)
|
||||
]
|
||||
)
|
||||
( \case
|
||||
source : target : patch -> do
|
||||
patch <- first P.text <$> traverse Path.parseSplit' $ listToMaybe patch
|
||||
sourcehq <- parseHashQualifiedName source
|
||||
targethq <- parseHashQualifiedName target
|
||||
pure $ f sourcehq targethq patch
|
||||
_ -> Left $ I.help self
|
||||
)
|
||||
|
||||
replace :: InputPattern
|
||||
replace = replaceEdit Input.ReplaceI
|
||||
|
||||
viewReflog :: InputPattern
|
||||
viewReflog =
|
||||
InputPattern
|
||||
@ -2348,29 +2142,6 @@ quit =
|
||||
[] -> pure Input.QuitI
|
||||
_ -> Left "Use `quit`, `exit`, or <Ctrl-D> to quit."
|
||||
|
||||
viewPatch :: InputPattern
|
||||
viewPatch =
|
||||
InputPattern
|
||||
"view.patch"
|
||||
[]
|
||||
I.Visible
|
||||
[("patch", Optional, patchArg)]
|
||||
( P.wrapColumn2
|
||||
[ ( makeExample' viewPatch,
|
||||
"Lists all the edits in the default patch."
|
||||
),
|
||||
( makeExample viewPatch ["<patch>"],
|
||||
"Lists all the edits in the given patch."
|
||||
)
|
||||
]
|
||||
)
|
||||
\case
|
||||
[] -> Right $ Input.ListEditsI Nothing
|
||||
[patchStr] -> mapLeft P.text do
|
||||
patch <- Path.parseSplit' patchStr
|
||||
Right $ Input.ListEditsI (Just patch)
|
||||
_ -> Left $ warn "`view.patch` takes a patch and that's it."
|
||||
|
||||
names :: Input.IsGlobal -> InputPattern
|
||||
names isGlobal =
|
||||
InputPattern
|
||||
@ -2865,24 +2636,6 @@ printVersion =
|
||||
_ -> Left (showPatternHelp printVersion)
|
||||
)
|
||||
|
||||
diffNamespaceToPatch :: InputPattern
|
||||
diffNamespaceToPatch =
|
||||
InputPattern
|
||||
{ patternName = "diff.namespace.to-patch",
|
||||
aliases = [],
|
||||
visibility = I.Visible,
|
||||
args = [],
|
||||
help = P.wrap "Create a patch from a namespace diff.",
|
||||
parse = \case
|
||||
[branchId1, branchId2, patch] ->
|
||||
mapLeft P.text do
|
||||
branchId1 <- Input.parseBranchId branchId1
|
||||
branchId2 <- Input.parseBranchId branchId2
|
||||
patch <- Path.parseSplit' patch
|
||||
pure (Input.DiffNamespaceToPatchI Input.DiffNamespaceToPatchInput {branchId1, branchId2, patch})
|
||||
_ -> Left (showPatternHelp diffNamespaceToPatch)
|
||||
}
|
||||
|
||||
projectCreate :: InputPattern
|
||||
projectCreate =
|
||||
InputPattern
|
||||
@ -3174,7 +2927,6 @@ validInputs =
|
||||
clear,
|
||||
clone,
|
||||
compileScheme,
|
||||
copyPatch,
|
||||
createAuthor,
|
||||
debugClearWatchCache,
|
||||
debugDoctor,
|
||||
@ -3195,18 +2947,14 @@ validInputs =
|
||||
deleteProject,
|
||||
deleteNamespace,
|
||||
deleteNamespaceForce,
|
||||
deletePatch,
|
||||
deleteTerm,
|
||||
deleteTermReplacement,
|
||||
deleteTermVerbose,
|
||||
deleteType,
|
||||
deleteTypeReplacement,
|
||||
deleteTypeVerbose,
|
||||
deleteVerbose,
|
||||
dependencies,
|
||||
dependents,
|
||||
diffNamespace,
|
||||
diffNamespaceToPatch,
|
||||
display,
|
||||
displayTo,
|
||||
docToMarkdown,
|
||||
@ -3220,7 +2968,6 @@ validInputs =
|
||||
findAll,
|
||||
findInAll,
|
||||
findGlobal,
|
||||
findPatch,
|
||||
findShallow,
|
||||
findVerbose,
|
||||
findVerboseAll,
|
||||
@ -3245,7 +2992,6 @@ validInputs =
|
||||
names False, -- names
|
||||
names True, -- names.global
|
||||
namespaceDependencies,
|
||||
patch,
|
||||
previewAdd,
|
||||
previewUpdate,
|
||||
printVersion,
|
||||
@ -3263,11 +3009,9 @@ validInputs =
|
||||
quit,
|
||||
releaseDraft,
|
||||
renameBranch,
|
||||
renamePatch,
|
||||
renameTerm,
|
||||
renameType,
|
||||
moveAll,
|
||||
replace,
|
||||
reset,
|
||||
resetRoot,
|
||||
runScheme,
|
||||
@ -3285,7 +3029,6 @@ validInputs =
|
||||
upgrade,
|
||||
view,
|
||||
viewGlobal,
|
||||
viewPatch,
|
||||
viewReflog
|
||||
]
|
||||
|
||||
|
@ -6,9 +6,7 @@
|
||||
module Unison.CommandLine.OutputMessages where
|
||||
|
||||
import Control.Lens hiding (at)
|
||||
import Control.Monad.State
|
||||
import Control.Monad.State.Strict qualified as State
|
||||
import Control.Monad.Writer (Writer, runWriter, tell)
|
||||
import Data.ByteString.Lazy qualified as LazyByteString
|
||||
import Data.Foldable qualified as Foldable
|
||||
import Data.List (stripPrefix)
|
||||
@ -128,7 +126,6 @@ import Unison.Server.Backend qualified as Backend
|
||||
import Unison.Server.SearchResult' qualified as SR'
|
||||
import Unison.Share.Sync qualified as Share
|
||||
import Unison.Share.Sync.Types (CodeserverTransportError (..))
|
||||
import Unison.ShortHash qualified as ShortHash
|
||||
import Unison.Sync.Types qualified as Share
|
||||
import Unison.Syntax.DeclPrinter qualified as DeclPrinter
|
||||
import Unison.Syntax.HashQualified qualified as HQ (toText, unsafeFromVar)
|
||||
@ -405,7 +402,6 @@ notifyNumbered = \case
|
||||
],
|
||||
numberedArgsForEndangerments ppeDecl endangerments
|
||||
)
|
||||
ListEdits patch ppe -> showListEdits patch ppe
|
||||
ListProjects projects ->
|
||||
( P.numberedList (map (prettyProjectName . view #name) projects),
|
||||
map (Text.unpack . into @Text . view #name) projects
|
||||
@ -551,99 +547,6 @@ undoTip =
|
||||
<> IP.makeExample' IP.viewReflog
|
||||
<> "to undo this change."
|
||||
|
||||
showListEdits :: Patch -> PPE.PrettyPrintEnv -> (P.Pretty P.ColorText, NumberedArgs)
|
||||
showListEdits patch ppe =
|
||||
( P.sepNonEmpty
|
||||
"\n\n"
|
||||
[ if null types
|
||||
then mempty
|
||||
else
|
||||
"Edited Types:"
|
||||
`P.hang` P.column2 typeOutputs,
|
||||
if null terms
|
||||
then mempty
|
||||
else
|
||||
"Edited Terms:"
|
||||
`P.hang` P.column2 termOutputs,
|
||||
if null types && null terms
|
||||
then "This patch is empty."
|
||||
else
|
||||
tip . P.string $
|
||||
"To remove entries from a patch, use "
|
||||
<> IP.deleteTermReplacementCommand
|
||||
<> " or "
|
||||
<> IP.deleteTypeReplacementCommand
|
||||
<> ", as appropriate."
|
||||
],
|
||||
numberedArgsCol1 <> numberedArgsCol2
|
||||
)
|
||||
where
|
||||
typeOutputs, termOutputs :: [(Pretty, Pretty)]
|
||||
numberedArgsCol1, numberedArgsCol2 :: NumberedArgs
|
||||
-- We use the output of the first column's count as the first number in the second
|
||||
-- column's count. Laziness allows this since they're used independently of one another.
|
||||
(((typeOutputs, termOutputs), (lastNumberInFirstColumn, _)), (numberedArgsCol1, numberedArgsCol2)) =
|
||||
runWriter . flip runStateT (1, lastNumberInFirstColumn) $ do
|
||||
typeOutputs <- traverse prettyTypeEdit types
|
||||
termOutputs <- traverse prettyTermEdit terms
|
||||
pure (typeOutputs, termOutputs)
|
||||
types :: [(Reference, TypeEdit.TypeEdit)]
|
||||
types = R.toList $ Patch._typeEdits patch
|
||||
terms :: [(Reference, TermEdit.TermEdit)]
|
||||
terms = R.toList $ Patch._termEdits patch
|
||||
showNum :: Int -> Pretty
|
||||
showNum n = P.hiBlack (P.shown n <> ". ")
|
||||
|
||||
prettyTermEdit ::
|
||||
(Reference.TermReference, TermEdit.TermEdit) ->
|
||||
StateT (Int, Int) (Writer (NumberedArgs, NumberedArgs)) (Pretty, Pretty)
|
||||
prettyTermEdit (lhsRef, termEdit) = do
|
||||
n1 <- gets fst <* modify (first succ)
|
||||
let lhsTermName = PPE.termName ppe (Referent.Ref lhsRef)
|
||||
-- We use the shortHash of the lhs rather than its name for numbered args,
|
||||
-- since its name is likely to be "historical", and won't work if passed to a ucm command.
|
||||
let lhsHash = Text.unpack . ShortHash.toText . Reference.toShortHash $ lhsRef
|
||||
case termEdit of
|
||||
TermEdit.Deprecate -> do
|
||||
lift $ tell ([lhsHash], [])
|
||||
pure
|
||||
( showNum n1 <> (P.syntaxToColor . prettyHashQualified $ lhsTermName),
|
||||
"-> (deprecated)"
|
||||
)
|
||||
TermEdit.Replace rhsRef _typing -> do
|
||||
n2 <- gets snd <* modify (second succ)
|
||||
let rhsTermName = PPE.termName ppe (Referent.Ref rhsRef)
|
||||
lift $ tell ([lhsHash], [Text.unpack (HQ.toText rhsTermName)])
|
||||
pure
|
||||
( showNum n1 <> (P.syntaxToColor . prettyHashQualified $ lhsTermName),
|
||||
"-> " <> showNum n2 <> (P.syntaxToColor . prettyHashQualified $ rhsTermName)
|
||||
)
|
||||
|
||||
prettyTypeEdit ::
|
||||
(Reference, TypeEdit.TypeEdit) ->
|
||||
StateT (Int, Int) (Writer (NumberedArgs, NumberedArgs)) (Pretty, Pretty)
|
||||
prettyTypeEdit (lhsRef, typeEdit) = do
|
||||
n1 <- gets fst <* modify (first succ)
|
||||
let lhsTypeName = PPE.typeName ppe lhsRef
|
||||
-- We use the shortHash of the lhs rather than its name for numbered args,
|
||||
-- since its name is likely to be "historical", and won't work if passed to a ucm command.
|
||||
let lhsHash = Text.unpack . ShortHash.toText . Reference.toShortHash $ lhsRef
|
||||
case typeEdit of
|
||||
TypeEdit.Deprecate -> do
|
||||
lift $ tell ([lhsHash], [])
|
||||
pure
|
||||
( showNum n1 <> (P.syntaxToColor . prettyHashQualified $ lhsTypeName),
|
||||
"-> (deprecated)"
|
||||
)
|
||||
TypeEdit.Replace rhsRef -> do
|
||||
n2 <- gets snd <* modify (second succ)
|
||||
let rhsTypeName = PPE.typeName ppe rhsRef
|
||||
lift $ tell ([lhsHash], [Text.unpack (HQ.toText rhsTypeName)])
|
||||
pure
|
||||
( showNum n1 <> (P.syntaxToColor . prettyHashQualified $ lhsTypeName),
|
||||
"-> " <> showNum n2 <> (P.syntaxToColor . prettyHashQualified $ rhsTypeName)
|
||||
)
|
||||
|
||||
notifyUser :: FilePath -> Output -> IO Pretty
|
||||
notifyUser dir = \case
|
||||
SaveTermNameConflict name ->
|
||||
@ -782,13 +685,6 @@ notifyUser dir = \case
|
||||
<> " by someone else. Trying your command again might fix it."
|
||||
]
|
||||
EvaluationFailure err -> pure err
|
||||
TypeTermMismatch typeName termName ->
|
||||
pure $
|
||||
P.warnCallout "I was expecting either two types or two terms but was given a type "
|
||||
<> P.syntaxToColor (prettyHashQualified typeName)
|
||||
<> " and a term "
|
||||
<> P.syntaxToColor (prettyHashQualified termName)
|
||||
<> "."
|
||||
SearchTermsNotFound hqs | null hqs -> pure mempty
|
||||
SearchTermsNotFound hqs ->
|
||||
pure $
|
||||
@ -814,8 +710,6 @@ notifyUser dir = \case
|
||||
P.warnCallout typeOrTermMsg
|
||||
<> P.newline
|
||||
<> P.syntaxToColor (P.indent " " (P.lines (prettyHashQualified <$> otherHits)))
|
||||
PatchNotFound _ ->
|
||||
pure . P.warnCallout $ "I don't know about that patch."
|
||||
NameNotFound _ ->
|
||||
pure . P.warnCallout $ "I don't know about that name."
|
||||
NamesNotFound hqs ->
|
||||
@ -833,8 +727,6 @@ notifyUser dir = \case
|
||||
pure . P.warnCallout $ "A term by that name already exists."
|
||||
TypeAlreadyExists _ _ ->
|
||||
pure . P.warnCallout $ "A type by that name already exists."
|
||||
PatchAlreadyExists _ ->
|
||||
pure . P.warnCallout $ "A patch by that name already exists."
|
||||
BranchEmpty b ->
|
||||
pure . P.warnCallout . P.wrap $
|
||||
P.group (prettyWhichBranchEmpty b) <> "is an empty namespace."
|
||||
@ -1356,17 +1248,6 @@ notifyUser dir = \case
|
||||
"You're missing:" `P.hang` P.lines (fmap (P.text . Reference.toText) new),
|
||||
"I'm missing:" `P.hang` P.lines (fmap (P.text . Reference.toText) old)
|
||||
]
|
||||
ListOfPatches patches ->
|
||||
pure $
|
||||
if null patches
|
||||
then P.lit "nothing to show"
|
||||
else numberedPatches patches
|
||||
where
|
||||
numberedPatches :: Set Name -> Pretty
|
||||
numberedPatches patches =
|
||||
(P.column2 . fmap format) ([(1 :: Integer) ..] `zip` (toList patches))
|
||||
where
|
||||
format (i, p) = (P.hiBlack . fromString $ show i <> ".", prettyName p)
|
||||
NoConfiguredRemoteMapping pp p -> do
|
||||
let (localPathExample, sharePathExample) =
|
||||
if Path.isRoot p
|
||||
@ -1500,12 +1381,6 @@ notifyUser dir = \case
|
||||
"I could't find a type with hash "
|
||||
<> (prettyShortHash sh)
|
||||
AboutToPropagatePatch -> pure "Applying changes from patch..."
|
||||
NothingToPatch _patchPath dest ->
|
||||
pure $
|
||||
P.callout "😶" . P.wrap $
|
||||
"This had no effect. Perhaps the patch has already been applied"
|
||||
<> "or it doesn't intersect with the definitions in"
|
||||
<> P.group (prettyPath' dest <> ".")
|
||||
PatchNeedsToBeConflictFree ->
|
||||
pure . P.wrap $
|
||||
"I tried to auto-apply the patch, but couldn't because it contained"
|
||||
|
@ -1,58 +0,0 @@
|
||||
# Replace with terms and types
|
||||
|
||||
Let's set up some definitions to start:
|
||||
|
||||
```ucm:hide
|
||||
.lib> builtins.merge
|
||||
```
|
||||
|
||||
```unison
|
||||
x = 1
|
||||
y = 2
|
||||
|
||||
structural type X = One Nat
|
||||
structural type Y = Two Nat Nat
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
```
|
||||
|
||||
Test that replace works with terms
|
||||
```ucm
|
||||
.> replace x y
|
||||
.> view x
|
||||
```
|
||||
|
||||
Test that replace works with types
|
||||
```ucm
|
||||
.> replace X Y
|
||||
.> find
|
||||
.> view.patch patch
|
||||
.> view X
|
||||
```
|
||||
|
||||
Try with a type/term mismatch
|
||||
```ucm:error
|
||||
.> replace X x
|
||||
```
|
||||
```ucm:error
|
||||
.> replace y Y
|
||||
```
|
||||
|
||||
Try with missing references
|
||||
```ucm:error
|
||||
.> replace X NOPE
|
||||
```
|
||||
```ucm:error
|
||||
.> replace y nope
|
||||
```
|
||||
```ucm:error
|
||||
.> replace nope X
|
||||
```
|
||||
```ucm:error
|
||||
.> replace nope y
|
||||
```
|
||||
```ucm:error
|
||||
.> replace nope nope
|
||||
```
|
@ -1,146 +0,0 @@
|
||||
# Replace with terms and types
|
||||
|
||||
Let's set up some definitions to start:
|
||||
|
||||
```unison
|
||||
x = 1
|
||||
y = 2
|
||||
|
||||
structural type X = One Nat
|
||||
structural type Y = Two Nat Nat
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
structural type X
|
||||
structural type Y
|
||||
x : Nat
|
||||
y : Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
structural type X
|
||||
structural type Y
|
||||
x : Nat
|
||||
y : Nat
|
||||
|
||||
```
|
||||
Test that replace works with terms
|
||||
```ucm
|
||||
.> replace x y
|
||||
|
||||
Done.
|
||||
|
||||
.> view x
|
||||
|
||||
x : Nat
|
||||
x = 2
|
||||
|
||||
```
|
||||
Test that replace works with types
|
||||
```ucm
|
||||
.> replace X Y
|
||||
|
||||
Done.
|
||||
|
||||
.> find
|
||||
|
||||
1. structural type X
|
||||
2. x : Nat
|
||||
3. X.One : Nat -> Nat -> X
|
||||
4. structural type Y
|
||||
5. y : Nat
|
||||
6. Y.Two : Nat -> Nat -> X
|
||||
|
||||
|
||||
.> view.patch patch
|
||||
|
||||
Edited Types: 1. #68k40ra7l7 -> 3. X
|
||||
|
||||
Edited Terms: 2. #gjmq673r1v -> 4. x
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
.> view X
|
||||
|
||||
structural type X = One Nat Nat
|
||||
|
||||
```
|
||||
Try with a type/term mismatch
|
||||
```ucm
|
||||
.> replace X x
|
||||
|
||||
⚠️
|
||||
|
||||
I was expecting either two types or two terms but was given a type X and a term x.
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> replace y Y
|
||||
|
||||
⚠️
|
||||
|
||||
I was expecting either two types or two terms but was given a type Y and a term y.
|
||||
|
||||
```
|
||||
Try with missing references
|
||||
```ucm
|
||||
.> replace X NOPE
|
||||
|
||||
⚠️
|
||||
|
||||
The following names were not found in the codebase. Check your spelling.
|
||||
NOPE
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> replace y nope
|
||||
|
||||
⚠️
|
||||
|
||||
The following names were not found in the codebase. Check your spelling.
|
||||
nope
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> replace nope X
|
||||
|
||||
⚠️
|
||||
|
||||
The following names were not found in the codebase. Check your spelling.
|
||||
nope
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> replace nope y
|
||||
|
||||
⚠️
|
||||
|
||||
The following names were not found in the codebase. Check your spelling.
|
||||
nope
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> replace nope nope
|
||||
|
||||
⚠️
|
||||
|
||||
The following names were not found in the codebase. Check your spelling.
|
||||
nope
|
||||
nope
|
||||
|
||||
```
|
@ -1,42 +0,0 @@
|
||||
# Test that copying a patch works as expected
|
||||
|
||||
```unison:hide
|
||||
x = 1
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
```
|
||||
|
||||
Change the definition of `x` so something goes in our patch:
|
||||
|
||||
```unison:hide
|
||||
x = 2
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> update.old foo.patch
|
||||
```
|
||||
|
||||
Copy the patch and make sure it's still there.
|
||||
|
||||
```ucm
|
||||
.> copy.patch foo.patch bar.patch
|
||||
.> ls foo
|
||||
.> view.patch foo.patch
|
||||
.> ls bar
|
||||
.> view.patch bar.patch
|
||||
```
|
||||
|
||||
Now move the patch.
|
||||
|
||||
```ucm
|
||||
.> move.patch foo.patch qux.patch
|
||||
```
|
||||
|
||||
The moved patch should be gone.
|
||||
|
||||
```ucm:error
|
||||
.> view.patch foo.patch
|
||||
.> ls foo
|
||||
```
|
@ -1,80 +0,0 @@
|
||||
# Test that copying a patch works as expected
|
||||
|
||||
```unison
|
||||
x = 1
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
x : ##Nat
|
||||
|
||||
```
|
||||
Change the definition of `x` so something goes in our patch:
|
||||
|
||||
```unison
|
||||
x = 2
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> update.old foo.patch
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
x : ##Nat
|
||||
|
||||
```
|
||||
Copy the patch and make sure it's still there.
|
||||
|
||||
```ucm
|
||||
.> copy.patch foo.patch bar.patch
|
||||
|
||||
Done.
|
||||
|
||||
.> ls foo
|
||||
|
||||
1. patch (patch)
|
||||
|
||||
.> view.patch foo.patch
|
||||
|
||||
Edited Terms: 1. #gjmq673r1v -> 2. x
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
.> ls bar
|
||||
|
||||
1. patch (patch)
|
||||
|
||||
.> view.patch bar.patch
|
||||
|
||||
Edited Terms: 1. #gjmq673r1v -> 2. x
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
```
|
||||
Now move the patch.
|
||||
|
||||
```ucm
|
||||
.> move.patch foo.patch qux.patch
|
||||
|
||||
Done.
|
||||
|
||||
```
|
||||
The moved patch should be gone.
|
||||
|
||||
```ucm
|
||||
.> view.patch foo.patch
|
||||
|
||||
This patch is empty.
|
||||
|
||||
.> ls foo
|
||||
|
||||
nothing to show
|
||||
|
||||
```
|
@ -1,94 +0,0 @@
|
||||
# Deleting term and type replacements from patches
|
||||
|
||||
```unison
|
||||
x = 1
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
```
|
||||
|
||||
```unison
|
||||
x = 2
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> update.old
|
||||
.> view.patch
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> delete.term-replacement 1
|
||||
.> view.patch
|
||||
```
|
||||
|
||||
```unison
|
||||
unique[a] type Foo = Foo
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
```
|
||||
|
||||
```unison
|
||||
unique[b] type Foo = Foo | Bar
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> update.old
|
||||
.> view.patch
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> delete.type-replacement 1
|
||||
.> view.patch
|
||||
```
|
||||
|
||||
```unison
|
||||
bar = 3
|
||||
unique[aa] type bar = Foo
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
```
|
||||
|
||||
```unison
|
||||
unique[bb] type bar = Foo | Bar
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> update.old
|
||||
.> view.patch
|
||||
.> delete.type-replacement 1
|
||||
.> view.patch
|
||||
```
|
||||
|
||||
we get an error when attempting to delete something that is neither a type nor a term
|
||||
```ucm:error
|
||||
.> view.patch
|
||||
.> delete.type-replacement notHere
|
||||
.> view.patch
|
||||
```
|
||||
|
||||
When attempting to delete a type/term that doesn't exist, but a term/type exists
|
||||
with that name, alert the user.
|
||||
```unison
|
||||
baz = 0
|
||||
```
|
||||
|
||||
```ucm:error
|
||||
.> add baz
|
||||
.> delete.type-replacement baz
|
||||
.> view.patch
|
||||
```
|
||||
|
||||
```unison
|
||||
unique type qux = Qux
|
||||
```
|
||||
|
||||
```ucm:error
|
||||
.> add qux
|
||||
.> delete.term-replacement qux
|
||||
.> view.patch
|
||||
```
|
@ -1,302 +0,0 @@
|
||||
# Deleting term and type replacements from patches
|
||||
|
||||
```unison
|
||||
x = 1
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
x : ##Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
x : ##Nat
|
||||
|
||||
```
|
||||
```unison
|
||||
x = 2
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These names already exist. You can `update` them to your
|
||||
new definition:
|
||||
|
||||
x : ##Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> update.old
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
x : ##Nat
|
||||
|
||||
.> view.patch
|
||||
|
||||
Edited Terms: 1. #gjmq673r1v -> 2. x
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> delete.term-replacement 1
|
||||
|
||||
Done.
|
||||
|
||||
.> view.patch
|
||||
|
||||
This patch is empty.
|
||||
|
||||
```
|
||||
```unison
|
||||
unique[a] type Foo = Foo
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
type Foo
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
type Foo
|
||||
|
||||
```
|
||||
```unison
|
||||
unique[b] type Foo = Foo | Bar
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These names already exist. You can `update` them to your
|
||||
new definition:
|
||||
|
||||
type Foo
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> update.old
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
type Foo
|
||||
|
||||
.> view.patch
|
||||
|
||||
Edited Types: 1. #ool30cf4ma -> 2. Foo
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> delete.type-replacement 1
|
||||
|
||||
Done.
|
||||
|
||||
.> view.patch
|
||||
|
||||
This patch is empty.
|
||||
|
||||
```
|
||||
```unison
|
||||
bar = 3
|
||||
unique[aa] type bar = Foo
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
type bar
|
||||
bar : ##Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
type bar
|
||||
bar : ##Nat
|
||||
|
||||
```
|
||||
```unison
|
||||
unique[bb] type bar = Foo | Bar
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These names already exist. You can `update` them to your
|
||||
new definition:
|
||||
|
||||
type bar
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> update.old
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
type bar
|
||||
|
||||
.> view.patch
|
||||
|
||||
Edited Types: 1. #evhqg163jj -> 2. bar
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
.> delete.type-replacement 1
|
||||
|
||||
Done.
|
||||
|
||||
.> view.patch
|
||||
|
||||
This patch is empty.
|
||||
|
||||
```
|
||||
we get an error when attempting to delete something that is neither a type nor a term
|
||||
```ucm
|
||||
.> view.patch
|
||||
|
||||
This patch is empty.
|
||||
|
||||
.> delete.type-replacement notHere
|
||||
|
||||
⚠️
|
||||
|
||||
The following names were not found in the codebase. Check your spelling.
|
||||
notHere
|
||||
|
||||
.> view.patch
|
||||
|
||||
This patch is empty.
|
||||
|
||||
```
|
||||
When attempting to delete a type/term that doesn't exist, but a term/type exists
|
||||
with that name, alert the user.
|
||||
```unison
|
||||
baz = 0
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
baz : ##Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add baz
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
baz : ##Nat
|
||||
|
||||
.> delete.type-replacement baz
|
||||
|
||||
⚠️
|
||||
|
||||
I was expecting the following names to be types, though I found terms instead.
|
||||
baz
|
||||
|
||||
.> view.patch
|
||||
|
||||
This patch is empty.
|
||||
|
||||
```
|
||||
```unison
|
||||
unique type qux = Qux
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
type qux
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add qux
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
type qux
|
||||
|
||||
.> delete.term-replacement qux
|
||||
|
||||
⚠️
|
||||
|
||||
I was expecting the following names to be terms, though I found types instead.
|
||||
qux
|
||||
|
||||
.> view.patch
|
||||
|
||||
This patch is empty.
|
||||
|
||||
```
|
@ -1,43 +0,0 @@
|
||||
We can create a patch from the diff between two namespaces.
|
||||
|
||||
```ucm:hide
|
||||
.> builtins.merge
|
||||
```
|
||||
|
||||
```unison:hide
|
||||
one.a = 1
|
||||
one.b = 2
|
||||
oneconflicts.b = 20
|
||||
one.c = 3
|
||||
one.d = 4
|
||||
one.e = 4
|
||||
|
||||
two.a = 100
|
||||
two.b = 200
|
||||
two.c = 300
|
||||
twoconflicts.c = 30
|
||||
two.d = 5
|
||||
two.e = 6
|
||||
```
|
||||
|
||||
```ucm:hide
|
||||
.> add
|
||||
.> merge.old oneconflicts one
|
||||
.> merge.old twoconflicts two
|
||||
.> delete.namespace oneconflicts
|
||||
.> delete.namespace twoconflicts
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> find one.
|
||||
.> find two.
|
||||
.> diff.namespace.to-patch one two thepatch
|
||||
```
|
||||
|
||||
A summary of the diff:
|
||||
|
||||
* `one.a` -> `two.a` is a normal update.
|
||||
* Even though `one.b` is conflicted, both `one.b#hash1` and `one.b#hash2` get mapped to `two.b`.
|
||||
* Because `two.c` is conflicted, `one.c` doesn't end up on the left-hand side of the patch.
|
||||
* Because `one.d` and `one.e` are aliases, they don't end up on the left-hand side of the patch.
|
||||
* Neither `one.f` nor `two.g` end up in the patch because the names `f` and `g` are not common to both namespaces.
|
@ -24,7 +24,7 @@ two.e = 6
|
||||
3. one.b#dcg : Nat
|
||||
4. one.c : Nat
|
||||
5. one.d : Nat
|
||||
|
||||
|
||||
|
||||
.> find two.
|
||||
|
||||
@ -34,24 +34,18 @@ two.e = 6
|
||||
4. two.c#qpo : Nat
|
||||
5. two.d : Nat
|
||||
6. two.e : Nat
|
||||
|
||||
|
||||
|
||||
.> diff.namespace.to-patch one two thepatch
|
||||
|
||||
Edited Terms:
|
||||
1. one.b#cp6ri8mtg0 -> 4. two.b
|
||||
2. one.b#dcgdua2lj6 -> 5. two.b
|
||||
3. one.a -> 6. two.a
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
```
|
||||
A summary of the diff:
|
||||
|
||||
* `one.a` -> `two.a` is a normal update.
|
||||
* Even though `one.b` is conflicted, both `one.b#hash1` and `one.b#hash2` get mapped to `two.b`.
|
||||
* Because `two.c` is conflicted, `one.c` doesn't end up on the left-hand side of the patch.
|
||||
* Because `one.d` and `one.e` are aliases, they don't end up on the left-hand side of the patch.
|
||||
* Neither `one.f` nor `two.g` end up in the patch because the names `f` and `g are not common to both namespaces.
|
||||
|
||||
|
||||
🛑
|
||||
|
||||
The transcript failed due to an error in the stanza above. The error is:
|
||||
|
||||
⚠️
|
||||
I don't know how to diff.namespace.to-patch. Type `help` or `?`
|
||||
to get help.
|
||||
|
@ -299,323 +299,16 @@ unique type Y a b = Y a b
|
||||
|
||||
.> view.patch ns2.patch
|
||||
|
||||
Edited Terms:
|
||||
1. ns1.b -> 3. ns2.b
|
||||
2. ns1.fromJust' -> 4. ns2.fromJust
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
.> fork ns2 ns3
|
||||
|
||||
Done.
|
||||
|
||||
.> alias.term ns2.fromJust' ns2.yoohoo
|
||||
|
||||
Done.
|
||||
|
||||
.> delete.term.verbose ns2.fromJust'
|
||||
|
||||
Name changes:
|
||||
|
||||
Original Changes
|
||||
1. ns2.fromJust ┐ 2. ns2.fromJust' (removed)
|
||||
3. ns2.fromJust' │
|
||||
4. ns2.yoohoo │
|
||||
5. ns3.fromJust │
|
||||
6. ns3.fromJust' ┘
|
||||
|
||||
Tip: You can use `undo` or `reflog` to undo this change.
|
||||
|
||||
.> diff.namespace ns3 ns2
|
||||
|
||||
Name changes:
|
||||
|
||||
Original Changes
|
||||
1. fromJust ┐ 2. yoohoo (added)
|
||||
3. fromJust' ┘ 4. fromJust' (removed)
|
||||
|
||||
```
|
||||
```unison
|
||||
bdependent = "banana"
|
||||
```
|
||||
|
||||
```ucm
|
||||
.ns3> update.old
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
bdependent : ##Text
|
||||
|
||||
.> diff.namespace ns2 ns3
|
||||
|
||||
Updates:
|
||||
|
||||
1. bdependent : Nat
|
||||
↓
|
||||
2. bdependent : Text
|
||||
|
||||
3. patch patch (added 1 updates)
|
||||
|
||||
Name changes:
|
||||
|
||||
Original Changes
|
||||
4. fromJust ┐ 5. fromJust' (added)
|
||||
6. yoohoo ┘ 7. yoohoo (removed)
|
||||
|
||||
```
|
||||
## Two different auto-propagated changes creating a name conflict
|
||||
Currently, the auto-propagated name-conflicted definitions are not explicitly
|
||||
shown, only their also-conflicted dependency is shown.
|
||||
```unison
|
||||
a = 333
|
||||
b = a + 1
|
||||
.ns2> update.old.> diff.namespace ns1 ns2.> alias.term ns2.d ns2.d'.> alias.type ns2.A ns2.A'.> alias.type ns2.X ns2.X'.> diff.namespace ns1 ns2.> alias.type ns1.X ns1.X2.> alias.type ns2.A' ns2.A''.> view.patch ns2.patch.> fork ns2 ns3.> alias.term ns2.fromJust' ns2.yoohoo.> delete.term.verbose ns2.fromJust'.> diff.namespace ns3 ns2
|
||||
```
|
||||
|
||||
```ucm
|
||||
☝️ The namespace .nsx is empty.
|
||||
|
||||
.nsx> add
|
||||
🛑
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
a : ##Nat
|
||||
b : ##Nat
|
||||
The transcript failed due to an error in the stanza above. The error is:
|
||||
|
||||
.> fork nsx nsy
|
||||
|
||||
Done.
|
||||
|
||||
.> fork nsx nsz
|
||||
|
||||
Done.
|
||||
|
||||
```
|
||||
```unison
|
||||
a = 444
|
||||
```
|
||||
|
||||
```ucm
|
||||
.nsy> update.old
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
a : ##Nat
|
||||
|
||||
```
|
||||
```unison
|
||||
a = 555
|
||||
```
|
||||
|
||||
```ucm
|
||||
.nsz> update.old
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
a : ##Nat
|
||||
|
||||
.> merge.old nsy nsw
|
||||
|
||||
Here's what's changed in nsw after the merge:
|
||||
|
||||
Added definitions:
|
||||
|
||||
1. a : Nat
|
||||
2. b : Nat
|
||||
|
||||
3. patch patch (added 1 updates)
|
||||
|
||||
Tip: You can use `todo` to see if this generated any work to
|
||||
do in this namespace and `test` to run the tests. Or you
|
||||
can use `undo` or `reflog` to undo the results of this
|
||||
merge.
|
||||
|
||||
Applying changes from patch...
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> merge.old nsz nsw
|
||||
|
||||
Here's what's changed in nsw after the merge:
|
||||
|
||||
New name conflicts:
|
||||
|
||||
1. a#mdl4vqtu00 : Nat
|
||||
↓
|
||||
2. ┌ a#mdl4vqtu00 : Nat
|
||||
3. └ a#vrs8gtkl2t : Nat
|
||||
|
||||
4. b#unkqhuu66p : Nat
|
||||
↓
|
||||
5. ┌ b#aapqletas7 : Nat
|
||||
6. └ b#unkqhuu66p : Nat
|
||||
|
||||
Updates:
|
||||
|
||||
7. patch patch (added 1 updates)
|
||||
|
||||
Tip: You can use `todo` to see if this generated any work to
|
||||
do in this namespace and `test` to run the tests. Or you
|
||||
can use `undo` or `reflog` to undo the results of this
|
||||
merge.
|
||||
|
||||
Applying changes from patch...
|
||||
|
||||
I tried to auto-apply the patch, but couldn't because it
|
||||
contained contradictory entries.
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> diff.namespace nsx nsw
|
||||
|
||||
New name conflicts:
|
||||
|
||||
1. a#uiiiv8a86s : Nat
|
||||
↓
|
||||
2. ┌ a#mdl4vqtu00 : Nat
|
||||
3. └ a#vrs8gtkl2t : Nat
|
||||
|
||||
4. b#lhigeb1let : Nat
|
||||
↓
|
||||
5. ┌ b#aapqletas7 : Nat
|
||||
6. └ b#unkqhuu66p : Nat
|
||||
|
||||
Added definitions:
|
||||
|
||||
7. patch patch (added 2 updates)
|
||||
|
||||
.nsw> view a b
|
||||
|
||||
a#mdl4vqtu00 : ##Nat
|
||||
a#mdl4vqtu00 = 444
|
||||
|
||||
a#vrs8gtkl2t : ##Nat
|
||||
a#vrs8gtkl2t = 555
|
||||
|
||||
b#aapqletas7 : ##Nat
|
||||
b#aapqletas7 = ##Nat.+ a#vrs8gtkl2t 1
|
||||
|
||||
b#unkqhuu66p : ##Nat
|
||||
b#unkqhuu66p = ##Nat.+ a#mdl4vqtu00 1
|
||||
|
||||
```
|
||||
## Should be able to diff a namespace hash from history.
|
||||
|
||||
```unison
|
||||
x = 1
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
x : ##Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
☝️ The namespace .hashdiff is empty.
|
||||
|
||||
.hashdiff> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
x : ##Nat
|
||||
|
||||
```
|
||||
```unison
|
||||
y = 2
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
y : ##Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
.hashdiff> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
y : ##Nat
|
||||
|
||||
.hashdiff> history
|
||||
|
||||
Note: The most recent namespace hash is immediately below this
|
||||
message.
|
||||
|
||||
⊙ 1. #ru1hnjofdj
|
||||
|
||||
+ Adds / updates:
|
||||
|
||||
y
|
||||
|
||||
□ 2. #i52j9fd57b (start of history)
|
||||
|
||||
.hashdiff> diff.namespace 2 1
|
||||
|
||||
Added definitions:
|
||||
|
||||
1. y : ##Nat
|
||||
|
||||
```
|
||||
##
|
||||
|
||||
Updates: -- 1 to 1
|
||||
|
||||
New name conflicts: -- updates where RHS has multiple hashes (excluding when RHS=LHS)
|
||||
|
||||
1. foo#jk19sm5bf8 : Nat - do we want to force a hashqualified? Arya thinks so
|
||||
↓
|
||||
2. ┌ foo#0ja1qfpej6 : Nat
|
||||
3. └ foo#jk19sm5bf8 : Nat
|
||||
|
||||
Resolved name conflicts: -- updates where LHS had multiple hashes and RHS has one
|
||||
|
||||
4. ┌ bar#0ja1qfpej6 : Nat
|
||||
5. └ bar#jk19sm5bf8 : Nat
|
||||
↓
|
||||
6. bar#jk19sm5bf8 : Nat
|
||||
|
||||
## Display issues to fixup
|
||||
|
||||
- [d] Do we want to surface new edit conflicts in patches?
|
||||
- [t] two different auto-propagated changes creating a name conflict should show
|
||||
up somewhere besides the auto-propagate count
|
||||
- [t] Things look screwy when the type signature doesn't fit and has to get broken
|
||||
up into multiple lines. Maybe just disallow that?
|
||||
- [d] Delete blank line in between copies / renames entries if all entries are 1 to 1
|
||||
see todo in the code
|
||||
- [x] incorrectly calculated bracket alignment on hashqualified "Name changes" (delete.output.md)
|
||||
- [x] just handle deletion of isPropagated in propagate function, leave HandleInput alone (assuming this does the trick)
|
||||
- [x] might want unqualified names to be qualified sometimes:
|
||||
- [x] if a name is updated to a not-yet-named reference, it's shown as both an update and an add
|
||||
- [x] similarly, if a conflicted name is resolved by deleting the last name to
|
||||
a reference, I (arya) suspect it will show up as a Remove
|
||||
- [d] Maybe group and/or add headings to the types, constructors, terms
|
||||
- [x] add tagging of propagated updates to test propagated updates output
|
||||
- [x] missing old names in deletion ppe (delete.output.md) (superseded by \#1143)
|
||||
- [x] delete.term has some bonkers output
|
||||
- [x] Make a decision about how we want to show constructors in the diff
|
||||
- [x] 12.patch patch needs a space
|
||||
- [x] This looks like garbage
|
||||
- [x] Extra 2 blank lines at the end of the add section
|
||||
- [x] Fix alignment issues with buildTable, convert to column3M (to be written)
|
||||
- [x] adding an alias is showing up as an Add and a Copy; should just show as Copy
|
||||
- [x] removing one of multiple aliases appears in removes + moves + copies section
|
||||
- [x] some overlapping cases between Moves and Copies^
|
||||
- [x] Maybe don't list the type signature twice for aliases?
|
||||
⚠️
|
||||
I don't know how to view.patch. Type `help` or `?` to get help.
|
||||
|
@ -1,27 +0,0 @@
|
||||
# find.patch Test
|
||||
|
||||
```ucm:hide
|
||||
.> builtins.merge
|
||||
```
|
||||
|
||||
```unison test.u
|
||||
hey = "yello"
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
```
|
||||
|
||||
Update
|
||||
|
||||
```unison test.u
|
||||
hey = "hello"
|
||||
```
|
||||
|
||||
Update
|
||||
|
||||
```ucm
|
||||
.> update.old
|
||||
.> find.patch
|
||||
.> view.patch 1
|
||||
```
|
@ -1,77 +0,0 @@
|
||||
# find.patch Test
|
||||
|
||||
```unison
|
||||
---
|
||||
title: test.u
|
||||
---
|
||||
hey = "yello"
|
||||
|
||||
```
|
||||
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in test.u.
|
||||
|
||||
I found and typechecked these definitions in test.u. If you do
|
||||
an `add` or `update`, here's how your codebase would change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
hey : Text
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
hey : Text
|
||||
|
||||
```
|
||||
Update
|
||||
|
||||
```unison
|
||||
---
|
||||
title: test.u
|
||||
---
|
||||
hey = "hello"
|
||||
|
||||
```
|
||||
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in test.u.
|
||||
|
||||
I found and typechecked these definitions in test.u. If you do
|
||||
an `add` or `update`, here's how your codebase would change:
|
||||
|
||||
⍟ These names already exist. You can `update` them to your
|
||||
new definition:
|
||||
|
||||
hey : Text
|
||||
|
||||
```
|
||||
Update
|
||||
|
||||
```ucm
|
||||
.> update.old
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
hey : Text
|
||||
|
||||
.> find.patch
|
||||
|
||||
1. patch
|
||||
|
||||
.> view.patch 1
|
||||
|
||||
Edited Terms: 1. #m0kuh98ou7 -> 2. hey
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
```
|
@ -1,8 +1,6 @@
|
||||
Previously, the `alias.term` and `alias.type` would fail if the source argument was hash-only, and there was no way to create an alias for a definition that didn't already have a name. Also, the `replace.term` and `replace.type` _only_ worked on hashes, and they had to be _full_ hashes.
|
||||
|
||||
With this PR, the source of an alias can be a short hash (even of a definition that doesn't currently have a name in the namespace) along with a name or hash-qualified name from the current namespace as usual, and the arguments to `replace.term` and `replace.type` can be a short hash, a name, or a hash-qualified name.
|
||||
|
||||
Note: `replace.term` and `replace.type` have since been replaced with just `replace`.
|
||||
With this PR, the source of an alias can be a short hash (even of a definition that doesn't currently have a name in the namespace) along with a name or hash-qualified name from the current namespace as usual.
|
||||
|
||||
Let's make some hash-only aliases, now that we can. :mad-with-power-emoji:
|
||||
|
||||
@ -10,29 +8,3 @@ Let's make some hash-only aliases, now that we can. :mad-with-power-emoji:
|
||||
.> alias.type ##Nat Cat
|
||||
.> alias.term ##Nat.+ please_fix_763.+
|
||||
```
|
||||
|
||||
And some functions that use them:
|
||||
```unison
|
||||
f = 3
|
||||
g = 4
|
||||
h = f + 1
|
||||
|
||||
> h
|
||||
```
|
||||
|
||||
```ucm
|
||||
.> add
|
||||
```
|
||||
|
||||
We used to have to know the full hash for a definition to be able to use the `replace` commands, but now we don't:
|
||||
```ucm
|
||||
.> names g
|
||||
.> replace f g
|
||||
.> names g
|
||||
.> view.patch
|
||||
```
|
||||
|
||||
The value of `h` should have been updated too:
|
||||
```unison
|
||||
> h
|
||||
```
|
||||
|
@ -1,8 +1,6 @@
|
||||
Previously, the `alias.term` and `alias.type` would fail if the source argument was hash-only, and there was no way to create an alias for a definition that didn't already have a name. Also, the `replace.term` and `replace.type` _only_ worked on hashes, and they had to be _full_ hashes.
|
||||
|
||||
With this PR, the source of an alias can be a short hash (even of a definition that doesn't currently have a name in the namespace) along with a name or hash-qualified name from the current namespace as usual, and the arguments to `replace.term` and `replace.type` can be a short hash, a name, or a hash-qualified name.
|
||||
|
||||
Note: `replace.term` and `replace.type` have since been replaced with just `replace`.
|
||||
With this PR, the source of an alias can be a short hash (even of a definition that doesn't currently have a name in the namespace) along with a name or hash-qualified name from the current namespace as usual.
|
||||
|
||||
Let's make some hash-only aliases, now that we can. :mad-with-power-emoji:
|
||||
|
||||
@ -16,96 +14,3 @@ Let's make some hash-only aliases, now that we can. :mad-with-power-emoji:
|
||||
Done.
|
||||
|
||||
```
|
||||
And some functions that use them:
|
||||
```unison
|
||||
f = 3
|
||||
g = 4
|
||||
h = f + 1
|
||||
|
||||
> h
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
f : Cat
|
||||
g : Cat
|
||||
h : Cat
|
||||
|
||||
Now evaluating any watch expressions (lines starting with
|
||||
`>`)... Ctrl+C cancels.
|
||||
|
||||
5 | > h
|
||||
⧩
|
||||
4
|
||||
|
||||
```
|
||||
```ucm
|
||||
.> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
f : Cat
|
||||
g : Cat
|
||||
h : Cat
|
||||
|
||||
```
|
||||
We used to have to know the full hash for a definition to be able to use the `replace` commands, but now we don't:
|
||||
```ucm
|
||||
.> names g
|
||||
|
||||
Term
|
||||
Hash: #vcfbbslncd
|
||||
Names: g
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
.> replace f g
|
||||
|
||||
Done.
|
||||
|
||||
.> names g
|
||||
|
||||
Term
|
||||
Hash: #vcfbbslncd
|
||||
Names: f g
|
||||
|
||||
Tip: Use `names.global` to see more results.
|
||||
|
||||
.> view.patch
|
||||
|
||||
Edited Terms: 1. #f3lgjvjqoo -> 2. f
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
```
|
||||
The value of `h` should have been updated too:
|
||||
```unison
|
||||
> h
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
✅
|
||||
|
||||
scratch.u changed.
|
||||
|
||||
Now evaluating any watch expressions (lines starting with
|
||||
`>`)... Ctrl+C cancels.
|
||||
|
||||
1 | > h
|
||||
⧩
|
||||
5
|
||||
|
||||
```
|
||||
|
@ -1,116 +0,0 @@
|
||||
# Resolving edit conflicts in `ucm`
|
||||
|
||||
```ucm:hide
|
||||
.> builtins.merge
|
||||
```
|
||||
|
||||
The `ucm` tool tracks edits to hashes in an object called a _patch_. When patches get merged, sometimes those patches will have conflicting edits. The `replace` command helps resolve such conflicts.
|
||||
|
||||
First, let's make a new namespace, `example.resolve` and add the builtins:
|
||||
|
||||
```ucm:hide
|
||||
.example.resolve> builtins.merge
|
||||
```
|
||||
|
||||
Now let's add a term named `a.foo`:
|
||||
|
||||
```unison
|
||||
a.foo = 42
|
||||
```
|
||||
|
||||
```ucm
|
||||
.example.resolve> add
|
||||
```
|
||||
|
||||
We'll fork the namespace `a` into a new namespace `b`, so we can edit the two concurrently.
|
||||
|
||||
```ucm
|
||||
.example.resolve> fork a b
|
||||
```
|
||||
|
||||
We'll also make a second fork `c` which we'll use as the target for our patch later.
|
||||
|
||||
```ucm
|
||||
.example.resolve> fork a c
|
||||
```
|
||||
|
||||
Now let's make a change to `foo` in the `a` namespace:
|
||||
|
||||
```ucm
|
||||
.example.resolve> deprecated.cd a
|
||||
```
|
||||
|
||||
```unison
|
||||
foo = 43
|
||||
```
|
||||
|
||||
```ucm
|
||||
.example.resolve.a> update.old
|
||||
```
|
||||
|
||||
And make a different change in the `b` namespace:
|
||||
|
||||
```ucm
|
||||
.example.resolve> deprecated.cd .example.resolve.b
|
||||
```
|
||||
|
||||
```unison
|
||||
foo = 44
|
||||
```
|
||||
|
||||
```ucm
|
||||
.example.resolve.b> update.old
|
||||
```
|
||||
|
||||
The `a` and `b` namespaces now each contain a patch named `patch`. We can view these:
|
||||
|
||||
```ucm
|
||||
.example.resolve.b> deprecated.cd .example.resolve
|
||||
.example.resolve> view.patch a.patch
|
||||
.example.resolve> view.patch b.patch
|
||||
```
|
||||
|
||||
Let's now merge these namespaces into `c`:
|
||||
|
||||
```ucm
|
||||
.example.resolve> merge.old a c
|
||||
```
|
||||
```ucm:error
|
||||
.example.resolve> merge.old b c
|
||||
```
|
||||
|
||||
The namespace `c` now has an edit conflict, since the term `foo` was edited in two different ways.
|
||||
|
||||
```ucm:error
|
||||
.example.resolve> deprecated.cd c
|
||||
.example.resolve.c> todo
|
||||
```
|
||||
|
||||
We see that the original hash of `a.foo` got replaced with _two different_ hashes.
|
||||
|
||||
We can resolve this conflict by picking one of the terms as the "winner":
|
||||
|
||||
```ucm
|
||||
.example.resolve.c> replace 1 2
|
||||
```
|
||||
|
||||
This changes the merged `c.patch` so that only a single edit remains and resolves the conflict.
|
||||
|
||||
```ucm
|
||||
.example.resolve.c> view.patch
|
||||
```
|
||||
|
||||
We still have a remaining _name conflict_ since it just so happened that both of the definitions in the edits were named `foo`.
|
||||
|
||||
```ucm:error
|
||||
.example.resolve.c> todo
|
||||
```
|
||||
|
||||
We can resolve the name conflict by deleting one of the names.
|
||||
|
||||
```ucm
|
||||
.example.resolve.c> delete.term.verbose 2
|
||||
.example.resolve.c> todo
|
||||
```
|
||||
|
||||
And that's how you resolve edit conflicts with UCM.
|
@ -1,265 +0,0 @@
|
||||
# Resolving edit conflicts in `ucm`
|
||||
|
||||
The `ucm` tool tracks edits to hashes in an object called a _patch_. When patches get merged, sometimes those patches will have conflicting edits. The `replace` command helps resolve such conflicts.
|
||||
|
||||
First, let's make a new namespace, `example.resolve` and add the builtins:
|
||||
|
||||
Now let's add a term named `a.foo`:
|
||||
|
||||
```unison
|
||||
a.foo = 42
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These new definitions are ok to `add`:
|
||||
|
||||
a.foo : Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
.example.resolve> add
|
||||
|
||||
⍟ I've added these definitions:
|
||||
|
||||
a.foo : Nat
|
||||
|
||||
```
|
||||
We'll fork the namespace `a` into a new namespace `b`, so we can edit the two concurrently.
|
||||
|
||||
```ucm
|
||||
.example.resolve> fork a b
|
||||
|
||||
Done.
|
||||
|
||||
```
|
||||
We'll also make a second fork `c` which we'll use as the target for our patch later.
|
||||
|
||||
```ucm
|
||||
.example.resolve> fork a c
|
||||
|
||||
Done.
|
||||
|
||||
```
|
||||
Now let's make a change to `foo` in the `a` namespace:
|
||||
|
||||
```ucm
|
||||
.example.resolve> deprecated.cd a
|
||||
|
||||
```
|
||||
```unison
|
||||
foo = 43
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These names already exist. You can `update` them to your
|
||||
new definition:
|
||||
|
||||
foo : ##Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
.example.resolve.a> update.old
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
foo : ##Nat
|
||||
|
||||
```
|
||||
And make a different change in the `b` namespace:
|
||||
|
||||
```ucm
|
||||
.example.resolve> deprecated.cd .example.resolve.b
|
||||
|
||||
```
|
||||
```unison
|
||||
foo = 44
|
||||
```
|
||||
|
||||
```ucm
|
||||
|
||||
Loading changes detected in scratch.u.
|
||||
|
||||
I found and typechecked these definitions in scratch.u. If you
|
||||
do an `add` or `update`, here's how your codebase would
|
||||
change:
|
||||
|
||||
⍟ These names already exist. You can `update` them to your
|
||||
new definition:
|
||||
|
||||
foo : ##Nat
|
||||
|
||||
```
|
||||
```ucm
|
||||
.example.resolve.b> update.old
|
||||
|
||||
⍟ I've updated these names to your new definition:
|
||||
|
||||
foo : ##Nat
|
||||
|
||||
```
|
||||
The `a` and `b` namespaces now each contain a patch named `patch`. We can view these:
|
||||
|
||||
```ucm
|
||||
.example.resolve.b> deprecated.cd .example.resolve
|
||||
|
||||
.example.resolve> view.patch a.patch
|
||||
|
||||
Edited Terms: 1. c.foo -> 2. a.foo
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
.example.resolve> view.patch b.patch
|
||||
|
||||
Edited Terms: 1. c.foo -> 2. b.foo
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
```
|
||||
Let's now merge these namespaces into `c`:
|
||||
|
||||
```ucm
|
||||
.example.resolve> merge.old a c
|
||||
|
||||
Here's what's changed in c after the merge:
|
||||
|
||||
Updates:
|
||||
|
||||
1. foo : Nat
|
||||
↓
|
||||
2. foo : Nat
|
||||
|
||||
Added definitions:
|
||||
|
||||
3. patch patch (added 1 updates)
|
||||
|
||||
Tip: You can use `todo` to see if this generated any work to
|
||||
do in this namespace and `test` to run the tests. Or you
|
||||
can use `undo` or `reflog` to undo the results of this
|
||||
merge.
|
||||
|
||||
Applying changes from patch...
|
||||
|
||||
```
|
||||
```ucm
|
||||
.example.resolve> merge.old b c
|
||||
|
||||
Here's what's changed in c after the merge:
|
||||
|
||||
New name conflicts:
|
||||
|
||||
1. foo#emomp74i93 : Nat
|
||||
↓
|
||||
2. ┌ foo#a84tg4er4k : Nat
|
||||
3. └ foo#emomp74i93 : Nat
|
||||
|
||||
Updates:
|
||||
|
||||
4. patch patch (added 1 updates)
|
||||
|
||||
Tip: You can use `todo` to see if this generated any work to
|
||||
do in this namespace and `test` to run the tests. Or you
|
||||
can use `undo` or `reflog` to undo the results of this
|
||||
merge.
|
||||
|
||||
Applying changes from patch...
|
||||
|
||||
I tried to auto-apply the patch, but couldn't because it
|
||||
contained contradictory entries.
|
||||
|
||||
```
|
||||
The namespace `c` now has an edit conflict, since the term `foo` was edited in two different ways.
|
||||
|
||||
```ucm
|
||||
.example.resolve> deprecated.cd c
|
||||
|
||||
.example.resolve.c> todo
|
||||
|
||||
❓
|
||||
|
||||
These definitions were edited differently in namespaces that
|
||||
have been merged into this one. You'll have to tell me what to
|
||||
use as the new definition:
|
||||
|
||||
The term 1. #qkhkl0n238 was replaced with
|
||||
2. foo#a84tg4er4k
|
||||
3. foo#emomp74i93
|
||||
|
||||
```
|
||||
We see that the original hash of `a.foo` got replaced with _two different_ hashes.
|
||||
|
||||
We can resolve this conflict by picking one of the terms as the "winner":
|
||||
|
||||
```ucm
|
||||
.example.resolve.c> replace 1 2
|
||||
|
||||
Done.
|
||||
|
||||
```
|
||||
This changes the merged `c.patch` so that only a single edit remains and resolves the conflict.
|
||||
|
||||
```ucm
|
||||
.example.resolve.c> view.patch
|
||||
|
||||
Edited Terms: 1. #qkhkl0n238 -> 2. foo#a84tg4er4k
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
```
|
||||
We still have a remaining _name conflict_ since it just so happened that both of the definitions in the edits were named `foo`.
|
||||
|
||||
```ucm
|
||||
.example.resolve.c> todo
|
||||
|
||||
❓
|
||||
|
||||
The term foo has conflicting definitions:
|
||||
1. foo#a84tg4er4k
|
||||
2. foo#emomp74i93
|
||||
|
||||
Tip: This occurs when merging branches that both independently
|
||||
introduce the same name. Use `move.term` or `delete.term`
|
||||
to resolve the conflicts.
|
||||
|
||||
```
|
||||
We can resolve the name conflict by deleting one of the names.
|
||||
|
||||
```ucm
|
||||
.example.resolve.c> delete.term.verbose 2
|
||||
|
||||
Resolved name conflicts:
|
||||
|
||||
1. ┌ foo#a84tg4er4k : ##Nat
|
||||
2. └ foo#emomp74i93 : ##Nat
|
||||
↓
|
||||
3. foo#a84tg4er4k : ##Nat
|
||||
|
||||
Tip: You can use `undo` or `reflog` to undo this change.
|
||||
|
||||
.example.resolve.c> todo
|
||||
|
||||
✅
|
||||
|
||||
No conflicts or edits in progress.
|
||||
|
||||
```
|
||||
And that's how you resolve edit conflicts with UCM.
|
@ -9,20 +9,16 @@ Test that tab completion works as expected.
|
||||
|
||||
view
|
||||
view.global
|
||||
view.patch
|
||||
|
||||
.> debug.tab-complete delete.
|
||||
|
||||
delete.branch
|
||||
delete.namespace
|
||||
delete.namespace.force
|
||||
delete.patch
|
||||
delete.project
|
||||
delete.term
|
||||
delete.term-replacement
|
||||
delete.term.verbose
|
||||
delete.type
|
||||
delete.type-replacement
|
||||
delete.type.verbose
|
||||
delete.verbose
|
||||
|
||||
|
@ -103,7 +103,6 @@ oldfoo = 801
|
||||
|
||||
```ucm
|
||||
.lhs> add
|
||||
.lhs> view.patch patch
|
||||
.lhs> todo
|
||||
```
|
||||
|
||||
|
@ -205,14 +205,6 @@ oldfoo = 801
|
||||
|
||||
oldfoo : Nat
|
||||
|
||||
.lhs> view.patch patch
|
||||
|
||||
Edited Terms: 1. oldfoo -> 2. foo
|
||||
|
||||
Tip: To remove entries from a patch, use
|
||||
delete.term-replacement or delete.type-replacement, as
|
||||
appropriate.
|
||||
|
||||
.lhs> todo
|
||||
|
||||
✅
|
||||
|
@ -17,7 +17,7 @@ Cause a conflict:
|
||||
.merged> merge.old .b
|
||||
```
|
||||
|
||||
Updating conflicted definitions works fine, and the associated patch contains two entries.
|
||||
Updating conflicted definitions works fine.
|
||||
|
||||
```unison
|
||||
x = 3
|
||||
@ -25,5 +25,4 @@ x = 3
|
||||
|
||||
```ucm
|
||||
.merged> update
|
||||
.merged> view.patch
|
||||
```
|
||||
|
@ -64,7 +64,7 @@ Cause a conflict:
|
||||
Applying changes from patch...
|
||||
|
||||
```
|
||||
Updating conflicted definitions works fine, and the associated patch contains two entries.
|
||||
Updating conflicted definitions works fine.
|
||||
|
||||
```unison
|
||||
x = 3
|
||||
@ -92,8 +92,4 @@ x = 3
|
||||
|
||||
Done.
|
||||
|
||||
.merged> view.patch
|
||||
|
||||
This patch is empty.
|
||||
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user