├── %SourceControl ├── Git.cls.xml └── Git │ ├── Test │ ├── AddRemove.cls.xml │ └── Git.cls.xml │ └── Utils.cls.xml ├── LICENSE.md ├── README.md ├── cache-tort-git.prj.xml ├── csp └── gitprojectsettings.csp.xml └── sc-list.txt /%SourceControl/Git.cls.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %SourceControl.Git 5 | %Studio.Extension.Base 6 | 62655,58027.787011 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | ]]> 48 | 49 | 50 | 51 | 52 | %Status 53 | 63 | 64 | 65 | 66 | 67 | %Status 68 | 118 | 119 | 120 | 121 | 122 | %Status 123 | 0 { //if more than one item is selected, we can only add/remove, no diff or blame 130 | set Enabled = $case(menuItemName,"%AddToSC":1,"%RemoveFromSC":1,:-1) 131 | 132 | }elseif ##class(Utils).IsInSourceControl(##class(Utils).NormalizeInternalName(itemName)) { 133 | set Enabled = $Case(menuItemName, "%AddToSC":-1,:1) 134 | } else { 135 | set Enabled = $Case(menuItemName, "%AddToSC":1,:-1) 136 | } 137 | quit $$$OK 138 | ]]> 139 | 140 | 141 | 142 | MenuItems. The DisplayName of this menu is 145 | also passed by reference and this may be modified to change the appearance of this menu item. The MenuName 146 | is the main menu name then the submenu name separated by a ','. If Enabled is set to -1 then it will remove 147 | this menu item from the list totally, 0 will gray the menu item out and the default 1 will display the menu item as normal.]]> 148 | 149 | %Status 150 | 168 | 169 | 170 | 171 | 172 | This is called before the actual load of data to give the chance 173 | to load the item from an external format. 174 | InternalName:%String 175 | %Status 176 | 183 | 184 | 185 | 186 | 187 | This is called after the item has been saved to the database. 188 | It may be passed a reference to the object representing the item 189 | just saved. It can be use to export this documement to an external form for example. 190 | InternalName:%String,Object:%RegisteredObject=$$$NULLOREF 191 | %Status 192 | 201 | 202 | 203 | 204 | 205 | Called after the compile of the item is done. 206 | InternalName:%String 207 | %Status 208 | 210 | 211 | 212 | 213 | 214 | Returns true if this item is in source control and false otherwise. 215 | expression 216 | InternalName:%String 217 | %Boolean 218 | 220 | 221 | 222 | 223 | 224 | Called after an item is deleted. 225 | InternalName:%String 226 | %Status 227 | 234 | 235 | 236 | 237 | -------------------------------------------------------------------------------- /%SourceControl/Git/Test/AddRemove.cls.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %SourceControl.Git 5 | %UnitTest.TestCase 6 | 63607,51627.861648 7 | 8 | 9 | 17 | 18 | 19 | 20 | 28 | 29 | 30 | 31 | %Status 32 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /%SourceControl/Git/Test/Git.cls.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 63607,51454.905525 6 | 7 | 8 | 1 9 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /%SourceControl/Git/Utils.cls.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | %occStatus,%occErrors 6 | 1 7 | 62657,53384.637236 8 | 9 | 10 | ^Git 11 | 12 | 13 | 14 | %SYS 15 | 16 | 17 | 18 | $case($system.Version.GetOS(),"Windows":"\",:"/") 19 | 20 | 21 | 22 | 23 | Name of the file with version controlled items 24 | sc-list.txt 25 | 26 | 27 | 28 | ,%Settings,%Commit,%Pull,%Fetch,%Switch,%Merge,%Push,%Diff,%RepoStatus,%Resolve,%Revert,%Log,%StashSave,%StashPop, 29 | 30 | 31 | 32 | ,%Clone,%Commit,%Pull,%Fetch,%Push,%Resolve,%StashPop, 33 | 34 | 35 | 36 | ,%Diff,%Blame, 37 | 38 | 39 | 40 | 1 41 | expression 42 | %String 43 | 45 | 46 | 47 | 48 | 49 | Returns root temp folder 50 | 1 51 | expression 52 | %String 53 | 55 | 56 | 57 | 58 | 62 | 63 | 64 | 65 | 1 66 | expression 67 | msg:%String 68 | 1 69 | %Status 70 | 72 | 73 | 74 | 75 | 1 76 | expression 77 | %String 78 | 80 | 81 | 82 | 83 | 1 84 | expression 85 | %String 86 | 88 | 89 | 90 | 91 | 1 92 | expression 93 | %Boolean 94 | 96 | 97 | 98 | 99 | 1 100 | expression 101 | %String 102 | 104 | 105 | 106 | 107 | 1 108 | %Boolean 109 | 119 | 120 | 121 | 122 | 1 123 | %String 124 | 128 | 129 | 130 | 131 | 1 132 | expression 133 | %Boolean 134 | 136 | 137 | 138 | 139 | 1 140 | expression 141 | %String 142 | 144 | 145 | 146 | 147 | 1 148 | path:%String 149 | 1 150 | %String 151 | 157 | 158 | 159 | 160 | 1 161 | 162 | %Status 163 | 176 | 177 | 178 | 179 | 1 180 | expression 181 | commandName:%String,itemName:%String="" 182 | %String 183 | 189 | 190 | 191 | 192 | 1 193 | expression 194 | menuItemName:%String 195 | %Boolean 196 | 0 197 | ]]> 198 | 199 | 200 | 201 | 1 202 | expression 203 | menuItemName:%String 204 | %Boolean 205 | 0 206 | ]]> 207 | 208 | 209 | 210 | 1 211 | expression 212 | menuItemName:%String 213 | %Boolean 214 | 0 215 | ]]> 216 | 217 | 218 | 219 | 1 220 | 221 | %Status 222 | 307 | 308 | 309 | 310 | 1 311 | 312 | %Status 313 | 315 | 316 | 317 | 318 | 1 319 | expression 320 | %Boolean 321 | 323 | 324 | 325 | 326 | 328 | removes first slash if present
329 | adds last slash if not present
]]>
330 | 1 331 | folder:%String 332 | %String 333 | 339 |
340 | 341 | 342 | 1 343 | InternalName:%String 344 | %String 345 | = 10 { //values in leaves 389 | set type = ..Type(InternalName) 390 | 391 | if $Data(@mappingsNode@(type), folder) { 392 | set folder = ..NormalizeFolder(folder) 393 | } 394 | } 395 | 396 | set name = $Get(rootFolder) _ $Get(folder) _ name 397 | 398 | // write "name=",name,! 399 | // write "external name = ", $Translate(name," *?","___")_".xml", ! 400 | quit $Translate(name," *?","___")_".xml" 401 | ]]> 402 | 403 | 404 | 405 | 1 406 | InternalName:%String 407 | %Status 408 | 422 | 423 | 424 | 425 | 1 426 | InternalName:%String 427 | %Status 428 | 457 | 458 | 459 | 460 | 1 461 | InternalName:%String 462 | %Status 463 | 490 | 491 | 492 | 493 | 1 494 | InternalName:%String 495 | %Boolean 496 | 506 | 507 | 508 | 509 | 511 | prj -- project
512 | csp -- csp-page or csp-folder. See IsCspFolder
513 | csp -- any static file from csp-folder ]]>
514 | 1 515 | InternalName:%String 516 | %String 517 | 0) { 524 | //we need to double-check 525 | //Sometimes (see NormalizeInternalName) Studio passes routine names as /Package/SubPackage/Routine.mac 526 | //Generally speaking this can be static file 527 | if (type = "mac") || (type = "inc") || (type = "int") { 528 | #dim filename = $system.CSP.GetFileName(InternalName) 529 | if ##class(%File).Exists(filename) { 530 | set type = "csp" 531 | } 532 | } else { 533 | set type ="csp" 534 | } 535 | } 536 | 537 | quit type 538 | ]]> 539 |
540 | 541 | 542 | 1 543 | expression 544 | InternalName:%String 545 | %String 546 | 548 | 549 | 550 | 551 | 552 | packageName without extension 553 | 1 554 | expression 555 | ClassName:%String,packageName:%String 556 | %Boolean 557 | 559 | 560 | 561 | 562 | 563 | projectName without extension 564 | 1 565 | InternalName:%String,projectName:%String 566 | %Boolean 567 | " 573 | #dim name As %String = $case(type, "cls": ..NameWithoutExtension(InternalName), 574 | "pkg": $Translate(..NameWithoutExtension(InternalName), "/", "."), 575 | "csp": $Extract(InternalName, 2, *), 576 | :InternalName) 577 | if $Extract(name) = "." && (type = "pkg") { 578 | set $Extract(name) = "" 579 | } 580 | 581 | //w name, " " 582 | #dim checkId = projectName_"||"_name_"||"_$ZConvert(type,"U") 583 | //w checkId 584 | #dim isItemInProject As %Boolean = ##class(%Studio.ProjectItem).%ExistsId(checkId) 585 | //w " ", isItemInProject, ! 586 | 587 | #dim i As %Integer 588 | if 'isItemInProject && ((type = "cls") || (type="pkg")) { 589 | for i = 1:1:$Length(name, ".") { 590 | set checkId = projectName_"||"_$Piece(name, ".", 1, i)_"||PKG" 591 | //w checkId, ! 592 | if ##class(%Studio.ProjectItem).%ExistsId(checkId) { 593 | set isItemInProject = 1 594 | quit 595 | } 596 | } 597 | } 598 | 599 | if 'isItemInProject && (type = "csp") { 600 | for i = 1:1:$Length(name, "/") { 601 | set checkId = projectName_"||"_$Piece(name, "/", 1, i)_"||DIR" 602 | 603 | if ##class(%Studio.ProjectItem).%ExistsId(checkId) { 604 | set isItemInProject = 1 605 | quit 606 | } 607 | } 608 | } 609 | quit isItemInProject 610 | ]]> 611 | 612 | 613 | 614 | 1 615 | expression 616 | InternalName:%String,cspFolder:%String 617 | %Boolean 618 | 620 | 621 | 622 | 623 | 1 624 | 625 | %Boolean 626 | 643 | 644 | 645 | 646 | 1 647 | 648 | %Boolean 649 | 666 | 667 | 668 | 669 | 1 670 | 671 | %Boolean 672 | 692 | 693 | 694 | 695 | 1 696 | 697 | %String 698 | 0 706 | if isInSourceControl { 707 | set sourceControlItem = InternalName 708 | }else { 709 | //if no direct reference maybe we have to look in packages, projects or csp-apps ? 710 | //We have three groups of routines 711 | //packages for classes 712 | //projects for everything 713 | //csp-folders for csp and static files 714 | 715 | #dim type As %String = ..Type(InternalName) 716 | if type = "cls" { 717 | #define StripExtension(%s) $Piece(%s,".",1,$Length(%s, ".") - 1) 718 | if InternalName'="" && ($$$defClassKeyGet($$$StripExtension(InternalName),$$$cCLASSgeneratedby)'="") { 719 | set isInSourceControl = 0 // skip generated classes 720 | } else { 721 | set isInSourceControl = ..FindInPackages(InternalName, .sourceControlItem) 722 | } 723 | } elseif type = "csp" { 724 | if $Extract(InternalName) '= "/" { 725 | set InternalName = "/" _ InternalName 726 | } 727 | set isInSourceControl = ..FindInCspFolders(InternalName, .sourceControlItem) 728 | } 729 | 730 | // our last chance to find item -- let's look in projects 731 | if 'isInSourceControl { 732 | set isInSourceControl = ..FindInProjects(InternalName, .sourceControlItem) 733 | } 734 | } 735 | //w "checking ", $G(type), " ", InternalName, "=", isInSourceControl, ! 736 | quit isInSourceControl 737 | ]]> 738 | 739 | 740 | 741 | 1 742 | expression 743 | InternalName:%String 744 | %String 745 | 747 | 748 | 749 | 750 | 1 751 | name:%String 752 | %String 753 | Namespace 757 | //If right-click in Workspace -> Project then everything passes ok 758 | //let's fix this 759 | if $Extract(name) '= "/" { 760 | quit name 761 | } 762 | 763 | set type = ..Type(name) 764 | 765 | if (type = "inc") || (type = "mac") || (type = "int") { 766 | set name = $Extract($Translate(name, "/", "."), 2, *) 767 | } 768 | quit name 769 | ]]> 770 | 771 | 772 | 773 | 1 774 | name:%String 775 | %String 776 | 783 | 784 | 785 | 786 | 1 787 | InternalName:%String 788 | %String 789 | 804 | 805 | 806 | 807 | 1 808 | InternalName:%String,tsh:%String 809 | %Status 810 | 814 | 815 | 816 | 817 | 1 818 | InternalName:%String 819 | %Status 820 | 824 | 825 | 826 | 827 | 1 828 | InternalName:%String 829 | %Status 830 | 840 | 841 | 842 | 843 | 844 | if temp file for InternalName not found return "0,0" in tempFileTSH 845 | 1 846 | 847 | 856 | 857 | 858 | 859 | 1 860 | InternalName:%String 861 | %Boolean 862 | 866 | 867 | 868 | 869 | 1 870 | InternalName:%String 871 | %Boolean 872 | 876 | 877 | 878 | 879 | 1 880 | projectName:%String 881 | %Status 882 | 907 | 908 | 909 | 910 | force = 1 then imports in any case.]]> 913 | 1 914 | InternalName:%String,force:%Boolean=0 915 | %Status 916 | 940 | 941 | 942 | 943 | 1 944 | 945 | %Status 946 | 0 { 955 | write "There were some errors while importing files",! 956 | for i=1:1:err { 957 | write err(i),! 958 | } 959 | } 960 | 961 | //change all csp/ names to /csp/ names 962 | #dim item As %String = "csp" 963 | for { 964 | set item = $Order(itemList(item)) 965 | quit:item="" 966 | quit:$Extract(item, 1, 4)'="csp/" 967 | kill itemList(item) 968 | set itemList("/"_item)="" 969 | } 970 | quit $$$OK 971 | ]]> 972 | 973 | 974 | 975 | 1 976 | force:%Boolean=0 977 | %Status 978 | 0 { 1018 | set ec = $$$ADDSC(ec, ##class(%Routine).Delete(item)) 1019 | }elseif type = "csp" { 1020 | #dim filename = $system.CSP.GetFileName(item) 1021 | if ##class(%File).Exists(filename) && '##class(%File).Delete(filename) { 1022 | set ec = $$$ADDSC(ec, ..MakeError("Error while removing "_item)) 1023 | } 1024 | } else { 1025 | set deleted = 0 1026 | } 1027 | 1028 | if deleted && ec { 1029 | do ..RemoveRoutineTSH(item) 1030 | write item, " was deleted", ! 1031 | } else { 1032 | if +$system.Status.GetErrorCodes(ec) '= $$$ClassDoesNotExist { 1033 | write "Error: could not delete ", item, ! 1034 | } else { 1035 | // if something we wanted to delete is already deleted -- good! 1036 | set ec = $$$OK 1037 | } 1038 | } 1039 | } 1040 | } 1041 | 1042 | write "==import done==", ! 1043 | quit ec 1044 | ]]> 1045 | 1046 | 1047 | 1048 | 1 1049 | path:%String,sep:%String="",level:%Integer=0,force:%Boolean=0 1050 | %Status 1051 | 1085 | 1086 | 1087 | 1088 | 1 1089 | InternalName:%String,expand:%Boolean=1,force:%Boolean=0 1090 | %Status 1091 | 1114 | 1115 | 1116 | 1117 | 1 1118 | project:%String,force:%Boolean=0 1119 | %Status 1120 | 1135 | 1136 | 1137 | 1138 | force = 1 then we export item even if timestamp in system is older]]> 1140 | 1 1141 | force:%Boolean=0 1142 | %Status 1143 | 1147 | 1148 | 1149 | 1150 | force = 1 then we import item even if timestamp in system is newer]]> 1152 | 1 1153 | force:%Boolean=0 1154 | %Status 1155 | 1159 | 1160 | 1161 | 1162 | 1 1163 | force:%Boolean=0 1164 | %Status 1165 | 1176 | 1177 | 1178 | 1179 | 1 1180 | %Status 1181 | " 1194 | } 1195 | 1196 | do file.WriteLine(fixedItem) 1197 | 1198 | } 1199 | $$$QuitOnError(file.%Save()) 1200 | do file.Close() 1201 | kill file 1202 | quit $$$OK 1203 | ]]> 1204 | 1205 | 1206 | 1207 | 1 1208 | %Status 1209 | ", defaultCspApp) 1222 | set a(..NormalizeExtension(item)) = "" 1223 | } 1224 | kill @..#Storage("items") 1225 | merge @..#Storage("items") = a 1226 | do file.Close() 1227 | kill file 1228 | quit $$$OK 1229 | ]]> 1230 | 1231 | 1232 | 1233 | 1234 | returns true if directory was deleted 1235 | 1 1236 | path:%String 1237 | %Boolean 1238 | 1262 | 1263 |
1264 |
1265 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Alexander Koblov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Caché Git 2 | 3 | Source Version Control plug-in for Caché Studio. Caché Git allows working with git-repos straight from Caché Studio. 4 | 5 | ## Features 6 | Caché Git provides interface from Caché Studio to TortoiseGit. Caché Git supports one repository for each Caché namespace. User chooses files to include in version control. 7 | 8 | ## Pre-installation Requirements 9 | 1. Install [msysgit](http://msysgit.github.com/). Choose "Run Git from the Windows Command Prompt" option when installing. 10 | 1. Install [TorgoiseGit](http://code.google.com/p/tortoisegit/). 11 | 12 | Caché Studio before 2011.1 cannot work with executables that have space in its name (like "C:\Program Files\TortoiseGit\bin\TortoiseGitProc.exe"). In that case you should either install TortoiseGit in the folder without spaces or use newer version of Caché Studio. Caché Studio can work with previous version of Caché server. For example, Caché Studio 2013.1 [can](http://docs.intersystems.com/cache_latest/csp/docbook/DocBook.UI.Page.cls?KEY=ISP_interop) work with Caché 2009. 13 | 14 | _On *Nix systems Caché Git provides only Export/Import without calling TortoiseGit._ 15 | 16 | ## Installation in Caché: 17 | 1. Enable [write-access](http://docs.intersystems.com/ens20151/csp/docbook/DocBook.UI.Page.cls?KEY=GSA_config#GSA_config_database_edit) to CACHELIB database via the Management Portal. (This is required for csp-page with settings import.) 18 | 1. Import project in %SYS: 19 | 20 | %SYS>do $system.OBJ.ImportDir("c:\your-path-that-contains-project-downloaded-from-github","*.xml","ck",,1) 21 | 22 | 1. Now you can disable write-access to CACHELIB. 23 | 1. In Management Portal select the new %SourceControl.Git class as the desired Source Control class in all namespaces where you wish to use it. (System Administration >> Configuration >> Additional Settings >> Source Control) 24 | 25 | ## Setup 26 | In Studio, in any namespace with %SourceControl.Git as a Version Control Class choose menu "Git > Settings" 27 | 28 | 1. Enter full path to TortoiseGitProc.exe (usually "C:\Program Files\TortoiseGit\bin\TortoiseGitProc.exe") 29 | 1. Enter default temp folder (usually "C:\Temp"). ATTENTION! This folder shouldn't contain anything valuable. There will be subfolders for each Caché namespace. 30 | 1. You can also specify temp folder for this particular namespace. Otherwise temp folder for this namespace will be <default-temp-folder>\\<namespace> 31 | 32 | * If you don't want to enter you credentials every time you use git create in temp folder file _netrc and add string `machine your-git-server login your-git-login password your-git-password`. 33 | Instead of your-git-server, your-git-login and your-git-password write actual values. Or use [Git Credentials](http://stackoverflow.com/a/15351702). 34 | 35 | 36 | ## How to work with plug-in 37 | ### How to start 38 | 1. In Studio, select Git >> Tortoise Git Settings and set up options for Git (e.g. Proxy). This options are stored in folder that you chose as temp. 39 | 1. Choose Git >> Create Repo. Press OK, one more time. 40 | 1. You will notice that the Git menu now has a full set of options. 41 | 1. A new menu item appears in context menu — "Git -> Add to Source Control", when right-clicking on elements in the Workspace Window (Alt+3). 42 | 1. Choose elements you want to add to Git. These programs, classes, csp-pages etc. are exported to hdd-folder and automatically synchronized with it every time when you open or save them in Studio. 43 | 1. Choose menu Commit. 44 | 1. Select all files, right-click on them and choose "Add". 45 | 1. Write comment and press "Commit". 46 | 1. Now you can immediately push changes to server. 47 | * You should press Push 48 | * Then click Manage button and specify git-server 49 | * For example: 50 | * Remote: assembla 51 | * URL: http://git.assembla.com/demobld.git 52 | * Choose the server you have just specified. 53 | * Press OK 54 | 55 | ### How to join existing repository 56 | 1. Choose menu Clone. 57 | 1. Enter repository URL. 58 | 1. [If your TortoiseGit Version < 1.8.5] In appeared window TortoiseGit adds repository name to folder. You should delete it (Write c:\temp\git\user instead of c:\temp\git\user\reponame) 59 | 1. Press 'OK'. 60 | 1. Select menu Import All to load changes from temp folder to Caché. Import All compares timestamps of files and Caché items and import files only if they are newer then Caché versions. There is also Import All Force menu item that import files without any checks. 61 | 62 | ### Work Cycle 63 | 1. Choose menu item Pull. 64 | 1. Resolve conflicts in TortoiseGit if any. 65 | 1. Select menu Import All to load changes from temp folder to Caché. 66 | 1. Do some changes in Caché Studio. 67 | 1. [Optional] Select menu Export All if you want to force-unload changes to temp folder from Caché. 68 | 1. Select Commit 69 | 1. Select Push from Caché Studio menu or immediately after Commit. 70 | 71 | ### Global's structure 72 | Data used by Caché-Git is stored in global which name is defined by Storage parameter of %SourceControl.Git.Utils class. Its value by default — ^Git. 73 | Options (path to tortoiseproc.exe and temp folder) are stored in %SYS namespace in nodes ^Git("%gitBinPath") and ^Git("%defaultTemp"). 74 | In each namespace we also store path to temp folder for this namespace that can override default path. Global name is ^Git("settings","namespaceTemp") 75 | 76 | In ^Git("items") node namespace elements are stored that traced by Caché-Git. We store names of particular items with extension in lower-case. 77 | 78 | In ^Git("TSH") node timestamps of last synchronization for each routine are stored. 79 | 80 | To run all tests: 81 | 82 | %SYS>do ##class(%SourceControl.Git.Test.Git).runall() 83 | 84 | ### Extra Repository Settings 85 | #### Mappings 86 | To specify particular folder in repository where Caché Git should place files set value of `^Git("settings","mappings") to relative path. Additionally you can specify subfolder for each particular item type. 87 | 88 | For example: 89 | 90 | USER>zwrite ^Git 91 | ^Git("settings","mappings")="src/cache/" 92 | ^Git("settings","mappings","cls")="cls/" 93 | ^Git("settings","mappings","csp")="csp-data/" 94 | ^Git("settings","mappings","dfi")="dfi/" 95 | ^Git("settings","mappings","mac")="mac/" 96 | ^Git("settings","namespaceTemp")="C:\temp\testctg\" 97 | 98 | In this particular case Caché Git stores all its files (except sc-list.txt) in `src/cache/` subfolder. Classes are stored in `src/cache/cls/` etc. All csp files (including static files -- js, css) are stored in `src/cache/csp-data/`. With this particular path to repository classes will be stored in folder `C:\temp\testctg\src\cache\cls\`. 99 | 100 | You can omit root mappings. Mappings for particular item type are still applied. 101 | 102 | #### Other Settings 103 | The following sub-nodes of `^Git("settings")` allow for further configuration: 104 | 105 | * `"groupByFolder"` - boolean value that defaults to `0` when not specified. The setting applies to all INC, MAC and INT routines as well as DFI exports. 106 | * When this value is true, use nested folders for these files, e.g. `Package.Include.INC` would be exported to `/Package/Include.inc.xml` 107 | * When this value is false, all these files are exported to the root folder, e.g. `Package.Include.INC` would be exported to `/Package.Include.inc.xml` 108 | * `"includeExtensionInFilename"` - boolean value that defaults to `1` when not specified. 109 | * When true, exported files include the lowercase extension in the filename, e.g. `MyClass.cls.xml` 110 | * When false, exported files do not include the extension in the filename, e.g. `MyClass.xml` 111 | 112 | NOTE: Caché Git does not do any automatic moving of files. If you have classes placed in root folder and change mappings for cls to "src/cache/cls/" you need to move files corresponding to these classes manually. Better -- set mappings on creating of repository, before adding new items to source control. 113 | -------------------------------------------------------------------------------- /cache-tort-git.prj.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /csp/gitprojectsettings.csp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | Cache-Git Settings 7 | 12 | 13 | 14 | set namespace = %request.Data("NSpace",1) 15 | set oldNS=$znspace 16 | znspace namespace 17 | if $Data(%request.Data("gitsettings",1)) { 18 | kill settings 19 | for param="gitBinPath","defaultTemp","namespaceTemp","groupByFolder" { 20 | set settings(param) = $Get(%request.Data(param,1)) 21 | } 22 | do ##class(%SourceControl.Git.Utils).UpdateSettings(.settings) 23 | } 24 | set gitBinPath = ##class(%SourceControl.Git.Utils).GitBinPath() 25 | set defaultTemp = ##class(%SourceControl.Git.Utils).DefaultTemp() 26 | set namespaceTemp = ##class(%SourceControl.Git.Utils).TempFolder() 27 | set groupByFolder = ##class(%SourceControl.Git.Utils).GroupByFolder() 28 | znspace oldNS 29 | set:defaultTemp="" defaultTemp = "c:\temp\" 30 | 31 | 32 |
33 | 34 | 35 |

Settings

36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 62 |
Path to tortoisegitproc.exe
(e.g. c:\tortoisegit\bin\tortoisegitproc.exe)
44 | file does not found 45 |
Default path to temp folder
(e.g. c:\temp)
Settings for this namespace only
Temp folder for this namespace
(e.g. c:\someproj\)
63 | 64 |
65 | 66 | Click cross in the upper-right corner to close the settings window. 67 | 68 | 69 | ]]>
70 |
71 | -------------------------------------------------------------------------------- /sc-list.txt: -------------------------------------------------------------------------------- 1 | %SourceControl.pkg 2 | /gitprojectsettings.csp 3 | cache-tort-git.prj 4 | --------------------------------------------------------------------------------