 Hello everyone and welcome to today's Bite Size Talk. I'm very happy to have here Edmund Miller from the University of Texas at Dallas and he is going to talk about Git concepts. Off to you. I'm Edmund Miller. Thank you for the introduction. Let's get started with some quick Git concepts. Hopefully these will be of interest to y'all. So first we had the legend of the merge cowboy was a previous presentation on Git that we had that kind of kicked this all off by Alex Pelzer with the GitHub contribution basics. So the scope of this presentation I'm trying to cover some finer Git workflow things on these and talk about some different things that might help speed up your workflow and make your life a little bit easier day to day. There's also working with GitHub using this code and the GitHub CLI that Phil gave. This is kind of a continuation of that maybe a little bit more heavy on the Git side. Hopefully these will be useful to you. So a long time ago my appreciation of Git kind of started with GitHub offering me GitHub pro for students and giving me private repos and I'd never used it before but I fell in love with using Git. So first and foremost let's talk about rewriting history. So using Git commit amend is a handy quick little tool that you can use. You can also amend a message to it using the dash in functionality as well. This is when you want to go back and you forgot to add in a file or you made a quick little typo on the previous commit that you made. You can also use no edit as well and that keeps the the same message and doesn't even pop up an editor you just quickly amend the commit. So the issue with using amend here and rewriting history is that we start to change the commit hashes and those kind of starts to be weird when you start to push and pull with other people and sharing these branches. So that's a problem so it's not recommended for using this command when you're working on main master dev and collaborating with other people mainly if it's just you that's perfectly fine you can force push all day. So quick little example of using amend in practice from the CLI you have Git add in F core main and let's just say we added a function and then we decided that was a lazy commit message and so we wrote out function in full there and then oh we forgot to format the code as well and so we went through and we formatted the Python file and then we amended it with no edit and that's just kind of what this would look like in practice instead of adding all these like whoops forgot to have these changes commits on top of these in VS code with the baked in functionality I think then you can go in and commit and then you can use the commit amend and commit staged as well down here and click on those buttons to amend your commit messages and or add new files. You can also do this with GitHub desktop and go through in the history and basically you click on the history tab and then you right click on the commit and then you can amend that commit very quickly and just edit the message pretty simple to use from that functionality a little bit harder from the CLI to get right and this is just for the previous commit as well however I'm sure in GitHub they've kind of wrangled the underlying parts to make it quick to edit those and what's what's underneath the hood on those is using git rebase and so that's a fun little like common so we'll get through a fun little common scenario we'll talk about interactive rebase and then we'll talk about using it with pull by default as well so in the scenario let's just say we went in and we wanted to change all the steric sub-work workflows to enough test because we're a saint and so we've gone through we've done bwa mem bw mem 2 um and then drag map and then we've done this branched off of div so 100 sub workflows later we finally get finished and we get to test umi yay so we go to make our pr and we get in there but i know a wild maxim has appeared and so he's already merged another pr um he just moves too fast for you and then your branch is out of date and you see this button on github and github's helpful though and it tells you to update your branch what the problem is is you had this beautiful linear commit history and then now you have this weird like merge branch dev into enough tests that you're about to merge back into and then we update the snapshots because he changed the test profiles on us so what ends up happening is then we end up with this weird like double merge back in when you purge that pull request in um it's just kind of a weird thing and it's hard to follow in the history this is just a single instance you can then get multiple instances of the like recommits coming back in so the concept that we're trying to do here is rebase and that's just taking a new base for where we started so we started back there on that commit masters then now moved on without us we're taking our two or a hundred commits and replaying them on top of that new um dev branch that pexim is made for us so the command to do that would be get rebase origin dash dev um on those and as you can see we've just replayed our commits on top of the previous commits so in comparison here we have merge on top and then we have rebase on bottom as you can see the merge history is pretty difficult to follow at times um and you can't really tell where the changes are coming in from whereas in rebase you can clearly still see where are like what each commit is trying to do so it's much easier to review on pr and go through and follow someone's thought process instead of like where these merges happened and you don't know what where the changes are coming in from so github has recently added the functionality to just do this by default from the web UI if you don't want to do that yourself um and you can just click on the drop down arrows and then it will pull up rebase instead of just updating the branch okay so I also said that we talked about interactive rebasing so this is where you can go back and completely rewrite history and change everything so as you can see here we've got a master branch um that's out of date with my modules pr happens all the time module smooths fast so I've right clicked here on the master branch and then I'm going to rebase the current branch onto that branch so we click on it and then we click on interactive rebase and you may have to turn this on in your settings I think and so then this pulls up this nice interactive rebase window you can also do this in like the cli of course but these nice little drop downs and then you can see we can drag and drop and rearrange our commits in whatever order we want just so that they actually like mean something with the changes that we're making and that'll come into play when we talk about git bisect so um we're going to reword the commit here is what we end up doing you can also go in and edit it um so we're going to start the rebase and I'm going to log into my gpg key so I can sign the commit and so I'm just going to go in here and I had a little typo with the multi qc capitalization and then we're just going to save the file and we're going to pull back up git lens view that closes it by default and so as you can see now we have a nice um clean history where I've rebased the multi qc integration test on top of the master branch from those and our commit message is now cleaned up and we have the proper capitalization of those so in summary be a rebase ranger not a merge cowboy set this by default in your git config to whenever you run git pull it will use a rebase instead of emerge by default locally as well for you um it's a very handy functionality um it does what you mean to do rather than what you actually tell it to do with the whole merge thing so uh julia evans you don't follow her um also has a nice little um rules for rebasing um I thought it was nice to share this so basically a couple rules of like don't rebase a million tiny commits you're just going to run into a bunch of merge conflicts don't force push to share branch that ends up with like weird whole scenarios for your collaborators um don't try to do too many things in one interactive rebase just go back and do it again later um you can end up with weird things although I think the vs code in the gooey's kind of help with that um also don't rebase other people's commits because that changes who the commit author is and all kinds of the weird stuff going on um and then also you can just bail out of a rebase if you get into some weird scenarios which is nice you just need to use dash dash abort um and if you're not comfortable with it don't bother rebasing just keep using the merge merge commits and that's okay um so let's also talk about git bisect this is a handy little piece of functionality baked into git that I don't think a lot of people use so let's have a scenario where we broke something we don't know what happened we knew was working in this commit called c1 let's say that's like version one of the pipeline or whatever with git bisect what we do is then we go in and we split all of those commits that we have and we start in the middle and we say okay was this a good or bad commit is it still working or is it broken um and then from that we make a decision on which direction to go and then we go and find where we introduce the breaking change in the commit this is also why it's important to make small commit messages often so we can actually do this and not well we made 200 changes here but we don't know what change broke that so in practice what this looks like first we just give it a git bisect start command and we're going to give it a broken commit or tag and then the working commit or tag as well so in this case we're just gonna use head and 2.0 and so then we can do a log and we could say these are the good commits these are the bad commits and break those up that way and then we can say the nftest and then we can run nftest on it and let's say nftest passed so then we can tell git bisect this is a good commit and then it will move us on to the next commit that it wants to do and split us into the next part of the middle of that binary tree surge um on those and from that then we can then run nftest let's say it failed get bisect bad and then it will go the other way so in practice this is a pretty quick little workflow you're kind of doing it anyways to check these out and go back and look at them you can just kind of start to automate some of the searching between those but we love to automate all the things so let's even automate this more with git bisect there's a baked in command called run and then you can just pass it a command so what we're going to do in that is then we can automatically run nftest every time that we want to test the pipeline so you just pass it the git bisect run nftest command and then from that git bisect will automatically mark the commit as good if the test will pass and then it'll mark the commit as bad if if the test will fail um this might take a really long time in practice you can also just do an xflow run um and run each of those and go grab a coffee and it'll check all of your commits for you until it finds all the good and bad commits and then you can just come back and you can figure out where the breaking change was so I just wanted to include another summary for like visual effect of this of git bisect so basically we know where our stable branch is we know where the broken part is at the beginning of like where we like where we are now we don't know where the change is it'll take us right to the middle if it's a bad commit it'll take us closer to stable if it's a good commit then we move closer to broken and we keep going until we find where the broken commit was okay so let's talk about work trees really quick so have you ever had a lot of active branches going at once have you ever been waiting on get-of-runners to pick up your test jobs and just can't wait to start your next your next PR but I've got a solution for you get-of-work trees or git work trees so I also asked co-pilot to make some of these funnier as well and it didn't disappoint but I'll just let people read that in post so work trees basically what it allows you to do is instead of get cloning multiple times you can then just get you can then just have separate directories for each of your branches going at the same time this is really handy if you want to maintain multiple burdens at the same time or you're working on different features in parallel or your co-worker wants you to try to debug their their feature branch but you're working on your own so in practice these are different directories entirely and outside of the repository but the difference is you don't have to have multiple git clones so it doesn't take up a bunch of space on your hard drive so you can just do this directly in vs code as well you have the feature work tree and then you can basically just write new work trees as you write new branches you can see over here on the left we have the create work tree section of that and that'll also show you all the work trees when you start to use them this is pretty handy when you're working on modules and you have multiple module PRs going at once but you're waiting for people to review them so but you also don't want to like do multiple git checkouts and everything and you need to kind of go back and forth so for the cli purists this is what it looks like a practice it's a pretty simple command it's just get work tree add and then you can say your feature x this is how you remove that work tree and then this is how you check out a branch remotely from that and so these start to get a little verbose so there's a nice cli utility for called work tree switcher and that just lets you do some of these commands really quickly without making it really verbose and having to remember all the incantations okay so just wanted to touch on a few github cli things that I found useful filled with this is the end of his presentation and I had a few that I wanted to add I don't really like the github workflow where you have to fork a repo and then like push to your branch and then make a PR to theirs and then keep those all interchanged mainly because it's a lot clicks to go in fork and then clone my own repo on that so I made a quick little alias in here to fork a repo and what that looks like in practice is just ghf and then you pass the cli or you pass the repo url and then that'll create my fork for me and then it'll also clone my fork down locally so I can quickly get working on those changes another one that I like to use as well is merging a bunch of PRs at once and so all this does is it just goes in and lists all the PRs takes the PR number and then it merges them and so what a real world use case would be for this is just using this for any PRs labeled a certain thing so you could also take this and close all PRs that are stale for example in this case I'm merging all PRs that are have the renovate label and then merging them in which is really handy when you have a bunch of version updates and you've gone through and checked them all so with that an obligatory xkcd and I'll take any questions thank you so much that was very interesting and now I open this for any discussion and questions and comments so yeah yeah go ahead yeah so Edmund I uh while you were away I basically gave like a 10 second explanation of work trees I'm glad you ended up covering it we thought it might be too technical but you actually did a good job of explaining it but I was wondering how you were doing it in vs code so was that through git lens was like that work tree feature that you had separately I know you had the CLI tool when you were doing it in vs code exactly it's added in um git lens I don't know if you have to have git lens plus or not I don't think so I yeah I personally just use it in um McGit and emacs so this is just a screenshot from uh git kraken but I will definitely show the article on work trees through git kraken on those it was it was pretty good okay it seems like the git lens the git kraken work trees actually checks out the entire repo multiple times like it doesn't actually use bare checkouts um but I'm but I'm guessing the the CLI tool you showed does do it uh yeah I so I was trying to not cover too many like in-depth details on these and more so give people kind of a taste of some of the the different things but usually when you use work trees you would do like a bare clone I don't know if Ben talked about that while I wasn't here and then you would then use work trees to then check out a bunch of different ones is what a lot of people do yeah I don't I don't know whether they do that in git lens or not yeah I was just uh I was finangling with this just yesterday trying to get it to work and it seemed like seems like basically VS code doesn't really work well with bare checkouts so if you're gonna do work trees or anything like that in VS code it's probably better to just have every every branch you want actually checked out just the normal way and I think this is how git kraken does it anyway so I guess I just leave that as a warning for anybody else who tries to get into this is uh don't don't don't don't try to get into bare checkouts if you start seeing recommendations around that um don't don't start doing bare checkouts unless you're willing to just do it all in the cli or if you're using like vim or emacs git recommendation also the git by something was crazy I there's I feel like there's so many features in git that like are amazing like that and there's nobody knows about them and they've been around for years exactly yeah it's been I don't use it enough honestly I think it's the that's why I wanted a testing framework in next flow so badly because then you can do stuff like that so yeah it's fun okay are there any more questions or comments from the audience okay I have one more um and it's about rebase I am not entirely 100% sure I know what rebase does but I knew it you have to handle it with care and some people have told me that I never do rebase because they think it's too dangerous and I'm not quite sure I understand why it's dangerous like you said it it sounded like nothing can go really wrong but I guess there's reasons nothing can go wrong as long as you have pushed your branch to a remote repo if you're just doing it all locally and you haven't pushed anything you can blow away a bunch of stuff on accident if that makes sense versus like yeah merge commit you're probably not going to like destroy your branch or like rewrite the history in a weird way so yeah I'd recommend you push first then you rebase and move it over right so what is the worst case that can happen worst case you end up like rewriting all of your history in a weird way because you didn't handle the merge complex properly right that's like the worst case it's not any worse than like if you had a merge like a branch they were working on you did a merge commit and then like you had to then I guess roll back that merge commit yeah I guess you're rewriting the history is the problem so you can either duplicate your branch and just make sure if you're scared while you're learning to use it or you can just push it up to github um rebase and then just push over that branch is what I typically do thank you you're welcome if there are no other questions then I would like to thank you very much for today's talk and um and I also would like to thank the audience for listening so thank you all very much for staying until the bitter end have a good day