Git Fu Developing
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 94 | |
Author | ||
License | CC Attribution 4.0 International: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/45613 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
FrOSCon 201964 / 94
7
10
12
14
15
16
17
20
22
23
26
27
28
29
30
31
32
33
36
37
38
39
41
44
45
48
52
53
55
56
57
58
60
61
62
64
66
67
74
76
77
78
79
81
83
84
93
00:00
Open sourceFreewareMultiplication signMereologyCASE <Informatik>Perspective (visual)Open setOpen sourceAngleXMLUMLLecture/Conference
01:02
Information securitySoftware testingOpen sourceTwitterComputer programmingWeb 2.0AreaTrailInternetworkingSimilarity (geometry)Right angleLevel (video gaming)Projective planeSoftwareOnline helpCommitment schemeXMLLecture/ConferenceComputer animation
02:08
VotingInheritance (object-oriented programming)FreewareOpen sourceMessage passingRight angleInheritance (object-oriented programming)VotingService (economics)Code refactoringGroup actionPatch (Unix)Computer animation
03:33
Open sourceFreewareOpen setComputer fileDigital filterHydraulic jumpCurvatureSoftware developerProcess (computing)CodeRegular graphRight angleOpen sourceBasis <Mathematik>Open setComputer fileCommitment schemePoint (geometry)Object (grammar)Group actionRule of inferenceAtomic numberGame controllerXML
05:37
Game theoryStructural loadVideo gamePoint (geometry)CodeBlogSet (mathematics)MathematicsRight angleComputer animationLecture/Conference
06:32
MathematicsSet (mathematics)Product (business)Rule of inferenceThumbnailMessage passingCommitment schemeSingle-precision floating-point formatComputer clusterRight angleSoftwareWordLecture/Conference
08:23
Open sourceLarge eddy simulationBookmark (World Wide Web)Rule of inferenceMessage passingCommitment schemeLine (geometry)Computer animation
09:11
Open sourceWordMultilaterationLine (geometry)Limit (category theory)FrequencyMessage passingForm (programming)NumberCodePoint (geometry)TrailBitRadical (chemistry)Imperative programmingMathematicsGraphical user interfaceCASE <Informatik>Commitment schemeLecture/ConferenceComputer animation
11:42
Line (geometry)Line (geometry)Message passingDot productMultiplication signRight angleXML
12:23
Asynchronous Transfer ModeBranch (computer science)Message passingGoodness of fitRule of inferenceThumbnailJSONXMLUML
13:02
Revision controlTwin primeExecution unitBranch (computer science)Message passingSoftware bugAsynchronous Transfer ModeXMLUMLLecture/Conference
13:43
Line (geometry)Message passingRight angleCombinational logic
14:28
Graph (mathematics)Open sourceGraphical user interfaceGraph (mathematics)Projective planePoint (geometry)Online helpDiagramTableComputer animation
15:23
WindowRead-only memoryOpen sourceBranch (computer science)Graph (mathematics)1 (number)Commitment schemeGraph coloringRegular graphBitDot productForcing (mathematics)TrailCodeSoftware bugBasis <Mathematik>Point (geometry)Projective planeRight angleMathematicsNetwork topologyINTEGRALLine (geometry)
21:55
Open sourceBitAliasingINTEGRAL2 (number)Branch (computer science)Computer animationLecture/Conference
22:51
Repository (publishing)Witt algebraBranch (computer science)CodeComputer animation
23:43
SoftwareBranch (computer science)Commitment schemeInformationStudent's t-testMessage passingWritingRule of inferenceThumbnailCodeLecture/Conference
24:32
Message passingAdvanced Boolean Expression LanguageBasis <Mathematik>Line (geometry)Computer configurationMessage passingOrder (biology)MathematicsCommitment schemeComputer fileElectronic mailing listUltraviolet photoelectron spectroscopySoftware developerMultiplication signProcess (computing)CASE <Informatik>Radical (chemistry)Type theoryLecture/ConferenceSource code
26:50
Inheritance (object-oriented programming)Type theoryInformationRepository (publishing)Sinc functionState of matter1 (number)JSONXMLLecture/Conference
28:11
CloningFunction (mathematics)Inheritance (object-oriented programming)Execution unitRight angleState of matterCASE <Informatik>Position operatorRepository (publishing)Coefficient of determinationJSONXML
30:09
Open setForcing (mathematics)WeightRight angleRepository (publishing)Branch (computer science)
31:27
Open setCorrelation and dependenceExact sequenceRight angleMereologyVirtual machineAliasingBitBranch (computer science)Multiplication signType theoryGame theoryVideo gameComputer animationLecture/ConferenceJSONXMLUML
33:11
Multiplication signRadical (chemistry)Repository (publishing)AliasingRoutingRow (database)RootLecture/Conference
33:55
Computer fileGraph (mathematics)Network topologyStatisticsLogarithmGraph coloringRadical (chemistry)Line (geometry)Computer fileComputer configurationGoodness of fitAuthorizationAliasingXML
34:35
LogarithmBinary fileType theoryRepeating decimaloutputDefault (computer science)Scripting languageConfiguration spaceError messageAliasingLoginGraph (mathematics)Hash functionRadical (chemistry)Branch (computer science)CASE <Informatik>Source code
35:37
Regular graphLogarithmOpen sourceType theoryTerm (mathematics)Radical (chemistry)Multiplication signGraphical user interfaceObject (grammar)MathematicsChainOpen sourceXMLJSONUML
37:50
MathematicsParameter (computer programming)Drop (liquid)Cartesian coordinate systemIntegrated development environmentConfiguration spaceDefault (computer science)Revision controlIntrusion detection systemJSONXMLUML
39:10
MathematicsState of matterRevision controlAsynchronous Transfer ModeRight angleIntegrated development environmentLecture/Conference
40:20
Open sourceCodeProduct (business)Point (geometry)Multiplication signRight angleSign (mathematics)Computer animation
41:56
Revision controlExecution unitSoftware testingQueue (abstract data type)Multiplication signSlide ruleState of matterDisk read-and-write headType theoryRight angleRevision controlPoint (geometry)Hidden Markov modelCommitment schemeLecture/ConferenceJSONXMLUML
43:26
Software testingExecution unitMathematicsOcean currentType theoryState of matterSoftwareCartesian coordinate systemPoint (geometry)Unit testingDisk read-and-write headBenutzerhandbuchExecution unitLecture/Conference
44:15
Revision controlExecution unitSoftware testingExecution unitError messageLogic gateUnit testingRight angleSoftwareJSONXMLUML
45:51
Revision controlComputer fileRepository (publishing)Execution unitUnit testingProgramming languageScripting languageLine (geometry)Ferry CorstenCodeStrategy gameKernel (computing)Software bugGame theoryType theoryNP-hardBinary codeInheritance (object-oriented programming)Commitment schemeComputer programmingComputer animation
50:15
Open sourceFreewareXMLComputer animation
Transcript: English(auto-generated)
00:07
Welcome everybody. Who of you has contributed to open source? Oh, that's nice. Okay, and who of you has done this using Git?
00:23
Okay, that's quite the most of you. Most of the time, and it's not primarily for open source usage, if we're using Git, we can use Git, but we can do it in a way that's not very nice.
00:43
What I'm trying to do in this talk is to look at the technical parts of Git, but from an angle of a use case perspective, how to behave in the right way when I'm using Git.
01:00
But first things first, my name is Sebastian. I'm working at Check24 here in Germany. I'm doing programming for roughly 30 years now, so I started with the C64 and some BASIC and moved from there. I'm doing some open source, mostly in the web PHP
01:22
area, and like most people, I say stupid stuff on the internet, so if you care, you can follow me on Twitter. Anybody has seen something similar like this, right? Yeah. I'm not swearing on stage, so I'm not reading out loud what's happening here, but
01:44
this is a commit history I see in a lot of projects. It doesn't help you at all figuring out what's happening in your software. Figuring out what's happening in your software is quite important. And it's especially important for open source software.
02:04
So the first concept I want to talk about are atomic commits. So what are atomic commits? So if you see a commit message like this, implementing new voting feature, fix an internal messaging issue, and refactor some inheritance menace.
02:23
Great, right? And there's way too much going on there. And that's basically not what atomic commit means. An atomic commit would be much more like this, right? We would say add voting persistence service,
02:42
refactor for mortars to be composable, fix internal messaging issue, and add voting API endpoints and actions. And this has a lot of advantages if we do it this way. For one, if somebody needs this fix, he can just cherry-pick this commit.
03:04
If you buried this fix somehow anywhere in the commit over there, he's not able to get the fix. So then you start copy-pasting stuff and sending patches and yeah, it's getting really messy. But if you do it in an atomic way,
03:23
you can just push it upstream and somebody can cherry-pick your fix. And that's quite nice. Another thing is, and that's where it's becoming important for the development process,
03:40
if you're doing pull requests or code reviews. So who's doing pull requests or code reviews on a regular basis? Yeah, nice. Okay, cool. So especially if you contribute stuff in open source, you're doing pull requests. Somebody has to figure out what you've done and has to
04:01
understand what you've done with the software. Imagine one commit. So you see a pull request like this. There's one commit, 17 files changed, and that's not very big, right? So it's still small. But if you look at the pull request and you see 17 files change, you have no idea where to start, right?
04:23
It's becoming this big mess. And like I said, 17 files is really small and even that's horrible to review, right? So if you have 50 files change or 80, it's a total disaster. What happens if you do this in an atomic way and doing atomic commits? You still have, in the end, 80 files changed.
04:44
But you have these anchor points of your thinking process where you can say, okay, I first did this and then I did that and then I did something else. And what somebody can do is he can click on every commit and can watch or can check the files that changed for each commit. And then he can follow your thinking process much easier.
05:06
He can say, oh, okay, that's what he did to change the persistence layer. Okay, that's totally clear because he had to add some data access objects and that's totally fine for me. Okay, that's five files. And then you go to the next commit and see, okay, he added some API endpoints.
05:23
Okay, therefore you should add some controllers and actions. Okay, next six files, check, done. Right? So it's much easier if you keep the commits and do very small commits. And of course, Master Uwe has some rules for atomic commits.
05:41
Atomic commits are a single irreducible but useful set of changes. And that's very important, the useful. Because what I hear often is, yeah, I read this blog post and they said commit often, commit always.
06:02
And that's right. But then your commit history is like a safe game in a computer game. Right? It's quick save, quick load, quick save, quick load. And none of your quick saves matter for me. So it doesn't really have anything meaningful in it.
06:23
So you can do this. But in the end, if you submit the pull request or get to the point where you get a code review, please clean up that mess and create a single useful set of changes. Next one is everything works.
06:43
And that's really, really important. You can commit as much crap as you want. Please, if you submit a pull request, make it that every commit is deployable to production. So I can choose any commit in the commit history and deploy it to production.
07:03
That makes it much easier for everybody to work with the software. Because everybody knows I can use any set or any commit in my history and deploy it to production and it should work.
07:21
Like I said, it doesn't have to work in your daily work. So you can commit. But before you submit a pull request or stuff like that, you can clean that up. And I will show you in a second how it's done. And the rule of thumb is don't use the AND word in commit messages.
07:43
So if there's an AND, then it's already too much. So don't do that. So when I'm talking about commit messages, I was really relieved that the previous speaker didn't go into detail about commit messages.
08:03
Because, yeah, then this would be kind of irrelevant now. But who knows this website, whatthecommit.com? Okay, not so many, that's nice. So if you ever need for a cool handy commit message, right,
08:22
and you don't know what to do, just go to whatthecommit.com and you get some gems like major fix up, fixed 2PO, one that not simply merge into master, and one of my absolute favorites is best commit ever.
08:42
So obviously, those are fun. But as we've seen before, they are not very useful. So once again, master Ube has some rules for us, how we should do commit messages. And the first one is separate the subject and the body with a blank line.
09:04
And when I tell people this, they look at me funny and say, commit message body doesn't have a commit message, only four words or something like that. Yeah, we will see an example later. Limits the subject to 50 characters. That's, we will see why this is a bit of important in a second.
09:24
Don't end the subject with a period. Yeah, this is more arbitrary. So since we're limiting us to 15 characters, every character counts, so don't waste it for a point or for a period. Next one, capitalize the subject line.
09:42
And that's, yeah, it's kind of the same. I'm kind of a strange person if I see a git history and the first word starting with uppercase, lowercase, uppercase, lowercase, lowercase, then it cringes me out. But that's, I'm special in that way. So I always try to bring people to the point where you can see,
10:04
okay, yeah, just capitalize them. And that's a little bit more important. Use the imperative mood for commit messages. And the imperative mood is, is the form where I say it's do it.
10:20
So it's not I fixed issue number 500 or something like this. It's figs issue. And we'll see good examples in a second. Next one is wrap the body at 72 characters. And that's mostly for terminal nerds like me
10:43
that are not using any GUI tools. We are very happy if we don't have to side scroll for your commit messages. And last one is use the body to explain what and why versus how.
11:01
Because how you did something, the code is telling me that. I know how you achieved your changes, but I don't know why you did it. And what was the intent of that change? So maybe you ever come across a situation
11:22
where somebody asks you, hey, why did we change that? And you say, I don't know. The commit message says we changed it. Yeah, but why is a completely different thing. So it's quite nice to keep track of stuff like that in commit messages.
11:43
But let's go back to the subject line. So if you have a commit message, and it's longer than 50 characters, most tools like GitHub, GitLab, or Bitbucket are shortening your commit message. And most of the time when I see this,
12:02
it's okay, yadda, yadda, yadda, and the important saving is dot, dot, dot. Oh, crap. The important stuff is always hidden behind the dots. So I always have to click. So yeah, just keep the very important stuff in 50 characters.
12:25
Then we said use the imperative mode. And we're just following the example of Git because Git is doing exactly that. It's not saying we are merging branch my feature. It says merge branch.
12:40
So we should always do as Git does. And there's a good rule of thumb. You can use this sentence. If applied, this commit will, and then use your commit message title or subject.
13:02
And if you have some bad examples, so if applied, this commit will fixed bug. Okay, that sounds strange. And the good example is this commit will merge branch feature x. This commit will update the getting started documentation. This will, this will.
13:22
And in the beginning, it's awkward to write commit messages like this. At least it was for me. But commit messages get very precise if you're using the imperative mode. So I can only encourage you to do that. And a complete example could look like this.
13:45
You have the subject, then the blank line and the body. And of course, yes, not every commit message has to look this way. Right? But especially if you keep atomic commits
14:03
and if you merge into master and you squish all your atomic commits together, then the merge commit should look like this. It should be a really combination of all the commit messages that were squished together.
14:28
Have you ever seen some stuff like that? In your projects or your GUI tool and you want to look what's happening in your branches and you're looking at the git graph
14:40
and at that point it's no longer a git graph. It's like a guitar hero thing. And, yeah. So Masa Ube has something to tell about that. So he says, your mind is like the git graph, my friend. When it is agitated, it becomes difficult to see. But if you allow it to settle, the answer becomes clear.
15:05
And what that means is, if you have a git graph like that and you can get to it very, very easily, it's totally useless. It doesn't help you anymore. And the git graph can be very, very useful. But for that you have to follow some guidelines.
15:24
So why is your git graph messed up like this? And it's messed up because you're doing merges. And if you're doing merges, git always keeps track of something where it came from and where it's going.
15:41
And if you merge a lot, then your git graph becomes like this guitar hero thing. So merging is safe. It's the safest way to get stuff together. But it messes up the history a bit.
16:01
So why is that? So if we look at a git merge, so we have a feature branch, and if nothing changes, we can do this fast-forward merge. So we just get our new commits in, and everything's fine. But if we have something happening in the master branch
16:23
in the meantime, then git has to kind of, yeah, I have to do some guesswork here, right? So I'm guessing, oh, this should work, but just to be sure, I'm creating this merge commit. And this merge commit is actually really, really handy
16:42
because, as I said, this is kind of guesswork, what git is doing, and it's really good in it, but it still can cause problems. This merge commit is handy in a way that you can, if you are undoing this merge commit,
17:02
then the red ones are gone as well. So if you undo the merge, all commits that you merged with this merge are gone as well. So it's very easy to undo merges. But how can we do this in a nicer way, right?
17:20
So since merge commits and merges are kind of messing up our history, so what can we do? And the answer to this is rebasing. And who of you is rebasing on a regular basis, like daily? Okay.
17:41
Git pull dash dash rebase, right? Okay. What rebasing does is it actually, and I heard a lot of people saying, no, no, no, we did rebase once, and it was a disaster. Everything went to fits, right?
18:02
And why was that? Because what git is doing is it's not throwing your commits away, but it's just removing your commits and storing them somewhere, and then it's getting the latest changes, and then it's reapplying your commits.
18:22
And it is subtle in the slides, but as you can see, the color has changed. Before the commits were red, and now the dots are purple. And that's because those are completely new commits. So what you've done is you've changed the history.
18:41
And that's the dangerous stuff in git, right? And that's why everybody's talking about never rebase master or never rebase shared branches and stuff like this, because what you're creating when you're pushing or force pushing this,
19:02
you can't create a big mess for other people with that code. But in our situation, this now is really nice, because for git now, it is that we started our work at this point,
19:22
and now we can again create this fast forward merge. And we don't have a merge commit, and that's quite nice. Cool? So now we have a very clean history, but this causes a problem.
19:43
So now, if we want to undo the merge, we have no idea how many commits we merged, right? So now it's easy, because, okay, we have the two purple ones, but what if you merged like 30 commits or something like this? You have no idea how much you really merged,
20:02
and if you want to undo it, you have to go back like 29 commits, or whether it's 30 or whether it's 31, and it's always one too much so you are not doing this, you cannot make this right. So what we are doing is,
20:22
we still are merging, but what we are doing now is, we are forcing git to create a merge commit. And now you're saying, okay, Sebastian, what you said, merge commits are bad. Yes, if you're doing merges all over the place,
20:41
but if you're doing it this way, what you're ending up with is something like this. And this is really, really nice. You have a clean history, and you always branch, and then return to the master. So this is your master, right?
21:01
And you always can see, okay, we did this feature, we did the green feature, then we did the blue bug fix, and then the purple feature, and stuff like that. And if you mess up the integration, you can just undo the merge commit, and all the commits that came with that merge are gone.
21:22
So if you have, so I always say, start with the simplest workflow, or git workflow you can, if you start developing a project. And this is quite simple, I would say.
21:40
But now your git graph is very useful. You can see what's happening in your project, right? It will always stay only two lines. It's never going wider than two lines, if you are doing this. You can do some funny stuff. You don't have to read this.
22:01
But we will talk a bit about git alias a bit more in a second. But what you can do is, you can create aliases that support your workflow in git. So this is a git alias that I called integrate. And what it does is, it tries to merge a branch.
22:23
But it checks if it can fast forward merge it. And if so, it merges it with a merge commit. And if it can't merge it fast forward, it will say, no, no, you have to rebase the branch first. So this is a really nice way of helping you
22:41
and doing that stuff that seems a little bit more complicated in the first place. But as I said, rebasing can be dangerous. And you should remember that, please, please don't do it on shared branches. So if you're working on your feature branch,
23:02
and you're working on it completely alone, it's completely fine. You can rebase however you want it. But as soon as somebody else is working on that code, please don't just rebase.
23:21
If you have to, please talk to the person that, or to the people that are using this branch as well. And if you have a workflow where you create branches of branches, don't ever rebase.
23:40
Because you have no idea if somebody is using your branch to create another branch. And if you rebase that, that's totally horrible for everybody who branched off of your branch. So a rule of thumb, please don't create branches or feature branches. If ever possible, don't do that.
24:06
So what does the good students do? We write commit message that precise and informative. And we create a mess by committing often,
24:23
but before we create pull requests or go to a code review, we clean it up. So how do we clean it up? So the people who are using rebase on a daily basis already know.
24:41
So we're starting with git rebase-i for the interactive rebase. And what that does is, it shows us a list of commits that we did in our development process. And now we have, as you can see, we have four commits in here. And git is very nice.
25:02
It's already giving us some options and it's telling us what we can do with those commits. And for example, we can just move the line and say, okay, this fixed typo belongs to the superhero fighting skills.
25:22
It wasn't a typo for the public API. It was a typo in the fighting skills. So we move it up. And what we can do now is, we can say, okay, I don't want anybody to know that I'm a bad typer. So this fixed typo commit, it should disappear. Nobody needs to know that.
25:41
So what we can do is, we can change pick to fix up here. And what that will do is, it will combine the second and now the third commit together. So the changes will be combined, but the fixed typo commit message is gone. So let's fix up.
26:02
And you can squash commits. That's quite the same thing. But now git will ask you what kind of commit message you want to use and give you the ability to edit the commit message again. You can go crazy and use edit.
26:20
Then the rebase will stop and you can go back to the terminal, add files or do more changes and really edit the commit. But in most cases, you're really fine with changing the order and doing fix ups or squashes. And that's most of the time
26:41
the only thing you have to do, right? Combining stuff and changing the order to make it understandable and clean. So we save. And now the rebase went through. And if we look at our git log,
27:01
now we can see that the fixed typo commit is gone. And nobody will ever know that you mistyped. That's really nice. And it's not only that nobody knows that you don't type very good. It's useless information for everybody out there.
27:21
So nobody cares that you fixed the typo. Of course they care, but it's not very useful information and it's not helping them in any way to understand what's happening in your repository. So you can easily get rid of those commits.
27:41
And now we have this problem since I've said, okay, if we do a rebase, so what we're doing is we're creating new commits, right? So we throw commits away and we're creating new ones. And especially if you squash them or maybe you accidentally said
28:04
you don't need that commit at all and that was a mistake. So now you're in a state where you can say, okay, that's not really good because it's gone, right? And that's where you normally do a dash RF
28:25
and remove the repository and clone it again and do all your days work again. Yeah. No more because there's the reflock, reflock to the rescue. What the ref is giving you is
28:41
if you execute give reflock command, the reflock is actually a more detailed history. You don't only have the commits as a history, the reflock has a much more detailed history. And as you can see in this example,
29:02
we have a lock entry where we started the rebase and then we have a lock entry where we did this fix up thing and combined two commits and even one where the rebase is done. And we can now go back to each of those states, right?
29:23
We can completely go back before our rebase and then everything is back to the state where we started rebasing. So if you completely mess up, it's not a problem. The reflock can help you.
29:41
So what you do is you just say, okay, I want to go to this position of the reflock. In our case, it's headed four. And then you're back at that state, right? And in our case, I think that's before we started the rebase. So you can retry to rebase it in the right way.
30:02
In this case, right? And now that we rebased and made everything clean and nice, of course we have to force push, right?
30:22
And that's scary because we can do a lot of harm with force pushing. And that's because there's force with lease. And what that's doing, it gives you a small safety net
30:41
because if you're pushing with force with lease, it will not override commits in a central repository that you don't know of. So if somebody changed your branch in the meantime while you were rebasing, then in the central repository, there's a commit that you don't know of. And then Git will tell you and say,
31:01
no, no, you can't force push because somebody changed the repository already. You have to do something differently now, right? So you have to rebase again or whatever, right? This prevents a lot of angry colleagues coming after you with pitches and forks
31:21
and throwing stuff at you. So that's basically the behavioral part, right? How we should behave.
31:41
And now to make this all a little bit easier, I want to share some tips and tricks you can use to make the Git handling a little bit more easy. And one of the first things I do when I configure a new machine is I set up my Git aliases.
32:05
And you can do a lot of crazy stuff with Git aliases. For example, like, yeah, I already told you, I'm not good at typing, so most of the time I'm using one-character commands, like git p for pull, git c for commit,
32:23
or git b for branch. Like, yeah, you have no idea how much I mistyped git status. So I'm doing Git workshops as well, so it's always funny. And then I'm not using my aliases because that would be kind of weird for everybody
32:43
if I only typed gs or something like that. But if we would make a drinking game whenever I mistype status, we won't get out of the workshop alive. So, yeah.
33:01
Just remember, don't get too crazy with Git aliases because maybe you have to help somebody else with the Git problem. And most of the time, they don't have your aliases. So, yeah. But, like, there are cool aliases to go to your, on the terminal,
33:23
go to your repository root. It's most of the time I'm using git gr for git root, and then you go always to the repository root. And that's really nice aliases, all the integrate alias. So I don't have to do two or three Git commands in a row.
33:42
I only execute one thing, and we're fine. A lot of people say to me, yeah, but I really like the GUI thing because I can see the log, and it's really nice,
34:02
and it has colors, and I see some lines and stuff like that. Git log is really, really powerful on the terminal. And you can do really cool things with Git log on the terminal. There are a lot of options you can use,
34:20
like before or after. You can get commits from specific authors. You can check files that changed and stuff like that. And, of course, you can use crazy aliases for your Git log.
34:41
For example, that's an alias I use. It's git l. And what that does is it renders out a really nice log on the terminal. What you can do is you can color code everything and configure what kind of hashes you want to see and stuff like that.
35:03
And in this case, I'm also using dash dash graph on the terminal. And as you can see, you can see the Git graph on the left side there. And if you're following the guideline that you only have feature branch, master branch,
35:22
feature branch, master branch, it's completely handleable on the terminal. If you have this Git hero thing, it's not very useful on the terminal. Another thing you can do with Git log is you can search in it.
35:42
Like with the regular less commands, you can just type slash and your search term and use n, an uppercase n, to the next or previous finding that you searched. That's really handy. And most of the time, that's much more difficult to do
36:02
in a GUI tool than on a terminal. Next up is git stash. Anybody's used git stash before? Well, that's quite a lot. So git stash is to...
36:25
If you want to... Most of the time, if you say, okay, I want to get upstream changes, I want to do git pull, and git is telling you, yeah, I can do it because you did some changes over there, and I don't know what to do with it. Please commit or stash. So what it means is,
36:41
git is telling you, yeah, you have some changes, and the upstream has changes as well, and I don't know how to put those together. And now, obviously, you can commit them and let git do the merge stuff, but you're not quite happy with those changes, and you don't want to commit them right now.
37:01
So what you can do is you can stash them. And what stash does is it moves your changes away in some magical place. So you can type git stash, and then your changes are gone, right? They are vanished, happily in the stash.
37:21
What you can do now is you can say, okay, let's see what's in my stash, and now we have an object in our stash, and we can now get our changes back. So with git stash pop, for example, we can get our changes back, execute git status, and now our changes are back.
37:41
So what we can do, we can stash them, we can pull changes from upstream, and then get our changes back from the stash. So we can git stash pop. What that is doing is it removes the item from the stash and applies the changes. But you can also use git stash apply,
38:03
and if you have multiple changes in your stash, you can pick the stash you want to apply them. And you can, of course, drop certain things from your stash and clean up the stash. But that's very useful. For example, if you have an application where if you want to debug the application,
38:24
you have to change three places. You have to change some config value, and you have to add some special parameters to it. And yeah, multiple changes. What you can do is you can add these changes or make these changes and then git stash them.
38:43
And whenever you want to debug, you can just apply that stash and then these multiple changes are done in your application. You can debug, and then you can run git stash again, or git reset and remove the changes again. But whenever you need them, you can get them from your stash.
39:01
So that's quite handy. A lot of IDEs are stashing on default. So if you're executing updates in JetBrains IDE, what they are doing if you have changes, they stash your changes, update, and then reapply your changes.
39:23
And since JetBrains IDE does that automatically, sometimes you can end up with some weird git state. Like, okay, I want to reapply the stash, but it can't because we have conflicts now.
39:41
And that's what's happening there. So then you can try to figure it out. A really nice thing about the atomic commits I was talking about earlier is if something bad happens.
40:05
So we are in our zen mode, right? We are developing and kicking features out, and somebody comes along and says, oof, something bad happens, right? And it's terrible enough that the bad thing happened,
40:22
and we can somehow fix it. But now the business is telling us, okay, we have to know since when this problem exists, right? So we had some customer stuff that wasn't working right,
40:42
and we have to know how many customers we have to contact. We have to know exactly since when this issue is in our code base, or when it went to production. So what we can do is we have to investigate our complete history
41:03
and have to figure out when this issue got introduced in our code base. So as we all know, the business is coming and saying, okay, we know it was working all right like two months before, right? So we have some point in time where we know this was working,
41:23
and now we have to figure out where the problem was introduced in our code base. So what we would do is we would do the binary search, and we go somewhere into the middle and would check, okay, is this working? No, here it's bad, right?
41:40
And then, okay, since it must be somewhere over there, okay, this is working, so it can be either this one. No, no, this is working, so this is the bad commit, right? And of course we can do that manually, but the cool thing is Git has a tool for that, and that's called Git bisect.
42:04
And what we can do is we can say, okay, we want to start a bisect, and so we type Git bisect start, and then we have to do two things. We have to say to Git, this is the stuff where everything worked, and this is the point in time where it didn't work.
42:23
So in our example, the current state, the head state, is not working. So what we are doing is we say Git bisect bad and say, okay, the head state is not working. And then we say, okay, Git bisect good, and we saw, no, like in release version two point whatever, it was good.
42:44
And we are getting the commit hash, and we're saying, yeah, this was good. What Git is doing now is exactly doing what was showing before on the slide, right? It's going to the middle. And then we check it. We say, no, this is still bad, and Git checks out the stuff,
43:04
and can we just say, okay, no, we can test it, and then say, okay, this one is good. And then after a while, Git will tell you, okay, this one was the commit that made everything burn in this example, right?
43:23
And here's the advantage of doing atomic commits. If you're doing small commits, the change set that you did in this commit should be very small, and then you can easily find the problem that caused the issue, right?
43:41
So now what we have to do, we type Git bisect reset. We want to end our bisect one, and then we are back to the point where we started in our current head state. And that's quite nice, because we don't have to check out all that stuff manually,
44:01
but we still have to check our software manually. So we still have to do all that stuff and check if our application works. And the cool thing is, if we have unit tests, we can say, okay, we do a bisect, and we do the same stuff, and Git will check out the same commit as before.
44:23
But what we can do now is we can say, okay, let's run our unit tests, and then Git will automatically validate the return value of our unit tests, and so if our unit tests pass, the commit will be marked as good,
44:42
and if the unit tests fail, the commit will be marked as bad. So it automatically checks out all our revisions, and will run the unit tests, and then will automatically determine the commit that did the bad stuff. So you don't have to do anything.
45:00
You can say bisect, unit tests, go for a coffee, and then come back and let Git tell you where the bad stuff happens in your software. So that's really, really nice. And that's one more example of why
45:21
you should make sure that every commit works, because if you have a commit in your history, then maybe you have a syntax error or something like this, or it couldn't even compile, right? Then this wouldn't work at all, because it will always fail, because you can't execute the unit tests
45:42
if you can't compile your application, or if you have some other stuff that's not working there. So that's all from me. Thank you. And if you have any questions, feel free to ask.
46:10
With Git bisect run, do you have a good strategy to run a new unit test against all the old commits? Yes.
46:22
What you have to do is... So if you find a bug, normally there's no unit test for it, right? Because otherwise you would have found the bug much earlier. What you can't do is, you can't write the unit test into a file that's already in your repository,
46:42
because if you commit it, and you check out an older version, the unit test isn't there. So what you have to do is, you have to write the unit test in a completely new file that's not in your repository. And just leave it there. The unit tool should recognize that file, and Git shouldn't care about the file
47:01
that's not in the repository. And if you found the bad commit, you can then move that unit test into the right file and commit it. You have to work around that you can't change a file that's in your Git repository. So if it's a new unit test,
47:21
you have to create a file that's not in your repository. But that works. What exactly does Git run when you do Git run unit tests? So what it does is, it's executing the binary, and it's evaluating the return value of that binary.
47:42
So the exit code, right? So if a Unix command is successful, it normally returns zero. And if it's not successful, it's returning an exit code higher than zero, like one or whatever. And what Git bisect run is doing, it's evaluating this exit code, and if the exit code is zero,
48:02
it will say, okay, everything worked, so it should be a good commit. And if the exit code of the command you run is higher zero, not zero, then it will mark the commit as bad. So you can create, you don't have to do unit tests, you can just write a script, whatever you want,
48:20
in your programming language, in Bash or whatever, that creates an exit code for the failure scenario, and an exit code of zero if everything's fine. So that's another easy way to find the issue, if you don't have unit tests. Just write a script that simulates the issue, and then you're fine.
48:47
What would I do if I have spent two days bisecting the Linux kernel and end up in a 3,000 line merge commit? Is this game over, or...
49:01
Yeah. Yeah, have fun. Yeah, of course. I think there's always, like, big projects, and sometimes it's necessary to change, like, 200 files at once. But if you have created an issue in this type of commits,
49:23
it's really hard, and there's no easy way to answer or to handle it. Yeah, it's hard work to find the issue, sadly. I think there's a good chance that that merge commit has two parents,
49:41
not just one. So there are other commits, which could be run through bisect and search for them, which are still good, and others which still fail. So normally you don't end up at the merge commit in a bisect run. Yeah. Yeah.
50:05
Any more questions? Nope. Then thank you again, and have a nice afternoon.