 Thanks for coming out. This talks next level get, just to make sure you're in the right place. We're going to be going over some intermediate to advanced get topics. So about us, I'm Mark Faree. I'm the Director of Engineering at Chapter 3. I use get every day. I have been for probably six or seven years. And every day, even yesterday, you know, going through our slides, learn some new things. So, you know, get is as deep as you want to go. And so we're going to try to share some of the things we've learned, you know, picking through get. I'm Brad Erickson, and I make a lot of things on the Internet, just like everyone else here. So the history of get gets a distributed version control system created in 2005 by Lawrence Corral for Linux kernel development when no existing options provided the required features. If you'd like to read the quote, that's where the name came from. If you'd like to read the quote, that's where the name of get came from. Oh, it's much louder now. So we have some prerequisites. So make sure you are aware so that you understand everything that's being covered in the rest of this. We need some working knowledge of get from the command line. You must know the following commands and their usage. Clone, checkout, add, commit, push, pull. So everything you would use if you use Pantheon or Aquia for developing your Drupal sites. So normal, you know, SVN level, you know, get usage. Got a bit of a glossary just to make sure you get you're in the right place. VCS, version control system, the commit repo or repository, which we'll use interchangeably, tag and branch. So, you know, these are the common terminology used across all version control systems. So, you know, we're expecting that, you know, when we throw these words out that you'll know what we're talking about. All right, some useful commands. One you may have seen right now is a tagging of commits like most version control systems. Get has the ability to tag specific points in history as being important. It's just a way to name it so that if you have an important commit such as most commonly used as a version number, you're going to give it a name. There's other important bits of history throughout the commit time. You can add in just to give it a name, such as this is the time we changed something. So in this case, it's just adding a tag for version 1.0. Tags are an add-on. If you notice in the example here, we also have hashes. So everything that happens in Git gets a hash. And by hash, it's a really long, unique string. So you see the commit, you know, LDA177E4C. So that's designed to be unique within that repository. So, you know, the tag is just a bookmark for that hash. So tags don't have any other special features. They're just, you know, giving you another name for a place in time in the repository. Another great one, Git diff. This is probably every time before I make a commit, I just want to check to make sure that I've only changed what I want to change. So Git shows the differences between commits, between the stage, or your current working directory, or different branches. So Git log is probably where I spend the most of my time. I look at code a lot more than I write code these days. So Git log has a huge, huge number of flags. The one, I actually have my, you know, bash file set up to pass p every time. So when you pass dash p, you get Git log, and instead of just getting the commit name and the commit message, if you just have the commit message there, you're relying on the developer to have put something useful. This actually shows you what changed and what file and even throws a small diff underneath it. So this output's a lot more useful if you're actually trying to get, you know, a real idea of what happened. Nice little short history. This is equivalent to a change log. If you don't have it, your project doesn't have a change log. And that's just Git log dash dash one line. And you can see that it's just going to list off the kit commit subjects from each of your commits. So Git what changed is actually just a short hand for another, you know, whole collection of log flags. What changed shows you the individual files and whether or not there was an addition or modification. So rather than showing you the diff, if a lot of files were changed in a single commit, this one might be a little bit more easy to process. So I use these all interchangeably, depending on what mood I'm in and what I'm trying to look at. Git's mood sensitive. Yeah. Then everyone's favorite command, if you haven't used it yet, will be your favorite is Git blame. You want to see who did what and why. So look here. We know the address and there's Nathan down there on line seven, line seven, excuse me, eight Nathan, but this is just useful if you need to see why and why, how, when something happened and what was changed. So Git stash takes you down a different road. So previously we were actually just looking at history, trying to parse history, figure out what happened in the repository. With stash, we were actually doing some of our own work. And so I tend to have very fragmented days. I'm across a bunch of different projects. So when I open a repo and start typing, a lot of times I like my thoughts are incomplete. I don't have working code. And I need to check out a different branch and look at something different. So stash is your best friend when you get stuck in this situation. So what stash allows you to do is without committing your changes and saying that this is something I actually want to keep, you can just shove it over to the side. It gives you a collection of stashes that you can list out. And what it basically says is, I forget what I was changing or I'm not sure I really even want this yet, but I may want to bring it back in the future. So you can push it to the side and then go work on something clean. The main time I have to use this is when I'm trying to pull in something that conflicts with what I have in my stash. Like maybe me and another developer were working on the same HEACS file. Production site's down. We've got a redirect loop in the HEACS file. We're both working on it. It's like I want to see his changes that he just pushed that brought back up the prod server, but I may want to introduce my changes back so that we get HTVS working properly. So shove it to the side, quickly pull in another change, and then you can list out, you know, the different stashes you have in your history. Another one is the amend option on commit. It's super useful when you just remember it at the last second. After you've finished that commit that there's a debug message in or some minor little CSS change. Before you push, it's often quite easy just to go and make the change of the file, get added, and then you can get commit update which will replace the previous commit with a new one. And then be careful. Don't amend the published commits that everyone else on your team already has access to. Unless it's already been discussed and you know what's happening. Or you want to spend half your day, you know, recovering from that mistake. Just like related to that is there is a force push and this can be over overrides the remote branch history with your local history. You can delete your entire remote branch and even your entire repository with this command. Some repository hosts won't let you force push but the majority will such as Bitbucket GitHub. You can delete entire repository with this or you can rebuild your history to remove passwords that were stored years ago that shouldn't be published. Oh and the new one new for this talk is bisect. And the definition of bisect just be clear is divide into two parts. When you have a project and you need to go back into the history and find why something again why something happened and a specific time that something broke. So you know that it was related to this issue and just the entire history of what caused this to be changed. What you can do is go step by step and pull out check out this commit check out this commit check out this commit but that's inefficient. You don't want to do that. So instead what we have is a system that uses binary search and you say get bisect start and then say the point at which everything went bad as the get hash and then the current tag or the current hash where everything is good and you'll do an optimized search by going through this one then this one then this one to come down to that one commit where it first went bad. It's particularly useful and a really busy repository. I don't know who's planning on going to the sprints tomorrow but you know the commits are going to start flying in really fast to Drupal core and you know knowing when a change happened when you've got 10 people pushing things and a lot of stuff happening can get really complicated. So you really want bisect when it's I know something went wrong at some point between last Thursday and today and I've got a hundred commits to look at so it'll help you work through that a lot more quickly. There's a good reference there webchip wrote a real nice Drupal centric little tutorial on it. The core devs love this one. Now we're going to get some story time. So using incorrect get incorrectly effectively it can work. You have two users on the same branch. One's going to check out the the current head. This is the green one here. One's going to check out. I can't do that. The the current tip they're going to make a change and then push it up to master the next user will pull out their change and start and continue from there. It works fine as long as there's no overlap it's right like this. We have some failed failed to push some breaths. I think we've all seen this message when someone else is working on it and you've you're fighting back and forth. Everyone adding little commits here little commits there for the last bit of CSS need to be changing on a project and so we have the important thing to remember here is like the power of get is the fact that it can branch so easily and so well and merge those branches in. So if you're only working on one branch you're basically using get just like a 20 year old version control system like you're not you're not getting any of the benefits from get so create branches often you know use them creatively like there's there's no reason for everybody to work off of master unless you're the only person on the repository. So here's an example of what happens when two people are working on the same exact branch. You have one user makes a commit and now that other user has a new new commit but their branch out of consistency is out of sync. Is the common solution that is that you see many people do is just do a get poll that's the same as a fetch and then merge it makes a merge commit it makes a messy history and what happens is all of those merges if you normally have more than this graphic shows will be shoved together and so you can't tell what there's no there's no history together there's no story. And I'm sure I work on a lot of Drupal projects I know a lot of those histories look exactly like this you know a lot of times when you're working on a Drupal site like all you're using get for is like a collection of the history so it's bad but it's not as bad as not using version control at all so you know don't feel feel too bad just understand that there is a better way you can make your life easier if you use get more fully in the future. So the reasons specific reasons avoid creates an extra merge commit introduces greater risk of merge conflicts and a messy history makes the problems more difficult to track so there's a better solution. So this is kind of your first baby step to understanding like the power of get branches from my perspective you know the more complicated you make your development workflow the more you can slow a project down with your workflow so you know you really want to take these as baby steps you know everybody working off master introduces its own set of issues you're resolving merge conflicts more often you're stepping on each other's toes and the history is more confused. So this gives you a nice baby step which is we're going to call a branch dev everybody's going to work on that branch but we can then safely do production pushes by merging into master so we can all collectively decide that dev is in a good space today we're going to push it to production tomorrow so we can merge it into master tag that merge commit on master and that's going to be our production release for the next day so we get the benefit of branches because the production branch at the top what our master is our production branch in this example it sits there ready for a hot fix so if I have a one line change I know I need to push to production right now I don't have to sort out the like week and a half of dev work that's happening on the dev branch I can ignore it completely hot fix master and you know move on with my life and just merge that back down to the dev branch so you know it's still there when we we merge again back up to so this is sort of like your first intro to branching like it's a nice way to you know if you're thinking about bringing this back to your team it's a nice way to get everyone started understanding the benefits of branching so here's the best solution everybody gets their own branches the second branches is is rebased and we'll teach you cover rebase in a moment then merge back to master when features are complete this is the correct way the recommended way to work on GitHub and Bitbucket or GitLab so what happens is both users start at that same commit they both make their own feature user A finishes feature A first they merge it gets merged back to master and so then what can happen is user B uses a feature called rebasing and what it does is it changes your base commit and you can see in the graphic that their commits are replayed so that the history and you could call it the story of the project stays linear so instead of in a merge where it gets shoved together it's this one and now this one gets stacked up on top the two pieces stay in order and then later when it's all merged you get a clean history and you only end up with one merge when the new features brought in could be a good chance good eye yeah I'm trying to remember our color conventions that is so like I said you know creating and then sorting out your branches is actually really simple straight forward it can be like an easy quick part of your workflow so my example I gave about Stash the smarter way for me to do that would be to not be working on master in the first place but I should have just created a branch for what I was thinking and I could have given that branch a really good name for what I was working on so you know that branch can sit there for three months until I get back to what I was thinking you know especially if you're working on the read me that's not usually the high priority you know work that you're doing on the repository but you know you always want to update your remit read me so I can start doing some typos and some edits to the read me and I don't have to put that back into the main repository until I'm ready for it so you know I can have a local branch I can also push that branch remotely so other people can tackle that same read me work but you know we then have like a nice sandbox to work together in now just clean up your messes delete your branches when you're done with them branches can be used for new features temporary tests or quick backups but when you're done it's quite easy to get rid of them and that way you can see what what's over what and still need to be dealt with you might have a feature that's been long oh it's been worked on for a long period of time and you need to work on it needs to be done but afterwards we don't need to deal with it anymore and so I get keeps track of what's been merged and what's not been merged so you can't you have to force effectively forced to lead a branch when it's been when it's not been merged and when it has been merged it's just going to get quickly deleted oh so so the process for merging branches is you so I like to edit my command line there's a lot of tutorials online for doing this where it actually shows you in your command line which branch you're currently in I have even more information about the repository but it's super helpful to know before you push not not to have to remember to run a command to know which branch you're in because it can get confusing when you're thinking about all these branches in your head which one merges where which one's in a current state so checking out the one you want to merge into and then merging merging the other ones is a typical flow but there's nothing to stop you from doing it the other direction so just keep in mind having having that in your command line so you know which branch you're on and you're thinking carefully about how you're merging you know it's important it's easy to screw up the nice part is with git until you push you're usually local you can always step back and rethink your decision so like Brad mentioned git keeps track of what's been merged and what hasn't so this gives you a good idea of sort of the status of your local work as well as remote work so if you pass the dash R it includes remote branches if you don't pass any flag to this you get just your local merged and not merged so if you're getting really organized you know I don't know you have a bunch of JIRA tickets assigned to you and you made a branch for each ticket assigned to you you can really quickly see like how's my week doing like am I on track to get this work done just with running one command on the command line so if you want to make some merge conflicts what you do is change the same line in two separate branches git is really really good at handling merging when separate files have been changed or completely separate lines but when it's the same line in two separate branches you try to merge them this is where it's going to cause a merge conflict this is especially painful when you work a lot on CSS because changing the same line is is way more common Linus doesn't write CSS so he didn't really think about that use case when he was writing the tools so unfortunately you know you might have to sort out some of those merge conflicts so this is how you go about tackling that so you know there's a couple of ways you can go through this you can do it in a more interactive step way especially if you have a lot of merge conflicts that might be a way to go I personally prefer to go at it from this angle which is I find my status I know I'm in a merge conflict I get both modified which means that git wasn't so hard enough to resolve this like git typically resolves like 90% of of what's in the repository it has a lot of strategies for dealing with different conflicts it comes across but when it can't figure it out it needs your input so what it does is it manually modifies the file throws in these you know greater than less than equal signs to let you know which branch has the change and what's the changes in each branch and so in this example you know we're trying to you know make this copy script thing cross browser by just you know changing changing the name for Mac OS to Linux and we change it in two files and then we try to merge them back together so in this case if we were good software engineers we'd have two separate branches that live separate from each other forever you know because we don't want our map configuration to break our Linux configuration so there's many remotes the source repository when you clone a project is called your origin remote that's just by convention you can rename it and call it anything else you'd like when you first do the remote you you clone down a project initially and you check the get remote and that's called and that'll be called origin or origin just a special key word it doesn't do anything you know particular it's just it's just a naming convention and so I've got a little graphic here so you can see that that orange remote has been brought down as your local copy of the repository and they're they're the same at this point and so a common use case is you got two users and one remote they both have access and in both cases the same repository is their remote origin you're going to push to it you're going to pull to it you're going to cause some merge conflicts so up to this point everything we've been describing is typically you're working on one repository so it's all the tools for everybody working together in one repository you know what people have realized is you know gets more powerful than that you know you can have a lot of you know a lot of copies of a repository you're not stuck with just one copy of the repository so what we're discussing here in this section goes beyond everything we just discussed and starts to add multiple repositories to the mix yeah and this is a different view of the same idea it's really hammered in so this is how you're going to do it most commonly again on any of the hosting providers you will fork the project and create your own version of it so that what happens is you have one user that owns a project and then another user has their fork and they work against their fork the nice part about Git is you always can have everything locally and you probably should and so if for some reason tomorrow you know the CIA went into the GitHub offices and shut down their servers if you had pulled right before that happened you would have everything in your repository and you could republish that somewhere else and so you know get you know once you'd be able to work from an airplane and do everything you would do if you had an internet connection and so your local forked copy is an exact copy of everything from that project as long as you pulled it down completely so when you're working like this the user too this is just the world according to user too you pull down changes from upstream into your local master you push changes to origin your fork and then merge changes upstream or you create a pull request so that at no point are you at no point are you going to push directly to the original upstream and this is the standard way to work on every major project on GitHub Bitbucket GitLab and so this is the a question that many people have constantly is how do I update when you have a fork how do you get that that fork back into your your fork or the original project and so there changes upstream master how do you bring those changes to your fork's master branch what I do is I add at this point we say get remote and there's no remotes get remote add upstream and the original project name now git remote update will bring down that upstream remote and any updates to the origin remote you'll have both of them on your on your machine so you check out the master branch because you have been working on the master branch on a feature branch and you pull upstream master and that will pull in all the changes to upstream master and then when you do a git push it's going to it's going to update your origin master so that now it's going to be in sync and now you can rebase or do whatever you need to do versus your feature branch in the in the Drupal world an example of this would be if you know your company has its own private github but you're also hosting the production site on Pantheon so Pantheon might be your origin you know you're going to you're going to merge in all the changes from Pantheon but you know you're also you're also going to have a copy of the repository on github because that's where your continuous integration runs you know you maybe using Travis CI so you know you're you're able to use remotes there's no limit to the number of remotes you could have you can I know on big github projects people will check out other developers remotes their their forks just so that they can check out other people's work that's happening over here it doesn't really affect my work but maybe I just want to go look at what they're doing so you could have 7, 8, 20 remotes and and just swap between them, merge between them they're all started from the same repository so most of the code should be shared so Drupal in many cases you're working on github or GitLab and you're aware of what pull requests are but some of you aren't pull request is a request to pull your changes this isn't something that is part of Git this is a something added to the UI tools that we're all using as a nice formality to discuss the the change you create a pull request when you have new commits in a project or a fork which will be pulled into the original project it's a straightforward idea but it's something that's not necessarily part of Git itself now we get some fun this is rebasing and I've made up this definition with the capitalization in because it there isn't a better one that I've seen yeah don't bother reading the man page for rebase you know on the Git command line it's not worth your time oh it is read the fine manual a merge generally creates a single commit with two parents and it's a non-linear history that's I was saying is that you get all of those commits you got commits from this commits from this and they they're going to be overlapping a rebase it takes that original that original one and yours it's going to come over here and stacks it on top it and it replays each one of them so that commits for each feature stay together it also and that process resolves a lot of merge conflicts more easily because you're going to be each each commit instead of having you have 50 new commits instead of having to resolve all of those at one time you can just say I'm going to resolve just this one commit merge conflict and then the next one and the next one through that the entire rebase process a regular merge is kind of like the lazy version it's like you know I trust get it's a really powerful tool it's really great to resolving merge conflicts I'm just going to smash it all together and hope it handles it well whereas a rebase is like you as somebody who's trying to add a feature to a project really thinking about is this message useful are these commits useful package together does this actually solve the whole problem I'm trying to solve so you're actually like making that decision point like this this is ready to go it's packaged up and I'm going to run it right on top of the current history of the projects and clean it up before I do it in many cases this is required for a pull request to be merged in a lot of projects and they won't accept a merge so remember this from the first time this is how you do it this is what it looks like it's really close to what you're doing with a merge just you're using the rebase command instead so the commands are you check out feature B then you rebase versus master instead of instead of merge versus master and so all your commands your commits are getting played played back on top now you can push force because if you've been working in your feature branch and you know pushing early and often that your feature branch is going to be out of date so what you need to do is force it and this is where it's acceptable to do it because this is your feature you own it, your fork overwrites your previous history now you check out master and you can merge master or this is the point where you're going to make a pull request based on your new feature branch so like I said the whole reason for this is not just to you know be correct in terms of the timeline of the project the reason is that you're actually going to think about how you're presenting this work so you know anybody here a front-end developer raise your hand so you guys are all guilty of really short commit messages that get fired in really frequently I know it from previous experience so we can actually squash those into something relevant and nobody has to know that you are just you know actually moving the same thing around for two hours up and down so Rebase gives you the opportunity to you know package your work and present it as you know a complete whole so if you get log one line will show you everything you've been working on in this feature branch but what we're going to learn how to do is squash these together so when you rebase interactively it presents the screen to you so it finds everything on your feature branch and it finds all those commits and hopefully been giving at least relatively good messages so you can tell them apart from the screen and you don't actually have to go and find a history elsewhere to find out what you changed and now you have the opportunity to start working through these changes and figure out how you're going to deal with them and the first thing you do well the only thing you do is if you look at the bottom of the commands here get is real nice and shows you the different commands there's pick, reword, edit, squash, fix up and exact in this case we're just going to be squashing and what that does is you have a look when you have that little merge you have that little CSS fix that you forgot or the little debug what you can do is squash it back into the previous one and bring all your commits together so in this project we currently have six commits and what we're going to do is take out three of them and get rid of them the minor edit, the minor edit and the minor read me edit just pretend those never happened so what you do is just edit whatever your text editor is change pick to squash, squash, squash now save and exit git is going to exit come right back with a new editor and allow you to adjust your commit message because you have that new feature and in this case I would just comment out or delete those minor edits and then the same thing before and we've got originally those six commits the six useless commits have now been turned into three useless commits the process is a you know it's after you've done it a couple of times and you can do this in little simple you know make a new repo and try it out it becomes second nature another good example here is a real simple more than amend when you need to do an amend on the most recent commit you type git commit amend and it'll bring up the editor and you can change the commit message but if you need to go back into the history and add something maybe a link to the stack overflow post that told you why you were going to do it do it this specific way it's a good place if it's not in your code itself is you can use the edit command and the same process get rebase given an older commit hash and change it to change the command to edit in that in that process and that's what these commands are doing we're going to show it shows the git log showing the rebase and now git commit amend is going to open the editor and at that point you can go and change what the commit message is and rebase continue the rebase okay we're done and now we can see that what was new feature is now new feature more details to message so you know part of the basis for using rebase for going back through and editing these things is you know when you're working quickly and all you really want to do is just be keeping track of your own changes for your own head like I'm going back and forth like I'm trying things out you may not take the time to do a useful commit message so you get something really short that doesn't provide any context or details about this is why I always pass dash P to every when I'm looking through the log because I need to see what changed because the message doesn't usually tell me so if you take the time rebase you can go back through and edit these messages or combine them into a useful message from a whole bunch of CSS fix but it's important to remember if you're working with other open source projects outside of Drupal there's actually really strict commit messaging standards for bigger projects so don't be surprised if someone tells you that they you know first of all you need to go learn how to amend and rebase because you need to edit these messages if you ever want to even dream of getting this pull request accepted and that's something overall very important just like in your code the comments should succinctly explain what and explain why in detail why you're doing this so that in the future someone understands what you were doing my favorite way to describe that is pretend the next person to be working on a project is a homicidal maniac who knows where you live so summary so so we went through a lot of new commands in addition to these these commands you can use on any repository we also introduced you to the concepts of you know pull requests rebasing bisecting so you know there's a lot thrown at you here get as you know this is you know still intermediate goes a whole another level beyond this and then some so don't be afraid to you know reach through the stack overflow posts you know do a lot of research we've got some resources coming up on the next slide so some some things you might want to tackle or it might be a problem you're already facing and you need you need to know that it's possible you can go in and rewrite history gets completely malleable you can use hooks there I mean this is a whole I don't know discipline into itself to do a whole lot of automation just with the get pushes and polls and all of the commands that get does itself it's a process that both of we have the on use when you push to a branch that will then go and update your development site doing other polls or processes so these this pull request rebase workflow might soon come to your life on Drupal especially contribute back to contribute modules or Drupal core itself so there's a good video on this there's a lot of issues about this as well and I like the for finding some of these same advanced commands Atlassian has done a lot of good documentation you know that they have their projects that use get heavily so that it was in their best interest to get people to use get properly so that's it for us we got five minutes for questions anybody has anything and they asked us to use the microphone if you have questions anyways okay for a developer here do you have any strong opinions about squashing down to a single commit I I I do not enforce that yeah the question was is there any strong opinions about squashing down to a single commit so you know it's really just you know the homicidal maniac comment it's like when you're looking back through your own code is it going to provide something useful are you going to be starting from scratch and just looking at what changed rather than like the information that you provided so you know it's twenty commits that change the same file and for the same part of the same file like don't serve anybody in the future I like I like keeping the commits more story if you if there's this piece and this piece and this piece squash down the one so that explains you can see more of why what happened in relation to get when you install a triple spin up a triple instance with Drush it'll create the get ignore file and it includes all the four files what advantages that to include files that you're not going to change if any um generally you the files you don't want to change or build artifacts is on on compiled systems it stuff that's going to be generated locally or changed locally you don't want to put that into the repository it's many times your editor settings there's a there's going to be specific to your your machine so you want to have those settings locally but you don't want to push it off to someone else who doesn't need to use those specific settings mm-hmm I'm keeping track of people that are hacking core I mean that that's a priority for me yeah yeah I actually created a get hook that reminded me to fetch every time I was getting ready to do a merge conflict so I mean it's um the docs used to tell you to do that and then get got better and just got better automatically merging so yeah I would say use fetch like I always use fetch right before I you know know I'm going to get off a lot drop off a Wi-Fi you know it's like I want to know what's happening that repo and I can deal I can deal with those changes later you know so fetch is a great tool like I do fetch dash dash all a lot of my repos now it's one of those like nervous twitching like what's going on with this repo let's just pull it all down and see what's happening so yeah generally a a get pull is equivalent to a for a fetch and then merge yeah so try not to ever do it fetch and merge yeah if you separate it out you get a chance to pull back and you know stop yourself before you do something you didn't want to do yeah and so generally I never use pull anymore except for the to the master from the master upstream because I'm never touching the master upstream so I don't need to do fetch and merge because it's the same I know that there's no there's no no new commits on that so it may be maybe not everyone would maybe you would have a Jenkins server that does it automatically for you or maybe you just have someone that's like you know the lead dev and they're responsible for production pushes so that's all on their head to make sure that things stay up to date so yeah so that's a really useful way to use remotes is like access control over who actually gets to push the prod yeah you have to go through the process of continue or you can you also use a board but it's when you are rebasing and it's just the simple one check and load that right there the simple one this example you don't need to do anything with the continue because there's not if there if there's no merge conflicts that's only when you're doing an amend or fixing a conflict or actually not even squashing it's just for the amending process of a commit when you need to make a change to it it's like hey I'm done I've amended this commit now continue with the rebase and so it actually when you have like 30 of the middle countdown one two three four and when you get to the fifth one the one you said to edit it's going to stop you can make whatever changes you can delete files you can edit the message and save then you do get commit amend and you've changed the committed actually changes a hash also and then you say get commit or sorry get rebase continue and it will then start applying the nest the rest of the commits all the way down the line yes there's it's I mean in terms of safety it get is keeping track of all of your commits and your history so it's safe either way to to merge no pass forward automation kind of changes all the rules like I mean like I would be more hesitant putting a force flag and running it from my own command line but I might write a script that's going to always overwrite the you know the production server because I want to make sure there's always consistent you know so like if somebody hacked the server and put their own changes there or as the station the server when they weren't supposed to sorry you know that that code's gone you should have done it the proper way so yeah yeah so so so when you're writing a script you can break some of the rules because you know you can have a lot more heavy handed because the last thing you want to do is introduce issues so look it depends how it gets written basically yeah you okay yeah because it was converted from CSV CVS CVS yeah yeah it was converted and there's all the many projects were converted over at that time if you ever find a CVS repository there's really good open source tools that'll do that automatically preserve all the history preserve SVN yeah mercurial like any any any version control system can come in to get at this point like I don't know it might not go back 30 years but you know yeah yeah from the settings file I did a project last year that was in the Android Library that we were integrating the Android Library with the Android UI but the UI they've been separate repos and it would been like change the the the images in the backgrounds and the URL to the server for this project and that and then the next project it just kept getting committed onto the UI project and then the whole the whole project was done together and what I did was bring those two projects together and make it so we could gpl the whole thing it's so I what I had to do was go into the history and pull out all the passwords and custom settings and all the old binary files so that because what it did it brought down the project from I think it was like 50s 60 megabytes down to four because it was just the simple backgrounds and everything all the passwords and everything had been removed I took out all these extraneous files a good script that's called BFG named after the gun and doom and that will go through and it uses the get filter branch command but it automated automate automate support. Yeah, people get attached to their history and sometimes it's not actually as valuable as you think it is especially after a certain point. So yeah, yeah, the Mike's not working. Yeah, it's out of battery. I think so Drupal stores everything in the database especially in Drupal 7 there's a module called features that lets you save that down to configuration files and in Drupal 8 luckily like thankfully for you know we finally have a full configuration management system and so that often gets committed to the repo and manage through get so now every every one of those changes we can actually export it save it into the repository and then move it between environments 7 has features it's partially functions 8 has has built it from the ground up with CMI so you know it's it's there a hundred percent like every configuration set setting should be there in CMI in one form or another. Yeah, if you're checking a checkbox that's configuration like that's the way I like to think about it. So there's a lot of checking checkboxes in Drupal. Yeah, I think skies. Yeah, thanks a lot.