Skip to content

Commit e4c989a

Browse files
committed
Merge branch 'main' into private-memory-store
2 parents 8846020 + f3a6db3 commit e4c989a

File tree

28 files changed

+1402
-214
lines changed

28 files changed

+1402
-214
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Default Owners
2+
* @isc-pbarton @isc-dchui @isc-tleavitt

CHANGELOG.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,67 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [2.13.0] - Unreleased
8+
## [2.15.1] - Unreleased
9+
10+
## Fixed
11+
- Fixed issue where Generated Files Read-only option didn't entirely work for files not in source control (#712)
12+
13+
## [2.15.0] - 2026-01-06
14+
15+
### Added
16+
- Import All has been added to public-facing API (#891)
17+
- Web UI workspace view now has an option to abort merge in progress (#895)
18+
- New setting lets you treat generated classes as read-only in Studio/VS Code (#712)
19+
20+
## Fixed
21+
- Web UI workspace view labels changes as Merge Conflict if there are unmerged changes (#890)
22+
- Web UI workspace view displays diff correctly for files with merge conflicts (#898)
23+
- Storage definition changes in persistent classes are now correctly exported to the Git repository (#906)
24+
- Catch and log exceptions thrown by pull handlers (#909)
25+
- Fix Incremental Load to first remove production items before removing classes (#907)
26+
27+
## [2.14.0] - 2025-11-07
28+
29+
### Added
30+
- Option to lock/unlock namespace is now available on the settings page (#650)
31+
- Settings page now warns if Embedded Git is not the configured source control extension (#857)
32+
- Settings page now has option to switch namespace (#856)
33+
- SourceControl.Git.Settings is now documented as part of the public API to allow programmatic configuration of settings (#262)
34+
- Newly configured instances start with default mappings for ESD, LUT and HL7 when relevant (#724)
35+
- New setting to define an SSH client configuration file for connections to SSH remotes (#293)
36+
- Changed default compilation flags from "ck" to "ckbryu" to include related items (#882)
37+
38+
### Fixed
39+
- When cloning a repo with Configure, that repo's embedded-git-config file will overwrite previous settings (#819)
40+
- Settings page no longer removes remote when saving after cloning (#858)
41+
- Always set the remote as the upstream branch when pushing (#871)
42+
- Fixed import of HL7 and LUT files added at the same time as their mappings (#864)
43+
- Fixed issue where Git's interactive credential manager causes Git push/pull/fetch to hang (#235)
44+
- Failed deployment of one interoperability production item no longer causes all other production items to fail (#886)
45+
46+
## [2.13.1] - 2025-09-16
47+
48+
### Fixed
49+
- Fixed Import All deploying changes to files in a CSP application (#828)
50+
- Fixed pull failure when deleted items have no internal or external name (#848)
51+
- Fixed an error where source control pages do not display after installing on IRIS 2025.1 (#852)
52+
53+
## [2.13.0] - 2025-08-20
954

1055
### Added
1156
- Expanded Baseline Export to include XSL Transforms (#815)
57+
- Enhanced "Check out branch" to first refresh list of remote branches to eliminate failure due to stale information (#823)
1258

1359
### Fixed
1460
- Fix Import All not importing items that do not already exist when compileOnImport is not set (#798)
1561
- Fix baselining output more consistent, human readable (#814)
1662
- Import All now imports configuration file before everything else (#806)
1763
- Fixed another instance of deletes showing as owned by undefined user (#812)
1864
- Fix Revert not syncing files with IRIS (#789)
65+
- Fix "Export All" stopping prematurely because a tracked item no longer exist in the namespace (#821)
66+
- Import All now outputs a warning instead of an error when an item is in the wrong path (#291)
67+
- Fixed an error where classes with compilation errors would revert to broken versions on export (#830)
68+
- Fixed installation of the package on IRIS versions with the IRISSECURITY database (#770)
1969

2070
## [2.12.2] - 2025-07-08
2171

CONTRIBUTING.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1-
# How to contribute
1+
# How to Contribute
22

33
Thank you for your interest in contributing! While this project originated at InterSystems, it is our hope that the community will continue to extend and enhance it.
44

5+
## Getting Started
6+
7+
We recommend setting up a local development instance by following these steps:
8+
1. Install an instance of IRIS (go to https://evaluation.intersystems.com/ for an evaluation kit).
9+
2. Install IPM (InterSystems Package Manager) (https://github.com/intersystems/ipm).
10+
3. Clone a copy of the Embedded Git repository to disk using `git clone`.
11+
4. Install Embedded Git using IPM by running this terminal command (`zpm "load <path_to_embedded_git_repo_directory> -dev"`).
12+
5. Configure your Embedded Git instance to point at a Git repository that IS NOT Embedded Git (it can get very messy very quickly).
13+
6. Modify the code locally! Note that any changes to CSP pages will require loading the module again with IPM to propagate the changes to your local instance.
14+
515
## Submitting changes
616

717
If you have made a change that you would like to contribute back to the community, please send a [GitHub Pull Request](/pull/new/main) explaining it. If your change fixes an issue that you or another user reported, please mention it in the pull request. You can find out more about pull requests [here](http://help.github.com/pull-requests/).
@@ -10,17 +20,16 @@ Every pull request should include at least one entry in CHANGELOG.md - see [keep
1020

1121
We encourage use of [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
1222

13-
## Coding conventions
23+
## Coding Conventions
1424

1525
Generally speaking, just try to match the conventions you see in the code you are reading. For this project, these include:
1626

17-
* Do not use shortened command and function names. For example, use `set` instead of `s` instead of `set` and `$piece` instead of `$p`
27+
* Use the full command and function names. For example, use `set` instead of `s` and `$piece` instead of `$p`
1828
* One command per line
19-
* Do not use dot syntax
2029
* Indentation with tabs
2130
* [Pascal case](https://en.wikipedia.org/wiki/Camel_case) class and method names
22-
* Avoid using postconditionals
23-
* Local variables start with `t`; formal parameter names start with `p`
31+
* Avoid dot syntax
32+
* Avoid postconditionals
2433
* Always check %Status return values
2534

2635
When making changes that involve JavaScript, ensure that your changes still work from Studio (which uses an old version of IE under the hood and therefore doesn't support various things you might take for granted).

README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@ Embedded Git support for InterSystems platforms, supporting unified source contr
1414
```
1515
zpm "install git-source-control"
1616
```
17-
To install on an environment without access to the internet, download the tar.gz file from the [releases](https://github.com/intersystems/git-source-control/releases) page. Copy the archive onto a file system the IRIS instance has access to and extract it. Use the package manager to load the release from that directory.
17+
To install on an environment without access to the internet, download the tar.gz file from the [releases](https://github.com/intersystems/git-source-control/releases) page. Copy it into a directory accessible to the IRIS instance and use a command in the IRIS terminal to install from the tar.gz file.
1818
```
19-
tar -xf /path/to/archive/git-source-control-release.tar.gz
20-
zpm "load /path/to/archive/git-source-control-release"
19+
zpm "load /path/to/archive/git-source-control-release.tar.gz"
2120
```
2221
2. Configure settings by running the following method and answering the prompts:
2322
```
24-
d ##class(SourceControl.Git.API).Configure()
23+
do ##class(SourceControl.Git.API).Configure()
2524
```
2625
This will also allow you to generate an SSH key for use as (e.g.) a deploy key and to initialize or clone a git repo. (If you want to use https instead, please see the documentation [here])(/docs/https.md)
2726
3. If using VSCode: Set up `isfs` server-side editing. First, save your current workspace in which you have the code open. Then, open the `.code-workspace` file generated by VS Code and add the following to the list of folders:
@@ -155,6 +154,14 @@ Assuming you have the local and remote repositories created,
155154
### HTTPS Support
156155
We recommend that people connect to their remote git repository using SSH. If you cannot use SSH connections, we also have support for HTTPS connection through OAuth2. See [our documentation for setting up an https connection](/docs/https.md).
157156
157+
## Editing files in the Git repository server-side
158+
159+
There are some circumstances where you'll want to edit files in the Git repository on the IRIS server. For example,
160+
- To edit interoperability system default settings for a different environment
161+
- To edit custom configuration files
162+
163+
Embedded Git allows you to edit files in the Git repository server-side through VS Code. Enable the "Define a namespace-level web application " option by running `do ##class(SourceControl.Git.API).Configure()`. This will automatically create a new IRIS web application for editing files with the VS Code ObjectScript extension. Then go to the Embedded Git Web UI and use the "Code Workspace" option to download a VS Code workspace. The workspace will allow you to edit files in the Git repository on the server.
164+
158165
## Support
159166
160167
If you find a bug or would like to request an enhancement, [report an issue](https://github.com/intersystems/git-source-control/issues/new). If you have a question, post it on the [InterSystems Developer Community](https://community.intersystems.com/) - consider using the "Git" and "Source Control" tags as appropriate.

cls/SourceControl/Git/API.cls

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ ClassMethod Pull(pTerminateOnError As %Boolean = 0)
4848
quit st
4949
}
5050

51+
/// Imports all items from the Git repository into IRIS.
52+
/// - pForce: if true, will import an item even if the last updated timestamp in IRIS is later than that of the file on disk.
53+
ClassMethod ImportAll(pForce As %Boolean = 0) as %Status
54+
{
55+
return ##class(SourceControl.Git.Utils).ImportAll(pForce)
56+
}
57+
5158
/// Locks the environment to prevent changes to code other than through git pull.
5259
/// Returns 1 if the environment was already locked, 0 if it was previously unlocked.
5360
ClassMethod Lock()

cls/SourceControl/Git/Extension.cls

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,22 @@ Method OnAfterDelete(InternalName As %String) As %Status
444444
quit $$$OK
445445
}
446446

447+
/// This is called if you compile a class and the compilation updates the class storage.
448+
/// It is called after the storage has been updated so you can determine how to deal with this
449+
/// change in the class. The <var>Location</var> is the global reference to the class definition that was changed.
450+
Method OnAfterStorage(InternalName As %String, Location As %String = "") As %Status
451+
{
452+
if (InternalName '= "") {
453+
write !,"Item '"_InternalName_"' changed during compile so exporting new version."
454+
set ..Modified(InternalName) = 1
455+
set sc = ..OnAfterSave(InternalName)
456+
if $$$ISERR(sc) {
457+
do $System.OBJ.DisplayError(sc)
458+
}
459+
}
460+
return $$$OK
461+
}
462+
447463
/// Convert the internal name, e.g. TEST.MAC, to an external name that is used to export
448464
/// the routine/class/csp item. This is often a filename to write the file out to.
449465
Method ExternalName(InternalName As %String) As %String
@@ -461,6 +477,8 @@ Method IsReadOnly(InternalName As %String) As %Boolean
461477
set settings = ##class(SourceControl.Git.Settings).%New()
462478
quit (##class(SourceControl.Git.Utils).Locked()
463479
&& '$get(^IRIS.Temp("sscProd",$job,"bypassLock")))
480+
|| (settings.generatedFilesReadOnly
481+
&& ##class(SourceControl.Git.Utils).ItemIsGenerated(InternalName))
464482
|| (##class(SourceControl.Git.Utils).ItemIsProductionToDecompose($get(InternalName))
465483
&& 'settings.decomposeProdAllowIDE
466484
&& '##class(SourceControl.Git.Production).IsEnsPortal())
@@ -531,7 +549,7 @@ Method GetStatus(ByRef InternalName As %String, ByRef IsInSourceControl As %Bool
531549
}
532550
} else {
533551
// If it doesn't show up in git status, there are no uncommitted changes so it should not be locked or checked out by any user
534-
set Editable=1, IsCheckedOut=0, UserCheckedOut=""
552+
set IsCheckedOut=0, UserCheckedOut=""
535553
if ##class(SourceControl.Git.Change).IsUncommitted(filename)
536554
&& '##class(SourceControl.Git.Change).IsDeleted(InternalName, .files) {
537555
#; Remove the item from the list of uncommitted changes;

cls/SourceControl/Git/File.cls

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ ClassMethod ExternalNameToInternalName(ExternalName As %String) As %String
3535
}
3636
new %SourceControl //don't trigger source hooks with this test load to get the Name
3737
set sc=$system.OBJ.Load(ExternalName,"-d",,.outName,1)
38+
// If the test load was unsuccessful then it may be due to an unsupported
39+
// file type (e.g. hl7 or lut) that we may otherwise be able to handle
40+
if $$$ISERR(sc) {
41+
set outName = ..ParseFileForInternalName(ExternalName)
42+
}
3843
set itemIsPTD = 0
3944
if $data(outName) = 11 {
4045
set key = $order(outName(""))
@@ -59,6 +64,40 @@ ClassMethod ExternalNameToInternalName(ExternalName As %String) As %String
5964
quit internalName
6065
}
6166

67+
/// Attempt to determine the internal name of a given file based on its content
68+
/// Intended to be used in situations where $system.OBJ.Load is unable to
69+
ClassMethod ParseFileForInternalName(fileName As %String) As %String [ Private ]
70+
{
71+
Set internalName = ""
72+
73+
Set fileExtension = $ZCONVERT($PIECE(fileName,".",*),"U")
74+
If (fileExtension = "HL7") {
75+
Set tSC = ##class(%XML.TextReader).ParseFile(fileName, .textReader)
76+
If ($$$ISOK(tSC)) {
77+
// The HL7 schema name is in the 'name' attribute of the 'Category' element
78+
// Example: <Category name="...">
79+
If (textReader.ReadStartElement("Category") && textReader.MoveToAttributeName("name")) {
80+
If (textReader.Value '= "") {
81+
Set internalName = textReader.Value_"."_fileExtension
82+
}
83+
}
84+
}
85+
} ElseIf (fileExtension = "LUT") {
86+
Set tSC = ##class(%XML.TextReader).ParseFile(fileName, .textReader)
87+
If $$$ISOK(tSC) {
88+
// The lookup table name is in the 'table' attribute of any 'entry' element
89+
// Example: <entry table="...">
90+
If (textReader.ReadStartElement("entry") && textReader.MoveToAttributeName("table")) {
91+
If (textReader.Value '= "") {
92+
Set internalName = textReader.Value_"."_fileExtension
93+
}
94+
}
95+
}
96+
}
97+
98+
Quit internalName
99+
}
100+
62101
Storage Default
63102
{
64103
<Data name="FileDefaultData">

cls/SourceControl/Git/PackageManagerContext.cls

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ Method InternalNameSet(InternalName As %String = "") As %Status
1818
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName)
1919
if (InternalName '= i%InternalName) {
2020
set i%InternalName = InternalName
21+
set resourceReference = $$$NULLOREF
2122
if (InternalName = ##class(SourceControl.Git.Settings.Document).#INTERNALNAME) {
22-
// git source control settings document is never in an IPM context
23-
quit $$$OK
24-
}
25-
if $$$comClassDefined("%IPM.ExtensionBase.Utils") {
23+
// Embedded Git settings document is never in an IPM context
24+
set ..Package = $$$NULLOREF
25+
} elseif $$$comClassDefined("%IPM.ExtensionBase.Utils") {
2626
set ..Package = ##class(%IPM.ExtensionBase.Utils).FindHomeModule(InternalName,,.resourceReference)
2727
} elseif $$$comClassDefined("%ZPM.PackageManager.Developer.Extension.Utils") {
2828
set ..Package = ##class(%ZPM.PackageManager.Developer.Extension.Utils).FindHomeModule(InternalName,,.resourceReference)
2929
} else {
30-
quit $$$OK
30+
set ..Package = $$$NULLOREF
3131
}
3232
set ..ResourceReference = resourceReference
3333
set ..IsInGitEnabledPackage = $isobject(..Package) && ##class(%Library.File).Exists(##class(%Library.File).NormalizeFilename(".git",..Package.Root))

cls/SourceControl/Git/Production.cls

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,17 @@ ClassMethod ExportPTD(internalName As %String, nameMethod As %String) As %Status
154154
Return sc
155155
}
156156

157-
/// Imports a PTD into a produciton given an external name and produciton name
157+
/// Imports a PTD into a production given an external name and produciton name
158158
ClassMethod ImportPTD(externalName As %String, productionName As %String) As %Status
159159
{
160160
try {
161161
set ^IRIS.Temp("sscProd",$job,"bypassLock") = 1
162162
set rollbackFile = ##class(%File).TempFilename()
163163
set sc = ##class(Ens.Deployment.Deploy).DeployCode(externalName,productionName,0,rollbackFile)
164+
if $$$ISERR(sc) {
165+
set sc2 = ##class(Ens.Deployment.Deploy).ClearDeploymentInProgressFlag()
166+
if $$$ISERR(sc2) set sc = $$$ADDSC(sc, sc2)
167+
}
164168
do ##class(%File).Delete(rollbackFile)
165169
kill ^IRIS.Temp("sscProd",$job,"bypassLock")
166170
} catch err {
@@ -386,16 +390,16 @@ ClassMethod IsProductionClass(className As %String, nameMethod As %String) As %B
386390
set filename = $classmethod(##class(%Studio.SourceControl.Interface).SourceControlClassGet(), nameMethod, className_".CLS")
387391
if ##class(%File).Exists(filename) && '##class(%File).DirectoryExists(filename) && (##class(%File).GetFileSize(filename) '= 0) {
388392
try {
389-
set ^||%oddDEF=1
393+
set ^||%oddDEF(className) = ""
390394
$$$ThrowOnError($system.OBJ.Load(filename, "-d"))
391395
// class XDatas are stored in ^||%oddDEF("<class name>","x","<XData name>") after temp load
392396
set hasProdDef = $data(^||%oddDEF(className,$$$cCLASSxdata,"ProductionDefinition"))
393-
kill ^||%oddDEF
397+
kill ^||%oddDEF(className)
394398
if hasProdDef {
395399
return 1
396400
}
397401
} catch err {
398-
kill ^||%oddDEF
402+
kill ^||%oddDEF(className)
399403
throw err
400404
}
401405
}

cls/SourceControl/Git/PullEventHandler.cls

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ Method OnPull() As %Status [ Abstract ]
2424
/// <var>pullEventClass</var>: if defined, override the configured pull event class
2525
ClassMethod ForModifications(ByRef files, pullEventClass As %String) As %Status
2626
{
27-
set st = $$$OK
27+
#Dim err As %Exception.AbstractException
28+
#Dim pullError As %Exception.AbstractException
29+
#Dim st As %Status = $$$OK
2830
try {
2931
set log = ##class(SourceControl.Git.DeploymentLog).%New()
3032
set log.HeadRevision = ##class(SourceControl.Git.Utils).GetCurrentRevision()
@@ -33,15 +35,20 @@ ClassMethod ForModifications(ByRef files, pullEventClass As %String) As %Status
3335
quit:$$$ISERR(st)
3436
set event = $classmethod(
3537
$select(
36-
$data(pullEventClass)#2: pullEventClass,
38+
$data(pullEventClass)#2: pullEventClass,
3739
1: ##class(SourceControl.Git.Utils).PullEventClass())
3840
,"%New")
3941
set event.LocalRoot = ##class(SourceControl.Git.Utils).TempFolder()
4042
merge event.ModifiedFiles = files
41-
set st = event.OnPull()
43+
try {
44+
set st = event.OnPull()
45+
}
46+
catch pullError {
47+
set st = pullError.AsStatus()
48+
}
4249
set log.EndTimestamp = $zdatetime($ztimestamp,3)
4350
set log.Status = st
44-
set st = log.%Save()
51+
set st = log.%Save() // this hides any errors returned or thrown by OnPull()
4552
quit:$$$ISERR(st)
4653
} catch err {
4754
set st = err.AsStatus()

0 commit comments

Comments
 (0)