 Thanks Autodesk for having me. Thanks Rumpi Giz for having me. Actually, I was pulled into this. Yeah. So I'm going to talk about debugging with Git. So Git is not just a conventional source control system, right? It's a very powerful tool. It has pretty much everything that you need to control your code base and control your source tree. And debugging is kind of like a side effect of it, but it's a powerful tool for debugging as well. So this is kind of like a beginner to intermediate talk. So if you're already familiar with all the concepts here, just bear with it. I think some people will benefit quite a bit from it as well. So the first part of the talk is going to be about the prerequisites. Before you can actually use Git for debugging, you have to satisfy some sort of requirements first. Because the biggest requirement, the first requirement is that you have to have smaller modular commits. I'm sure if you've been working in a team, probably you'll get your ass kicked about this a lot. And I'm going to kick your ass again. If you're not doing this, please do it. The reason is that you have to walk through the Git history in order to know what's going wrong in your code base. If that's a bug, it's a defect, for example, you have to walk through the Git history and understand why that happens. So if your commit is not small and modular enough to be read and understood, then that's impossible. So the second requirement is your commit message has to be descriptive. And don't be like myself three years ago and do something like this. It's pretty embarrassing and stupid. When you look through your Git message, you should probably have a good idea of what a commit does. If you have to use the word end in your commit, then you should think again. Things like cleanup and refactoring probably are not very suitable for a small and modular commit. You should break it down to two commits, one for cleanup and one for refactoring. And even better, you should break down into cleanup something, cleanup like a user model, for example. Cleanup one file, refactoring one file. And why do we have... Oh, sorry. So when you have a big change, I think a lot of you go through this problem a lot. You're developing and you forget to commit often. The best way is to always commit when you do something and then it works and then commit it. But you can and you forget to do it. And then you have a big chunk of code to be checked in. Then you can use the dash P option when you're doing a Git add. Does everyone know about this? No? Oh, great. So yeah, if you provide a dash P option when you add a file or adding a folder, for example, it will show you all the chunks, all the code pieces that you can pick which one you want to go into a commit. So doing it that way, you can break down a small chunk of changes into smaller commits. And yeah, the reason why you need that is think about Git history as some sort of an event system. Each commit is like a record of something that has been changed in your code base. And if you put a lot of changes into one commit and you lose a record of all changes inside. So this is going to come back again when I do a live demo. I'm going to show you some techniques where you can go when it comes to debugging. So let's get to that now. Oh, and almost all changes in your code base should be recorded. Again, using smaller modular commits. So debugging with Git, basically the main philosophy is that you have a system. You have an application, for example. And things were working fine yesterday or some day ago in the past, but now it doesn't. So some features just got broken. Someone stupid just come in and check in some bad code and break everything that you've been working on. So debugging with Git will be able to help you resolve that problem. So I'm going to go through some scenarios and do some live demo, hopefully they'll work. Yeah, so the first scenario is that you have a defect of the bug. And if you're the one working on the code related to that bug, you probably will know which file contains the issue. So if you know the file, you can use either Git blame or Git log to go through what all the changes have been done to the file. So I'm going to show you an example right now. Just clear that up. Okay, I have a project here that I've been working on or I used to work on in the past. And yeah, it's basically a Ruby gem. And this project is incubated by Ruby on Rails organization. And if you're a Rails developer, any Rails developers here? Oh, wow. So I worked on this in the past, but I haven't been working with it for a long time. And I just checked it out the other day and I saw something different. Suspicious commit. And if I do that again, hopefully it's the one I'm looking for. So there you go, I have my white border. So it's a pretty useful tool. And now since the change is very small, I can really look through this and understand what happens, whether it's intentional or not. And probably hopefully I can get my white border back. So if you are the one working on the file and you know which file contains the issue, you can go with git blame and git love. They're very powerful tools. But it's often time that you don't know that, right? If you're new to the project or you're fixing some bugs that's someone else. Right? Yes? I'm so moved to git, but like, no. Can I run two git folders? No, two git archives on the same folder. Sorry, can you review that? Can I have two git histories? Two git histories? For the same folder. I don't think you can. I'm thinking to run one every minute. That's a commit. And then doing a totally separate that I do manually. You should use branches for that. Are you familiar with git branch? I always see the issue. And I make some changes to some project on git helping. Yeah, so, I don't know what you're saying this. Maybe you can talk after this. Okay, so the second scenario is that if you're not the one working on the file and you don't know which file is the one you should be modifying. And seriously, you have no idea. So you can use git bisect. It's a very powerful tool as well. What it does is that you'll run a binary research process similar to this. So you know that the current commit is bad. And then some time ago, you can go through the history and see that there's a commit that's good. So like the commit I just checked out earlier is a good commit. And I can mark it as bad. So I can mark the current head as bad and that commit as good. And git bisect will walk me through the binary research process. You'll go to this commit in the middle and then I can test and see if it's a good one or a bad one. And then you continue going like that. You'll go to the middle and then it's bad and then go to here and it's good. And then this is the one I'm looking for. So it is pretty powerful. I want to show you right now. Is this commit based on branch or is it on file? It's on my branch. So given this process, you don't really know what file it is targeting. It's just that commit you're targeting. So what you're looking for is a commit, right? And then if you do git show or commit, then you'll see all the things that the commit does. So basically it's touching this web console HTML file. Yeah, these are the things that have been added and removed. One commit can have more than one file also. Sorry? One commit can have more than one file also. Yes. So that's why I was saying that if you really want to do debugging easily, then it should have very, very small commit. And if there are more than one file changed and you don't have a really good reason for it, then probably you should back it down. So you would commit per file? I would personally do that. But if you don't want to, if multiple changes in multiple files correspond to the same feature that you're committing, then it's fine. But I highly encourage you to do that. Because if you want to group multiple commits together, you can do it with pull requests. But a commit should be atomic. Sure. But very often the single commit, if you do it on the file level, it may not work or it may only fix part of what you're trying to do. Yeah, you can use steps for that. So if you're adding a new file and it doesn't do anything, if it has the function call, it can just return something. And then it works. It definitely works. It will run and it doesn't break anything. And then you can start adding more stuff to it. It's more like a process thing than a technical thing. You just have to be disciplined to it. I lost what I'm doing. Oh, automation, yes. So this is on the assumption that we are debugging on the branch where we have made all the commits. So let's say I have a front-end commit to that branch. And then I integrate to the next level, right? All that history will be gone. What do you mean by the next level? Okay, maybe I'm not very well versed with the big things. But master, let's say master. I have my own branch. Yes. I have 40 commits. And then I integrate back to master. Yes. That will go as one commit, right? It will be treated as a merge commit. 40 commits. 40 commits. And then I can debug master in the same manner? Yes. Unless you squash them. Yeah, if you squash them, then it's just one commit. Then that goes right. Then you resist. Yeah. Okay, automation. GetBicycle is pretty sweet as well. You don't have to do all of that manual step yourself. You can just write a test script and then do getBicycle run with a test script. And if the test script returns with a status code of zero, which means that the commit you're testing is good. So we can automate all of the rails, start server, and then go to the browser and check for the white border easily by writing a test script. And again, just go and grab a coffee and go back and then you'll find it for me. It's pretty sweet. Yeah. But the third scenario is very, very complicated. Is that if you go through the getBicycle process and you find one particular commit that causes the problem, but when you look at the commit, you have no idea what it does. It makes changes to the file that you don't understand. You don't know the code that it tries to change why it was created in the first place. So in that case, you have to walk through the entire getHistory and make a snapshot of the getHistory related to the problem that you are trying to debug. You have to do this in a manual process, but I can show you it's fairly easily done as well. So let me go back to master. Master is very far ahead from the branch that was done away with you. So now all of the code structure has been changed a lot. There's no action dispatch folder. Everything is inside a web console folder. And inside that folder, we have templates. And inside templates, we have multiple template files. There's not just one file anymore. And we have this style of CSS.ERB. This is the one that contains all of the CSS files in master. And if you do a getLog of that file, it's only one commit. What does this mean? If this is the one causing the problem and there's just one commit, you can't do anything. This means that this file is either brand new or it's broken down from another file. And in order to verify that, you just have to look at what the commit does. And there's a huge chunk of thinking here, which is why I said if you have really, really small commits, that's a lot easier to go through each individual commit and then know what it does. I can just search for my file, the file that I was looking for. Yeah, so this file is basically renamed from... Yeah, so this is the one deleted and this is the one added. So style.css.erb was renamed to... Yeah, style.css is renamed to style.css.erb. So if I want to know what happened to this style.css, I can just check out the commit that happened before that, which is the commit that creates the style.css file. And then I can still have... I have the style.css and I just do a getLog again. But again, you have only four commits here. It's still not enough. I want more information because I want to find out why this code is added at the first place. So if it is a problem and I haven't worked on the code, I'm not the one writing it, then I need a lot of information in order to understand what it does and why it doesn't behave the way I want it to. So the same thing. You can just check out this commit and go back to the commit before that, which is the commit that before creating or renaming your file. And you check that again. Style.css.erb. So style.css.erb was renamed to style.css and is renamed to style.css.erb again. So if this thing continues, right, then if you just do a git bisect and you get the very first commit that's bad, you have no idea what goes on. You need to understand why this crazy behavior happens. Probably some programmer thinks of some brilliant idea and then it doesn't work out. It's not the case here, but... Yeah. So if you log the file again, again, there's only one commit, it's still not in half. You remember when I did the... What if you commit every minute with a timestamp? You will be able to read everything. You will be able to read everything, but your commit will probably not make sense because your commit needs to work. Yeah. You have some changes that something like add a new file or delete some file and it doesn't contribute anything. And the commit message is important too. You read... This is a very good commit message, right? It says extract something or something which probably means that there's a file that's been broken down into smaller files and then, yeah, this timestamp is just getting quite big and blah blah blah so I need to break it down further. So this is very, very descriptive description. It helps to understand what the commit does even though the commit is rather big. So if you commit every minute, you lose that very descriptive message. I usually have a descriptive message on top of each function. Top of each function. Yeah, but the message is for the change. Yeah. That's why you're making a change. Yeah, why you're making a change. Yeah, I'm looking at this because if you're going to make a very huge editorial responsibility of these commits, you will spend a lot more time just putting in the timestamp and reading step by step backwards. Well, it's a good investment. Think of it as an investment, right? You get a timestamp, you know, a lot of commits that don't really make sense when you go back to the commit to time traveling, and you won't be able to understand what they do. This is documenting. Yeah, basically documenting. It's like in your life, right? In some stage of your life, something happened and you want to make sense of it. Like you'll get married while you get married or something. Yeah, so... It's the same process over and over again until I can... So you can see here now, if I go back one commit earlier, then we have this session.shml.erb file, which is the only file that's under template. And remember the commit message earlier? Extract template, rendering, and split into template files. So this is a big file that we're talking about. Now if I go and git log the file and it would show me some changes to it, and if this provides enough information for me to start debugging, then I'll just stop here. But you can go on and on, keep walking through the git history until you find probably until the beginning of time when something was introduced, some features introduced, and then you have all the information you need. You understand about the system, you understand about the problem, and you can start debugging with that. So I'm going to stop here, but you can actually go further and then go to the underscore web console, the html.erb file that was showing you earlier. So some food for thought, actually. My live demo is done. We'll see that again. Can all of this be automated? It actually can be, right? Git by-side can be automated using a test script, as I mentioned earlier. And the whole process of walking through the git history also can be automated. The problem is that your commit is not good enough for you to write any script that passes the commit and do something with it, like walking through the git history. It's basically the same process. You go git log and then get the first commit, the changes in the file, and then check out the commit before and then it goes through it again. So if you can classify the commits into different categories, git basically acts on files, right? And there are only a few things you can do with files. Either you're adding a new file or deleting a file, or breaking down a file into multiple smaller files, as I showed you earlier, or you're making changes to the file. And it's just that. Each commit should do one of the four things and nothing more than that. This is a little bit out of control because as a developer, you can't be disciplined enough to do something like that. So I'm thinking about something, some sort of a abstraction layer on top of git that influences this kind of behavior. But it's just some thoughtful thoughts, seriously. But the same is my philosophy in theory that this whole thing can be automated very well. And then think about, imagine the future, right? If your user reports something wrong with the system, some new bugs were introduced, and then just run a single command and give you all the information that you need through the git history, and then you can have everything you need to start debugging and start crafting up a solution. It's pretty powerful. So git is awesome. Use it. If you're not very good at it yet, just keep working with it until you're better, I think. Yeah, that's it. I got a quick question about renaming files. It sounds like from what you say that the moment you do a git mv, you should commit before you work on the rename file. Renaming file basically to git, it means you're deleting a file and then you're creating a new file. And then there's some reference to that as well. Exactly. Yeah, so if you rename a file, probably you should commit. Immediately before you work. Before you work on something else. I think you should change the references also to this file before you commit or not. Now, git will do that automatically. So to git, basically you're adding a new file and deleting an existing file. But if you commit right away, and you look through the commit message in the future, and you know that you're basically just renaming a file, and you shouldn't miss your changes into that as well. I think that's my mistake. I've got a lot of trouble with that. The log history of files when you're renaming. It's probably very hard. It's very, very hard. So what I did, right, as you can see earlier, you should keep the history of when it's renamed. So this file is actually renamed from a style of CSS file. And you can do git log dash dash. Which means you'll provide the logs of all the commits that happen to the file which has been renamed. This is the one that appeared in the past and doesn't appear now. And you can still do that with git. But the problem is in this scenario, right, you have a file, file A has been renamed to file B. But then you'll rename back again to file A. And then it's impossible to just look through all the changes. And you have to walk through the git history, go back to the commit before when the file is renamed, and then you can log it and see the commits before that. Does the follow option work? Follow option? So git log has an option called dash add follow? Let's just try that. I haven't tried that actually. This? Yeah. It's still... Wait, let's move... If you don't have the follow option... Oh yeah, it works actually. It's pretty good. Yeah, it works. Thank you. So basically when you rename a file, it sort of keeps track of it based on the similarity of the deleted file and the created file. And you can... I think in log or some other commands, you can actually delegate how much similarity you wanted to keep in mind. So I don't know the exact option, but it has it somewhere. It can do that? I thought it's like keeping an i-note of the file or something. I don't know. I also don't know. Yes. That would be a silly question. Just you mentioned of file A renamed to file B then back. Yeah. So if this happened in the past, then is that a way for us to correct it or, you know, make less trouble to the... For the future. You have to do it yourself in the present. You cannot go back. Well, I encourage you not to go back and then make modification in the past because it's very nasty. You want to keep a record of all the things that have been changed in the system and basically don't keep lies because if you go back and change something, it's just a lie. So yeah. So my colleague has this... My colleagues has this nasty habit of checking out git and then after that copy it to another folder who changes there, take a bunch of files and everything move back to the git directory. Yes. Copy it and there's one whole change. Yes. How do I tell them not to do that? I think those are called standard operating procedures. Just kick their ass, really. Get the precom calls. In this folder, there are lots of checkouts that are happening. Yes. In real time, all that happens is when the issue comes in, whenever we are working on the other task. Yes. So what will happen to the files? Consider I do a checkout. Yeah. And at that time, I already had some files which are made. I was able to do it. Yes. So all three are sold. So you can do either one or two things. The first thing is you can stash them. It basically will go to a place somewhere like a heaven. Yeah. Yeah. So yeah. The second option is that you can go to another branch and commit all the changes there. Just a dummy commit. It's just like a placeholder. And then go back to the current branch and you can check out in the past easily. Sorry. No, just go to a temporary branch. Yeah. A disposable one. Yeah. Is there a possible way to commit procedures? Yes. You can. Git rebase can do that as well. So. Okay. Any other questions? No? Okay. Thank you. Thank you.