 First, I'm going to just take a moment. It's been two and a half years since I've been on the stage. So wow, there's people here. Right, OK, so we're going to talk about Git. Manuel, I already asked you all whether you use Git. Even if you don't use Git, even if you don't work with code, version management can still be useful. Because what is Git? Basically, it's a library. You have everything of the history of a project there. And it can be used for all sorts of document management. So if you manage the documentation of a project with markdown files, that can also go into Git. If you manage something else, again, with file-based documents, it can go into Git. It's version management with a big undo button. And you can undo and go back to it in the history at any point in time. Now, before we really dive in, I just want to make sure that we actually all are on the same page and understand what we're talking about. A lot of people still look at Git or at version management in a kind of old-fashioned way. They look at it as, OK, we have the primary, and then we have replicas. And those replicas talk with the primary, get their information from the primary, and give back to the primary. That is not Git. That is SVN, that is CVS. That is how we used to do things. Git works differently. You have a primary, but then you have a fork. And then there's another fork. And those forks can all talk together. And each of them contain the complete truth. And each of them can go a different direction, and there's still the complete truth. And each of them can be a remote for your fork. So it's not that there is one source of truth, one primary. There might be one canonical base repository from which everything started. But each of these contain the complete truth. So if there's one thing you take away from this talk, forget everything else I'm going to say. Remember this, there is no one truth. Every repo, every fork, even your local copy is the complete truth at that point, at that fork. And you decide which truth you use, which truth you want to believe. So if we're talking different forks, different forks can go in different directions. The original might just add a couple of commits and might have one branch which is still work in progress. But the fork might add onto that. And another fork might go in a completely different direction. And all of that is fine. All of that is a complete truth. These are their own truths. So if you have multiple remotes, you can choose and pick from each remote which bits you like. Am I losing anyone already? Or are you saying like, hang on, now suddenly Gith is starting to make sense. Good, now we're getting somewhere. OK, so when I do a poll, when I grab whatever is in the remote and pull that into my local copy, what am I saying? I'm saying, I accept your truth as my truth. When I push up to a repo, whether it's my own fork upstream as in online, or when I push up to a repo where I have commit access, I'm saying, my truth is now your truth. This is now the truth of that particular fork. So when I send in a pull request, what am I saying? Will you accept my truth as your truth? Correct. So when someone merges my pull request, thank you for asking. I accept your truth as my truth. This is how it works. And you don't always send a pull request to the primary, to the original canonical repo. You might send it to one of the remotes. The primary might be abandoned at some point. And one of the remotes has an active maintainer and becomes the new canonical primary. So this is how it works. All of them have the complete truth and you decide which truth you want to believe. Now when you send in PRs, if you create your PR based on the main branch, which is often called trunk, master, main, sometimes develop, if you create your PR based on that, you can only have one PR open at the same time. If you create separate branches, you can have multiple PRs open. You can have a PR in a separate branch for a documentation change and a PR with a code change in another branch. Why would you use different branches for that then? Why not have those two changes in one PR? So let me first repeat what you were saying. So you can easily merge them and you were saying, smaller PRs are easier to review and merge. Anyone else? Fullback? Okay, the simple answer is, what are the decision points? Every single decision can yield discussion. If you have a PR which has four decision points, then three of them might be fine and might be approved, but then there's still discussion on that fourth point. And because there's discussion on that fourth point, your PR is not getting merged. And those other three changes which were perfectly felled in their own right and should have been merged already are blocked because they're all in the same PR. So if there is a different decision point, use a different PR. And that might mean that some really small changes are in one PR, documentation changes. Then you have some CS changes in another branch and then you have a feature in another branch and a bug fix in yet another branch. That's fine. Branches are your save points. You can have as many as you like. How many of you have ever had a repo with more than 100 open branches? Right, you actually understand that they are your save points. Do manage your branches though, because as soon as something gets merged, throw them away because it's merged into the truth. Don't hold on to everything because otherwise it gets really messy in your head. How do we find a branch which is still working on et cetera? So how do you organize branches? You use prefixes. And this is just some ideas of prefixes you can use. You have to find out the prefixes you use yourself which work for your brain. For my brain, like if there's something I know I need to do but I haven't got time to work on it yet, I might just open a branch without any commits in it yet and just say to do with a little note on what I need to do. It's always a good idea if you create feature branches, if you create a feature or a bug fix to have the issue number of the track ticket or the GitHub issue in the branch name. So you can link it back straight away. You know what the reference is where the original issue was reported. If you're still working on something and it's not ready for commit, you work in progress. Or there might be something where you have a more complex change where you need to change something upstream in another repo which is a dependency for this repo. So you send in a pull request there but you know that you can only send in the pull request to make the change needed in your repo once that other pull request has been merged. So wait for it. I'm waiting for that other PR to be merged. And often I wouldn't annotate what repo and what PR I'm waiting for. PR, once something is a PR you can't make changes anymore as easily as you would if something is only local branch. So prefix of PR is an annotation to give an indication like, hang on, I need to be careful with this branch. I can't make changes without communicating to potential reviewers that I'm still making changes on it. So there's lots of different ways to do it and you have to figure out your own way. I mean, these are just some examples. But figure out your own way. The using prefixes can be a great way to organize your branches and to make it easier to find them back, find the right branch again. Make sense? Is this helpful? Yeah. Yeah? Okay. Now, I'm gonna take a drink because my throat is getting dry. But yeah, how to write history and get your PR accepted? On average, how many of your PRs get accepted? 10%? 20%? 50%? And 90 because they're small. That's a good answer. Mm-hmm. Right. If you look at history of a repo, if you see a history tree like this, what does this tell you? Someone was experimenting, this should never have been committed to the primary branch of that repo. But it is in one of the repos I work on. Not my commits, but still. What about this? Can you still follow what was going on in this repo? Or what about this? Is this better? And what you see here is that each of the commits also have a prefix sort of indicating what's going on. So it identifies what part of the code base that commit was working on. So when you look through the repo, look through the history, it's quite clear to pick out what commits are relevant to what you're currently working on. To get a clean history that requires foresort and discipline. And I'm not talking about deciding everything in advance and making those commits from the start straight away clean. Nobody works like that. Our brains don't work like that. Our brains are messy. We start working on a bug fix and then we notice, oh, hang on, that documentation is wrong. So we fix that documentation. And then we add a new test and they're like, hang on, but that test should have been, there's five tests for the same thing that should have been in a data provider. So you change that test data to data provider and then you add your own test. And hang on, now I have all those different changes. But I was only working on this one bug fix. So how do you work with that? Discipline you need is to make very small commits and commit often. Because that will give you a chance to reorganize those commits later into atomic commits, into logical groupings of code which belong together. You don't normally share that kind of messy branches with anyone. You have that locally and that's fine. Nobody needs to see the mess. Believe me, the branches I have locally you do not want to see. But once you have that mess and you've got the mess, but clearly annotated, okay, I'm doing something small here. I'm doing the documentation change there. I'm changing something to a data provider there. If you have those small commits, then you can reorganize them. You can pull them out to separate branches if they should be in a separate branch in a separate PR. You can reorganize the commits. And the whole fact of creating those small commits and committing often gives you the opportunity to do that. Now, what are the tools of the trade for that? Oh, sorry, I forgot. I haven't slide about atomic commits here. Okay, atomic commits. Anyone knows what those are? Oh, I can tell you something new. That's lovely. Atomic commits are basically a unit which is completely self-contained. If you make a bug fix and that bug fix ought to have a test, then that test is contained within the same commit. Everything that's needed for the commit to be complete is in that one commit. So if you decide, okay, well, I have a PR with three commits, with three different very related changes. And one of those changes is not accepted. You can just pull out that one commit, revert that one commit, and the other two commits can stay the way they are because their each commit is self-contained. It's past the CI, it has the test, it has the documentation, it's complete. Past the CI is important because every commit should be able to be merged. If it doesn't pass CI, your PR should not be even opened. And when I say past the CI, is anyone here looking at me like, what the hell is she talking about? Okay, CI is continuous integration. Continuous integration is used to do quality checks on your code. So for instance, to run your code sniffers checks, your code style consistency checks, or to run your unit tests, or to run security checks on your code. Those kind of things can be automated and can be automated to run on every PR, on every commit, on every merge. That's continuous integration CI. And I very much recommend you use that, yeah? I'll come back to your question because I know what you're saying and I often do the same, but there's a trick to it. Okay, so past the CI, they focus on those commits, focus on one thing. So each commit has one focus. There is no scope creep and it's so easy to get into the scope creep, but they focus on one thing and they're easy to review. Sometimes I have a PR with seven or eight commits and each of them is very interrelated and it all belongs together, but they each make a separate change. It's like storytelling, a little stepping stone, okay, this step is needed and then because I made that step, now I can make the next step and the next step and the next step. So they are interrelated, they belong together, but they are each separate changes. If you review that as one complete thing, you see one file with only red and green and every single line has been changed. If you review each commit individually, it's so much easier than that. Having those atomic commits saying, okay, this test belongs with this change, this test belongs with this change, this test belongs with that change, then it makes it easy to review. The reviewer knows exactly what you've done, can verify each commit individually and then say, okay, I now know the whole is complete and is correct and can merge it. Does this make sense? Yeah? Are you going to change it and scale the review in the comment or just all the changes in the... That the question is whether you would review as a reviewer individual commits or the complete thing with a complex refactor. Well, that really depends. On the one hand, it depends on how well the reviewer knows the code base. If they are intimately aware of where the code base, they understand really well what the refactor is you're going to do. They might just look at the complete thing. At the same time, if the refactor is extremely complex, that storytelling with those individual commits can make it easier. Like if I move some code from location one to location two, as a reviewer, I would want to know that there were no changes when I moved it. I moved it without changes. That's a separate commit. And then the changes I make are in the commit after. That way you can make sure that you know exactly what was changed. And that becomes a lot harder if you look at everything as a whole. And it depends. It really depends on how well you're familiar with the code base and what the changes are. If you're interested, I can show you some PRs at some point where I explicitly say to the reviewer, review per commit, because I know that's going to help them. And some others where I don't say that and it's up to them to decide what they do. Correct? Yes. Right, so what have we learned today? Atomic commits is storytelling. You take the reviewer through your thinking process. They're step by step. They are individual, self-contained changes. And if one of those steps is wrong, you can just pull out that step and all the other steps can still stay in place because you're using atomic commits, yeah? So tools of the trade. First off, amend. I've made a commit and I'm going to continue working on something and I run CI and I'm like, I forgot to actually run the code style checker before I made that previous commit and there's code style errors in my previous commit. As that is the last commit I made, I can just amend that commit. I can say, okay, I'm just going to rewrite some code. Just add that to that commit. I might even rewrite the commit message and say, okay, fixed. Make sure it's past the CI now. So you, amending a commit can be either amending it with file changes or amending it with the commit message change, but both can happen and you can still do that. That's fine. If you've pulled the PR and you've run CI online and all it throws up is a code style error, please amend the commit and do not create a separate commit saying fixed CI. That fixed CI commit has no value. It doesn't add anything to the history of the project. It's just saying, I forgot something. So amend the original commit and make that an atomic commit again because then it's complete again. Yeah, that's a meant interactive rebase. How many of you use rebasing? Can I invite everyone who did not put up their hands to learn rebasing? Pay very close attention to this part. It's gonna make your working bit get so much easier and so much more powerful. Remember that I said that branch is for your save points. Yes. Yes, create a duplicate branch. Just create a branch before you do the interactive commit. Then you have a backup and you can always go back to your backup. There's nothing wrong with that. And then you do your interactive commit of a rebase and if that fails and you get into a conflict and you don't know how to get out of it, just reset it and go back to the backup copy. Yeah, save points. Good. Right, so what is rebasing? A plain rebase is okay, we have a branch which is branch off at some point. The primary branch in the repo has moved on. Now I'm ready to pull it but I wanna make sure it doesn't conflict with any changes which have been made in the meantime. So I'm just gonna move this commit. I'm just gonna cut it off from where it was originally attached and I'm just gonna move it to the top of the primary branch again. That's a plain rebase and you don't need to do this just with one commit. If your branch has five commits, you can just rebase it on top of the latest commit of the master branch and those five commits will be on top of it. That's normal rebase. Now interactive rebase is where it gets really interesting. Say we have those commits here, four commits and one of the commits is because I made some local CS changes, I'm fixing something up. Another is like, okay, for the storyteller, for the reviewing, it's actually gonna make more sense if that commit would be before the other commit so we can just reorganize them. We can change the order of commit or we can group commits together and just merge them into one commit. How do you do that? You call interactive rebase, well, you get rebase dash i interactive and then you get a choice and you get a choice of what to do. You can choose to reword a commit and you just get to edit the commit message. You can choose to edit. Then the rebase stops at that point. You can edit the files and you can edit the commit message. Basically, you're amending a commit while it's rebasing. You can drop a commit. You can say, okay, that wasn't something I was trying but it's not actually relevant anymore. I'm just gonna drop that, not relevant. Or you can fix up and that's squashing those two commits together. But hang on, there's also squash. I'll get back to that. The difference between squash and fix up in a minute. And you can say pick. Pick means I want that commit but you can still pick that commit and then move it in a different place in the order of things. So what does that look like? Okay, so I'm adding a feature here. I started with a failing test. Like you said, then I'm working on the feature then I add some more tests. I add helper methods. Maybe the helper method should have been before the feature. I work some more on the feature, some more on the helper method, et cetera, et cetera. You can see what I've been doing here. And this is how a normal human brain works. It's messy. Now we're gonna create order from that mess. So I'm gonna do an interactive rebase. I get this screen in which I can edit what I wanna do. You can see by default everything is set at pick. Now I'm gonna change that. And I'm gonna change it like this. So the F means those two, I've moved things around. You can see that the helper is at the top now, the first commit. I've moved all the commits which are related to the helper method next to that. And I'm just gonna fix up that commit. I'm gonna pick that failing test. I'm gonna squash the feature into it. And then I'm gonna fix up everything else with that. What I end up with if I then save this and run it is this. Two atomic commits. So yes, very often when I start working on something to answer your original question which you asked earlier, I often create a failing commit first, a failing test. Locally, I will create that failing test because that failing test proves that the bug exists and it's very helpful to make sure that the test is actually failing. If I would commit everything in one go straight away, I cannot verify that my test actually tests the bug fix because I can't verify that it's failing because it's together with the fix. So locally, I would have that failing test separately but then by the time I send it into a PR, I merge them together because they belong together as an atomic commit. At the same time as a reviewer, if it's a complex bug fix, I may go in, check out that commit, just undo the feature change, the bug fix and run that test locally to verify that that test is failing before the bug fix goes in. Does that help? Does that answer your original question? Good, what I just showed you, is does this look like magic to you? Does this look helpful? Helpful? Good. If you want, I can do a live demo in the question bit but yeah, let's first see if we can get through the slides. Now, the difference between squash and fixup. Squash basically says I wanna merge the file changes so the changes in the files of multiple commits, I wanna squash them together and I want to edit the commit message. I can get the commit messages of all those different commits and I can combine them and I can rewrite them so the commit message encapsules all the information. Fixup also means I wanna combine all the changes except I wanna keep the original commit message of the first commit which I'm using. So if I have a commit where all the commit messages is add to that helper, that is not a useful commit message. That's just a note to myself that that commit belongs with the helper function so I don't need to keep that commit message, I can just fix it up. If I have a commit message where I say oh hang on but now I'm adding some more information because I have had some more insights and I actually have a good commit message for that commit then I wanna join those commit message together. So when you wanna join the commit message together you use squash, if you wanna throw away the commit message except for the first one you use fixup and I know you might think like hang on but I'm gonna make so many mistakes. Again, use those save points, use temporary branches, experiment, go and play with this. When I first started with it, I made so many mistakes but once I realized how it worked and actually understood and saw the changes starting to work the way I wanted to, it became my power tool. I live in interactive rebase. How are we doing for time? 10 minutes left, okay. Right. I've already mentioned all this so let's move on. The next bit which is actually really interesting if we're talking about interactive rebase, if we're talking about the squashing and fixup and editing that commit message but whether you're amending a commit or whether you're doing an interactive rebase, we also talk about commit match. So let's, let's pause there a little. What's a good commit message? I already give some hints here but why are these things important? Someone. For your future self. For your future self. Absolutely. Well, what other reason? Absolutely. Yeah, okay, you get two years on and you want to change it and you're like, what the hell did that person do here? Which may have been me. And you go back and you look at the commit message and now hang on. Now I understand what the reason was behind this change and maybe I should not change it but do it in a different way that fix which I want to make. It cannot be too long. And this is really important. I see a lot of people who have very short commit messages and then have a really long description in the PR. Please do not ever do that. And there's a very simple reason for it. What if you move from GitHub to Bitbucket? You lose all that information which was in the PR. You do not lose your commit messages because that remote which used to be GitHub now has a fork and it lives on Bitbucket and all the commit message are still there. All the commit information is still there but your PR information is no longer available. So keep that information in commit message. Make those commit messages useful. So what does it look like? Often I often use a prefix to just indicate what part of the code base I'm working on, short description, long description. In that description, describe why you're making the change, what you're trying to fix, what the alternatives were which you considered and why you decided that this was the right way to fix it. This will help your reviewer but it will again also help your future self. And also something which I know few people use, give credit where credit is due. If someone helped you with that commit, if you created the commit with PR programming, if someone inspired that commit and you looked at their code for an example on how to do it in your code base, give them credit, co-altered buy. And if you look for commits with co-altered buy in GitHub, you will see that it actually shows both avatars. Both people get credit for that commit. Credit where credit is due. We are working on open source. Why claim something out of your own if it's not? Leaves your ego out at the door basically. Okay, now how do we work with this? How do we create those small commits? Because again, brains are messy. So we've been working and okay, we've made all those things but now how do I make those small commits because I didn't do that while I was working on things? Well, you can cherry pick. And you can cherry pick individual commits, you can cherry pick files, you can even cherry pick lines. You can cherry pick them when committing. So you can say, okay, I'm just gonna stage a few lines and one file and the rest of my changes, I'm not gonna stage yet. I'm just gonna commit this first and then I'm gonna stage another part of what I fixed and make a separate commit again. You can also pick things from other commits or even from other branches. Cherry picking is useful, but once you've changed things and now you have a PR open and there's a conflict, what do you do? Do you do a rebase and force push? Or hang on, say a CI fails and the PR is open. You've already basically asked someone, look at my code, review my code. To force push or not to force push, it depends on, in large part, on the conventions in your project, but basically if it's a non-collaborative branch, you've not pulled it yet, force push it will. Feel free to force push, nobody's looked at it, you're fine. If you've pulled the branch, you've rebased it but not made any changes other than maybe fix a conflict, force push it will. But do leave a comment in the PR rebased without changes so the reviewer knows you've not made any changes. Depending on the conventions in your project, if it's been pulled and you fix a typo or CS fix, maybe it depends. Sometimes the reviewer might prefer to see a separate commit so they know what's been changed and then they can squash them together or merge. I would recommend squashing them together and merge then. If it's a non, if it's a collaborative branch, you're working together and someone else might pull in changes, you might pull in changes, you might push changes, someone else might push changes, please do not use force push because you might overwrite someone else's change and you really don't wanna do that. If you've pulled something and the review has already started, do not use force push because you will confuse the reviewer. They will not know what you've changed. They can't see the difference if you've made a change in the original commit and then they don't know whether you've fixed up what you needed fixing or made a completely different change and they need to do the review completely all over again which is wasting their time so let's not do that. Yeah? Okay. I'm very briefly gonna go into when things go wrong and then skipping a lot of the rest because I also have when things go really wrong and when things go really, really wrong. If you really wanna know, ask me in the questions. I'm just gonna do this bit and then we're gonna go and have some questions. Okay, when things go wrong, reset and refer to the rescue. What is reset? Reset is basically, okay, I'm just gonna go back. I'm just gonna remove that one commit. You can do a soft reset. That means I'm gonna remove the commit but I'm gonna keep all the fault changes and that allows you to commit them again in a different way or you can do a hard reset and then that commit is gone and your fault changes are gone and you can start with a clean slate. That's reset. That's something you only do locally. You do not do that on a public branch. On a public branch, if something has gone wrong, you referred and what I referred is, is saying, okay, we've had a commit. Now I'm gonna basically do the complete opposite of the commit and refer to those changes and that doesn't have to be the top commit at the top of the branch. That can be an earlier commit as long as there's no conflicts. You can still refer to it but if you refer to it, it adds an extra commit which undoes those changes which communicates to other people. Again, okay, we've stopped that change. We're not gonna do that and other people can build on to it again. Make sense? Any questions on that? No? Then I'm just gonna skip over some slides to work the end. Whoop. Can I, yep, let's see if I can quickly find that part where I wanna go to. Right, this bit. Now a lot of people are very hardcore and say, oh, you need to learn to get on the command line. You need to really understand all those little commands and all those little parameters and you need to remember it all by heart. No, you do not. You need to know the terminology and I've used the terminology here. Rebase, revert, reset, amend. That same terminology is used on the command line as well as in GUIs. But if a GUI works better for your brain, please use one. When I started using a GUI, my productivity went up by 300%. I've never looked back. I've never since that moment ever, ever, ever used Git on the command line. So use the tooling which works for you. Start experimenting with some GUIs because especially like how those branches work together, cherry picking from other branches, those things are so much easier when you have a good GUI. Find one which works with your brain, with your visualization and then Git in comfort. Right, questions. Questions about the atomic damage. Yes. How you describe that is pretty much the same thing that's called stacked branches which is used by a lot of companies. Because that's a branch on top of a branch, a top of a branch, and you're reviewing each branch individually, which is basically how you describe how these should be reviewed when they are atomic. No. Okay. Stacked branches are often branches which depend on each other. If you would pull those individually, they would conflict. So if you pulled them individually and one would get merged, and the other one is still open, they would create a merge conflict. That's why you stack them. Atomic commits, you can have a PR with just one atomic commit. A PR doesn't have to have multiple commits. A PR with one atomic commit can be just a soluble or a PR with multiple atomic commits. If you have stacked branches, those stacked branches would still use atomic commits. But the stack has to do with preventing merge conflict between your open PRs, while atomic commits don't necessarily have to do with that. Does that make sense? Yeah, it does. So basically it's all about ranking and order. Generally, yeah. You're looking at varying jobs, and the other one didn't start in the same door and don't want backing. Absolutely. So with stacks, more than anything, you want to prefer to prevent merge conflicts. You know that if the next change depends on this change and this change needs to be merged, otherwise this change can't be made. That's why you use stacking. More questions. Or is everyone just desperate for lunch? That's fine as well. Please, hang on, there's a mark behind you. Was there a reason GitHub desktop wasn't included in the software comparisons? Not particularly. To me, it's never... I mean, I tried it when it first came out. It was not feature complete, and it really didn't work. It wasn't that user-friendly. So of the tools I listed, those are the ones which have a better reputation than GitHub desktop itself. That doesn't mean that GitHub desktop might not have evolved to a point that it should have been included. I did not re-evaluate it. Okay. Tower, I think that was on the slide, wasn't it? Oh, sorry. Sorry, yes, could have definitely been on the slide, but I only had eight slots. Right. Right. Is an ongoing discussion in the team will change log entries to be part of the commit for the feature or to be separated? Oh, yeah, that's a process flow thing. Generally speaking, it really depends on how large the team is which works together. If you work on your own on a repo, yep, please add your change log entries with your commits. That's fine because that again makes them more atomic. At the same time, if you have a large team working on a project and there's 10 open PRs, and each of them adds a change log entry, believe me, that change log entry is gonna conflict because everyone's gonna add their change log entry at the end of the existing change log, and now we have 10 different change log entries which are all on the same line. So it depends on the project, it depends on how many contributors there are, what the discipline is. Sometimes one of the tricks I see used is have a template for a pull request where you ask people to add a change log entry, and then the committer which merges the PR adds the change log entry to the change log as the next commit, or squashes it into that commit at the point of merging because at that point you won't create a conflict but if they are already in the PRs, they will very easily conflict. So in big projects I work on where there's lots of changes in a release, I normally just milestone everything. There's a little tool in GitHub you can enable to force every PR to have a milestone and you cannot merge without milestone. And because of that I can just select a milestone, it will show me the whole list of every single PR which was merged for that milestone and just go through them, spend half a day going through them and just listing the change log then. It depends on the project. I can't give you advice, but yeah, there are some considerations there. Having them always in the commits is asking for merge conflicts. Okay, more questions. So you are very active on GitHub. So the question to you is, I am. You are very active on GitHub. Yeah. You have a lot of rebels. So the question to you, do you merge and commit? No, merge and score or just merge? Again, it depends on the convention of the projects. In a lot of projects I merge because it also shows that there was a PR and what was happened. There's also one project where we actually have forbidden to merge with forbidden squash. We only allow rebase merge because that was the convention in the project before I became part of it. And it depends really on what you agree upon with the team of people who have commit rights. Like in WordPress core, basically it's all rebase mergers, but then it's SVN. So, yeah. Yeah, because when Adobe commits us, you show them separated and easy and understandable and so on. But if it's just a breakdown within the branch while working on PR? That should not be a PR. Now, seriously, that should be a work in progress branch. Maybe a work in progress branch you've shared. You might have shared it as a draft PR, but it should not be an open PR if it's a breakdown. Okay. More questions. I'm starting to get a feeling that the questions come from the usual suspects. Just a small one. What about the instance and the workers, for example? Do we need to thank kids and next users? It will be 6.1. My future will be merged. So, I use the next version. Or should I use the 6.x or something like that to leave it to the committer to use the version which is this patch? You're talking about track where the little drop down which version it should be committed to or? No, no, no, the code. The AdSins. Oh, the Sins tag in the dog blocks. Okay, generally new features only go into majors, so then you already have your answer. For anything that is not necessarily a new feature but a bug fix, use your own judgment. Look at the track ticket also where it's milestoneed in track and the committer might just adjust it depending on what the actual reality is gonna be. And patches sometimes stay open for years, so there might be patches still out there with the Sins 4.8 and it hasn't been committed yet. And I do feel sorry when that happens, but it happens. So don't let yourself be bound too much by that. Just use your discretion and judgment where you think it belongs. Submit the patch and then the committer can make that final adjustment. That's okay. I'll be around, you can ask me questions later. Thank you for all the questions. This is what I'm considering with all the questions. Thank you very much. A warm round of applause.