{"id":27931,"date":"2023-03-09T07:00:12","date_gmt":"2023-03-09T15:00:12","guid":{"rendered":"https:\/\/www.podfeet.com\/blog\/?p=27931"},"modified":"2023-03-08T20:32:36","modified_gmt":"2023-03-09T04:32:36","slug":"git-keyboard-maestro","status":"publish","type":"post","link":"https:\/\/www.podfeet.com\/blog\/2023\/03\/git-keyboard-maestro\/","title":{"rendered":"Version Control with Git for Your Keyboard Maestro Macros"},"content":{"rendered":"<p>I\u2019ve talked quite a bit lately about learning to automate things on the Mac using the fabulous tool Keyboard Maestro. Keyboard Maestro is essentially like a little programming language with a graphical user interface, but it&#8217;s missing an essential part of any document creation tool &#8211; there&#8217;s no way to save versions of what you create. If you change something in one of your macros, there&#8217;s no way to get back to a known good version.<\/p>\n<p>If you\u2019ve got a simple little macro you\u2019re working on with 3 steps and you try to add a 4th step and it falls over in a heap, it\u2019s pretty easy to roll back the change by removing that 4th step.  But what if you\u2019re working on a more complex macro with 20 or 30 separate steps and it\u2019s <em>almost<\/em> working, but you tweak it in a couple of different places over the course of days or weeks and it breaks? How do you figure out what you changed?<\/p>\n<p>Mike Price worked out a really nifty macro for me that streamlines the addition of chapter marks into my recording software, Hindenburg. If you like the chapter marks in the NosillaCast, you should thank Mike for them.<\/p>\n<p>When something got fiddly with the macro, I started poking at it changing things. For a while it got better, but then whatever I did completely broke the macro.  I\u2019ve had to ask Mike to send the original to me again and now I have to try to get it back to the configuration that did work.<\/p>\n<p>Since Keyboard Maestro doesn\u2019t have its own built-in version control, I went on a hunt for a way to do this.<\/p>\n<p><a href=\"https:\/\/pbs.bartificer.net\/pbs102\" target=\"_blank\" rel=\"noopener\"><\/p>\n<figure style=\"float: right; margin-left: 10px\"><img decoding=\"async\" src=\"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2023\/03\/Git-Introduction-on-PBS-102.png\" alt=\"Git Introduction on PBS 102\"  title=\"Git Introduction on PBS 102.png\" width=\"400 \" height=\"192\"><figcaption style=\"text-align:center\">Git Intro on Programming By Stealth<\/figcaption><\/figure>\n<p><\/a>In the <a href=\"https:\/\/pbs.bartificer.net\/pbs102\" target=\"_blank\" rel=\"noopener\">Programming By Stealth podcast<\/a>, Bart Busschots taught a 20-part mini-series within the series all about version control, and specifically the tool Git to do version control. It&#8217;s pretty nerdy, but I&#8217;ve really grown to enjoy the safety net that it creates when I program. Not that I would <em>ever<\/em> break my own code of course.<\/p>\n<p>With Git, when you want to save a version of a file, you do what\u2019s called a commit.  When you commit, you also add a commit message. This commit message tells future you something about that version of the file. These commit messages are essential to figuring out which version you might want to roll back to.<\/p>\n<p>All of these committed versions of the same file live on your computer, but you can also push them to another machine on your network for safe keeping, or push them up to a repository on the web such as GitHub or Bit Bucket. It&#8217;s all built into the Git system. If you mess up your code (or any kind of document you put into Git) you can always revert back to a previous version by looking at those commit messages you carefully crafted.<\/p>\n<p>When I decided I really needed a way to do version control on my Keyboard Maestro macros, my first thought was to do it in Git. I had no idea how hard this would be. The good news for you is this isn&#8217;t going to be a 20-minute dissertation on everything I tried to do and how it failed and finally I figured it out. Nope, I Googled for Keyboard Maestro and Git and discovered someone else had solved it already. I&#8217;m glad I found this solution because I never would have known how to do what this somebody did.<\/p>\n<p>The reason this problem is a sticky wicket is that Keyboard Maestro doesn\u2019t store each macro you create in its own file \u2014 everything is one giant file in the file system. In Keyboard Maestro, you save macros in groups and can have them work only in specific applications, so that makes this one file even more complex.<\/p>\n<p>The hero of this story is a lovely gentleman named Dan Thomas. He solved this problem, and interestingly he used Keyboard Maestro to solve it. He created two macros: <a href=\"https:\/\/github.com\/dagware\/DanThomas\/blob\/master\/MacroRepository\/MacroRepository.md\">Macro Repository Updater and Macro Repository Importer. He released both of these macros on GitHub<\/a> and made them open source under his own, very generous license. This means you can download his macros, open them in your own copy of Keyboard Maestro and use them.<\/p>\n<p>The first macro called Macro Repository Updater saves all of your groups and macros within them to individual source files.  This solves the main problem of all the macros being mashed into one file, and preserves the groups. It takes a while the first time you run it because it\u2019s got to disentangle all of those files and sort them into separate folders.<\/p>\n<p>After the first time you run the Macro Repository Updater macro into a folder, you can then initialize the folder as what\u2019s called a Git repository, and commit all of the files for the first time. This action gives you that precious save state as of when you ran Dan&#8217;s macro.<\/p>\n<p>Dan&#8217;s Macro Repository Updater macro creates a folder structure that starts with a folder called Data. Inside Data are folders that start with your Group names and have a long UUID appended to the end.  Inside each of these folders are your macros, and they also have a very long UUID appended to the end of their names.<\/p>\n<figure style=\"float: center; margin: 10px\"><img decoding=\"async\" src=\"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2023\/03\/Macro-Repository-Updater-Data-Folder-Structure.png\" alt=\"Macro Repository Updater Data Folder Structure\"  title=\"Macro Repository Updater Data Folder Structure.png\" width=\"598 \" height=\"307\"><figcaption style=\"text-align:center\">Macro Repository Updater Data Folder Structure<\/figcaption><\/figure>\n<figure style=\"float: center; margin: 10px\"><img decoding=\"async\" src=\"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2023\/03\/Macro-Repository-Updater-Data-Folder-Naming.png\" alt=\"Macro Repository Updater Data Folder Naming\"  title=\"Macro Repository Updater Data Folder Naming.png\" width=\"597 \" height=\"222\"><figcaption style=\"text-align:center\">Macro Repository Updater Data Folder Naming<\/figcaption><\/figure>\n<p>So far so good, we\u2019ve got a Git repo filled with the current state of our macros.  Now let\u2019s say we go work on Mike Price\u2019s Hindenburg macro. We change a few things and it seems to be working. We can now run the Macro Repository Updater and it runs much more quickly because just that one macro gets exported to the Git repo. We can run the Git commands to commit that one macro and most importantly add a message for future us telling us what we changed.<\/p>\n<p>Now let&#8217;s say we break Mike&#8217;s macro and we want to go back to a known good version. This is when the second macro Dan Thomas wrote comes into play. The second one is called Macro Repository Importer, and it does what you suspect, it lets you restore previous versions of your group or macro source files into Keyboard Maestro. I haven\u2019t tested that part of the process yet, but I really should when I&#8217;m calm and haven&#8217;t actually just broken something!<\/p>\n<p>You can use Dan\u2019s macros to just keep version-controlled macros on your computer, or you can then also push the macros to GitHub or BitBucket or even another machine on your local network to make sure they\u2019re safe. I&#8217;m doing that with my macros and it makes me feel warm and fuzzy to know that all of these versions of the files are protected.<\/p>\n<p>Let\u2019s review the process to follow then to keep versions of your macros:<\/p>\n<pre><code>1.  Change\/create\/delete a macro in Keyboard Maestro\n2.  Run Macro Repository Updater macro\n3.  Either from the command line or a GUI Git tool\n    \u2043   stage and commit changes to that macro\n    \u2043   push to GitHub or whatever other repo if desired\n<\/code><\/pre>\n<figure style=\"float: center; margin: 10px\"><img decoding=\"async\" src=\"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2023\/03\/Git-from-command-line-for-macros.png\" alt=\"The process described to commit to git and push to GitHub all in the command line\"  title=\"Git from command line for macros.png\" width=\"599 \" height=\"471\"><figcaption style=\"text-align:center\">Git from the Command Line for Keyboard Maestro Macros<\/figcaption><\/figure>\n<figure style=\"float: center; margin: 10px\"><img decoding=\"async\" src=\"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2023\/03\/Git-from-a-GUI-for-macros.png\" alt=\"Git from a GUI called GitKraken for macos - showing list of previous commits and current file being committed along with its commit message\"  title=\"Git from a GUI for macros.png\" width=\"599 \" height=\"380\"><figcaption style=\"text-align:center\">Git from a GUI (GitKraken)<\/figcaption><\/figure>\n<p>The hard part is to remember to keep running Dan\u2019s macro and committing the changes right when you make them. I\u2019m sure I\u2019ll remember on the trickier macros but I\u2019ll make you a dollar bet that I get too lazy to do it on the smaller macros!<\/p>\n<p>Dan\u2019s macros are <em>really<\/em> well documented in his GitHub repository, so I\u2019m actually not going give you any more detail on it. If you use Keyboard Maestro and if you know Git, I highly recommend you check out his repo and follow <a href=\"https:\/\/github.com\/dagware\/DanThomas\/blob\/master\/MacroRepository\/MacroRepository.md\">his instructions<\/a>.<\/p>\n<p>I&#8217;m really happy that Dan figured this out, and I&#8217;m really happy that he gave it back to the community, and I&#8217;m really glad that Bart taught us all about Git.  Of everything he&#8217;s taught us, I think the miniseries on Git is the part that people write to us the most about saying they appreciate what they&#8217;ve learned.<\/p>\n<p>Now I have to go back and figure out how to get Mike&#8217;s Hindenburg macro working again!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I\u2019ve talked quite a bit lately about learning to automate things on the Mac using the fabulous tool Keyboard Maestro. Keyboard Maestro is essentially like a little programming language with a graphical user interface, but it&#8217;s missing an essential part of any document creation tool &#8211; there&#8217;s no way to save versions of what you [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":27933,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[147],"tags":[2064,1830,4307],"class_list":["post-27931","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-posts","tag-git","tag-keyboard-maestro","tag-version-control"],"jetpack_featured_media_url":"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2023\/03\/Keyboard-Maestro-git-logos-no-alpha.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/posts\/27931","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/comments?post=27931"}],"version-history":[{"count":1,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/posts\/27931\/revisions"}],"predecessor-version":[{"id":27932,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/posts\/27931\/revisions\/27932"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/media\/27933"}],"wp:attachment":[{"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/media?parent=27931"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/categories?post=27931"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/tags?post=27931"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}