Episode: 3548 Title: HPR3548: Make a custom Git command Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr3548/hpr3548.mp3 Transcribed: 2025-10-25 01:15:13 --- This is Haka Public Radio Episode 3548 for Wednesday 9th of March 2022. Today's show is entitled, Make a Custom Get Command and is part of the series, version controlled. It is the 270th show of Klaatu and is about 20 minutes long and carries a clean flag. The summary is, Make a Get Subcommands with Shell Critics and Get Rent Pass. Hey everybody, this is Klaatu. In this episode, I want to talk about Get, specifically how to create your own Get Subcommands. You may have seen projects in the past that have added functionality to get. So you install the thing and then suddenly you have these new subcommands within Get. Get is kind of famous for having lots of subcommands. I don't think there's actually that many, but it does seem to be enough of a joke in the world that someone created sort of a website where it would give you fake Get Documentation for a bunch of fake Get Subcommands. It was actually quite entertaining. But if you do type in Get-Dash Help, I guess pipe it into less maybe, it doesn't even fill up a screen. That's not that many. So there's Get Clone, Get Init, Get Add, Get Move, Get Restore, Get Bicec, Get Diff and so on. So those are the subcommands or the verbs or whatever you call those, the second statements in a command that you use, I call them subcommands lately. Those are built in to get and in fact when you do a man get space clone for instance, you do notice in the name of the man page it's Get-Clone and that applies to any of the subcommands. You can do a man of Get space, any of the subcommands and it brings up a man page for a Get-Dash something. But if you do a witch on Get Space Clone, you don't get anything. So the Get-Executable itself is that user, bin, get or wherever it is on your system. You do witch, get, it'll tell you. And if you do, for instance, a file on that thing, on that executable, it is an executable, it's an else binary. So Get is parsing as a compiled option within Get, it parses what subcommand path you want to go down when you do Get space clone or Get space init or Get space, whatever. I'm making this point because I'm going to lever it or I'm going to do something different than that. But the principle is somewhat the same. Okay. So in order to create your own Get subcommand, I guess I could mention that I have created my own Get subcommand. And it's over on GetLab.com slash slacker media slash Get-Portal. I think I'll put a link in the show note, I guess. But it's called Get-Portal. Yeah, it's Slacker Media slash Get-Portal on GetLab. And it might even be Meridon GitHub. Anyway, it's a Get subcommand. So you type in Get space portal, whatever. And it does some things with some Get hooks and some Get commands and scripts. The point of it is that it manages, it's a very lightweight way to manage large binary blobs that are associated with your Get project. So it removes binary blobs from version control, which admittedly is not something you normally want to do with Get. And it was one of those things that was kind of particular to a project that I was working on, but continues to be particular to a couple of projects that I work on. So it's still a tool that I use all the time. And it's good because it keeps, it keeps big binary blob information out of the version control that I do need. But it keeps those large binary blobs associated with the project. And then there are things like get LFS and get annex. But honestly, those were both, I looked into them and they were both overkill for lots of different reasons, which I won't go into right now. Point being that I created this subcommand and I wanted it to feel like part of the Get system. I didn't want it to be another tool that people sort of had to remember to tack on to onto a project. It should feel integrated into the rest of the workflow. It wasn't necessary. I mean, it could just be a separate command, but I thought it might be nicer if it just felt like another thing that you do in get kind of fits into the workflow of your Get commands. You do a get add a get portal, get commit that that was the flow. And I felt like that was easy for people to kind of integrate into what they were doing anyway. So I wanted it to be, I wanted it to fit into into get very naturally. And the way to do that is to make it a sub command, making a script that you've written into a sub command of get is actually really, really easy. Get makes this very simple. It can be, well, it can be embarrassingly simple. It can also be quite complex. So I'm going to go over kind of two of them to give an example of what you might do. Okay. So first of all, before we go into into how to do that, I need to talk a little bit about get rev parse. So rev dash parse, rev parse is a sub command of get it's built in. And it's one that you may not have used before. You may have, I didn't start using it until I started doing a lot of get hook scripting. And then it becomes really, really useful because it gives you honestly kind of weird, weird functions that you don't really need outside of a script a lot of times. So for instance, get space rev dash parse space dash dash show dash top level. That shows you the top level of your get repository. And if you're a user, you're in a get repository, do you really need to know your top level? I mean, just look in the directory that you're in, right? Well, sure, but what if you're in a sub directory of a sub directory of a sub directory? The quickest way, potentially, to get your, you know, to sort of remember where you are is, well, honestly, PWD. We'll show you where you are and then you just kind of backtrack until you see the folder called myproject.get. That's your top level, probably. But again, if you need to know exactly where your top level is, you can do a get space rev dash parse space dash dash show dash top level. And it'll tell you home, so slash home slash class to slash my project.get. That's your top level. What is a top level directory? Well, it's, it's the outer bounds of the get repository. As far as get knows, that top level is the, the start of the world. That's where the universe begins. Get doesn't know there are directories outside of it. Get doesn't know it's on your computer. Get knows nothing other than the top level and everything below it. So get rev show top level shows you the, the directory with a hidden dot get directory in it. And you can, you can actually see that hidden directory with another get rev parse command called get rev parse dash dash get dash der and that shows you again, the top level and the hidden get level in, in the top level. This again, seems weird if you're just using get, you know, you, you probably don't need that. You just go to the top level and then you do an LS dash a or something and there's the hidden get folder where you can just go into the get folder yourself, although you probably shouldn't. So another cool rev parse one is get rev parse dash dash show dash CD up and that shows you how to CD to the top level. And so if you do, if you're in a subject, you have a subject and you do get rev parse dash dash show CD up, it returns dot dot slash dot dot slash dot dot dot. So if you're going to do a CD command and you, and you want to end up in your top level, get rev parse dash dash show dash CD up tells you exactly what you need to type in after CD. There are other functions to rev parse a bunch of different functions, but generally what I want to emphasize here is that if get get rev parse exists and it's got a lot of useful scripting utilities that will help you kind of get yourself above get, you know, it kind of gives you that sort of detached view of your get repository, which can be useful when scripting and it can also be useful when you're creating your own sub command. Here's more about that now that we know that get rev parse exists. So let's do a really simple hello world style implementation of this and then we'll do a more complex one where we're passing parameters and things like that. So I'm going to open up a text and I'm going to go to a demo directory so I don't clutter up my hard drive. Okay, that's good. So I'm going to open up a file called hello, no, get dash hello dot sh and the dot sh is somewhat significant is significant in this in this instance. So do add a dot sh if you're trying this yourself there are you can imagine different ways to do this, but the you'll see why I'm saying to specifically put a dot sh on the end of this one. So I'm going to just create this file shabang slash bin slash sh and then I'm just going to write echoes quote, hello, close quote, redirect slash temp slash hello dot txt. That's my exciting get script. That's the function that I want to give my users so that when they type in get space hello, they'll get a file in their temporary directory with the word hello in it. It's not very useful, but it's demonstrative. So now, so that that that file exists. So if I put that somewhere in my path, actually, I'll try mod it first, try mod plus x get dash hello. And then I'm going to move get dash hello dot sh into some location on my path. I have a binary, a bin told us slash bin directory in my home directory and that's always on my path. So now that it's there, if I execute get dash hello dot txt, nope, I'm an sh. Then if I do a cat of slash temp slash hello dot txt, I get the word hello. So that works. And now I'm going to trash slash temp slash hello dot txt because I don't want it to confuse me later. I don't want to false positive. So I've no hello dot txt in my temporary directory now. I've confirmed the script works. So of course, if I do get space, hello, it doesn't work. It tells me get hello is not a get command. And that's correct. What I can do now is create a second to file. And this one, I'm going to call just get dash hello. And in this file, I'm going to put a shabang bin s h and then I'm going to just give the path. I'm going to give the full path. You don't have to actually I won't just do get dash hello dot s h. So in this file called get dash hello, I am simply executing get dash hello dot s h. Now because get hello s h is on my path, I don't have to give it the full path here. You can if you feel nervous about it not being in your on in the user's path, but ideally you would have an installer that would kind of manage the paths. So get hello get dash hello, just launches get dash hello dot s h. I'm going to now move get dash hello to somewhere on my path. So again into my tilde slash bin folder. And now if I, if I type get space, hello, nothing happens because I forgot to cha mod plus x bin get dash hello. Okay. Now if I type in get space, hello, it doesn't tell me anything. But guess what? If I do a cat slash temp slash hello dot txt, there's the word hello. So file exists, even though I had moved it to the trash earlier. So this is a new version of that file. And that's how you make your own get sub command. So just to overview that again, what we did, we created one, one script file with a unique name. It could be anything. I mean, it could be penguins dot s h or just penguins. It doesn't matter as long as it's executable, long as it is, you can run this script. It's good. It prefer to call it something obvious, obviously related to the thing that I am building. So in this case, get dash hello was logical. But I wanted to distinguish this file from the front end file. This is kind of the back end business logic part of the of what we're doing. So it's get dash hello dot s h. That's put into your path created marked executable. You need to create a front end file for get to find. And that front end file needs to be the incantation you want people to be able to type into get as a sub command. So if it's get hello is what you want, then you need to make a file called get dash hello and put it somewhere in the path when you then type get space hello get knows to look in the path for something that matches that seek of that combination. And if it does exist, then get runs it get dash hello resolves to get space hello in get. Now in this case, my front end script was quite simple. It just launches get dash hello dot s h that's easy, but it can be more complex. So forget portal for instance, I need to pass arguments. You don't just type in get space portal there. There's other stuff you need to do like there's if you're going to add an image or a file to to your portal, you do get space portal space, add space, whatever file you want to add to your portal. So I needed those arguments. I needed to know what action the user was going to take are they adding something or they moving something. What are they doing with get portal and and what file are they targeting. So all those things needed to get passed through to to the actual the actual script that was getting run and and the hooks and all the things that were getting processed get rev parse is able to help you with exactly that. So if I go to get portal, I'll go into the file here. Okay, so here's the get dash portal command. And you don't really need to know what the get dash portal dot s h command is. It's a script. It has a bunch of different functions in it and does lots of different things depending on what kind of input it receives. But none of that's like that's just detail work, right. All we know is that we got a black box here called get portal dot s h and it needs some input and it'll provide output accordingly. So the get dash portal script to launch that is it's only like four lines. Shabang slash bin slash s h are equals dollar sign parentheses get space rev dash parse space dash dash s q dash quote. So s q dash quote is an option that get rev parse provides you to safely quote the rest of whatever command you're feeding it. So whatever is considered an argument or a parameter or whatever it gets quoted. So dash dash s q dash quote space quote dollar sign at sign close quote. So that's dollar sign at sign in in quotes and then close the parentheses. So the arg variable has just been set to the results of using get rev parse dash dash s q dash quote on dollar sign at sign which which represents to the shell that it it's the rest of the arguments. And second line is command or I just put cmd because I'm lazy didn't want to type cmd equals quote get dash portal dot s h space dollar sign arg close quote. So the command variable is simply executing get dash portal dot s h wherever it may be. I don't care. I have faith because the the the user has installed this somehow. So I have faith that get dash portal dot s h is somewhere in their path. So I'm just calling get dash portal dot s h space dollar sign arg where arg is of course the result of that get rev parse command that I just went through. And then finally the the final line is eval space quote dollar sign cmd close quote. That's it. You're done. So if I just go over to a back over to my demo folder here and do a get in it dot or I guess I could have just done get in it now I think and then I'm going to do while I need some content here. So I'm going to copy this pixel file that I keep handy from my home folder into my current directory. And now if I do get portal that is get space portal space add space pixel dot png then now I see that in my current directory I have a new directory called underscore portal which is the default name of the of the portal. It has a simlink from pixel dot png into the portal and that's how this that's how get manages this. And you do a get commit pixel dot png so you're committing the simlink rather than the actual binary file and I didn't add that yet get add pixel dot png there we go get commit dash in added a file close quote. And now I've got a get log that contains a record of me committing pixel dot png but I've got a repo without actually that does not contain pixel dot png it just contains a simlink to a known location underscore portal that contains the actual file that's what get portal does. It's simple in theory and works actually quite well if you if that sounds like something you want to try feel free to try it to been working for me really well for several different projects where I'm dealing with either really really large multimedia files or I'm dealing with so many multimedia files that just don't really matter to me that much. It's just the fact that there is a jpeg in this location so I use get portal quite a lot to abstract sort of the art from the craft and and it works out I mean it it it does remove things from version control so if that's not something that you want don't do that but if it is something that you want try it out get portal and and either way if you just need reinforcement of what I've just discussed in this episode that's the repository to look at get lab slash get lab.com slash slacker media slash get dash portal that's the that I'll have if you look in the bin file you can ignore all the you know the auto tools and the configuration files and stuff like that just go to the bin file there's get port get dash portal that's the front end get dash portal dot sh that's the the that's the business logic that's where it all happens that's the application that's the script there are some hooks as well so there are some things in there that that that you won't see but I think that those two files together should demonstrate really really well what I've talked about in this episode so I hope this helps you it's really fun and and cool to be able to just create your own sub commands don't get carried away I guess but it is it's a neat little trick thanks for listening talk to you next time you've been listening to hacker public radio at hacker public radio dot org today's show was contributed by an hbr listener like yourself if you ever thought of recording a podcast then click on our contribute link to find out how easy it really is hosting for hbr this kindly provided by an honest host dot com the internet archive and our sync dot net unless otherwise stated today's show is released under creative commons attribution share like