These days, Git is synonymous with source control itself.
Rare are the current debates of whether to use Git versus SVN versus some fossil like
SourceSafe versus you name it, but do you know how Git works? What about its internals?
I'm sure you've seen a .git folder in your project's root, but to most folks, that's a black
box. In this episode, you'll meet Rob Richardson. He's going to pop the lid on that black box as we
dive into Git internals and the .git folder, among other things about source control.
This is Talk Python to Me, episode 311, recorded April 1st, 2021.
Welcome to Talk Python to Me, a weekly podcast on Python, the language, the libraries, the
ecosystem, and the personalities. This is your host, Michael Kennedy. Follow me on Twitter where
I'm at mkennedy, and keep up with the show and listen to past episodes at talkpython.fm,
and follow the show on Twitter via at Talk Python. Congratulations to Mike Manning. He's the final
winner of our PyCon ticket giveaway. Thank you to everyone who entered, and if you didn't win,
I hope you're able to get a ticket and support the PSF, the Python community, and be part of that
awesome conference. See you in May. Rob, welcome to Talk Python to Me.
So glad to be here. I'm really excited that I get to join you. Great to meet your audience.
Yeah, it's great to have you here. You got to meet Intersection. You gave a talk at the Python
web conference recently that I also spoke at, and your talk was really interesting and certainly
relevant to the Python folks, so I thought it'd be cool to have you over here. And, you know,
I should give credit to Paul Everett for connecting us. He's like, oh, that was a great talk. You should
go talk to Rob. So thanks, Paul, as well, who was not long ago on the show.
Yeah. I've been chatting with Paul about thoughts around the talk as well. He's a really brilliant
guy.
Yeah, he is. He definitely is. He's been doing a lot of cool stuff for a long time. So yeah,
he's a great guy. Now, before we get into Git and all those types of things, which, you know,
it's really surprising to me how much it's taken over the world, right? It used to be,
there was always a question, well, what source control do you use? Like, that's not a question
I hear all that often these days, not at least as much as it used to be. But before we dive into the
details of that, let's start with your story. How'd you get into programming?
This is actually a really fun story. I was 10. I was at the library because they had the computer
and we'd play video games. And the methodology of how you do this is you go up to the counter and you
flip through the book and you go find the video game and you show them that page and they give you the
disc and you have the save icon. You take the save icon and you put it in the computer and you play the
game. So I had finished playing my game and I went back to the desk to go pick another
one flipping through the, you know, plastic sheets. And I found a drawing program. And I said,
I'd like to play this game. They gave me an eight and a half by 11 sheet of paper. The top two thirds
was graph paper, you know, graphs. And the bottom third was how to write the program to draw that on
screen. Oh, cool. Okay.
And it was so much fun. I got to start to build content that was in my mind in real life in this
artistic medium with a very technical implementation. So, you know, that was so much fun. I did never
return that game. And so that kind of brought me into the world of software development. I always
thought it was just a fun thing that people did. I didn't realize it was a career. So it wasn't until
really late in my college experience when I realized that I could do this for a career.
And so after I graduated, I got into programming professionally and I've had a really fun time
coding now for professionally for more than 20 years.
Yeah. Awesome. I think programming is special because it's one of those things you kind of
hinted at where you, you think of something, you dream of something, you imagine something.
And then with a little bit more thinking, that thing can become real. Whereas, you know, so much
of what humans do, it's one or the other. I could tell an amazing story and write the book,
or I could go build an awesome house. But normally those things don't actually coexist where you think
a lot about something and they come into existence. But I do think that's a magical part of what we get
to do. And I think it captures a lot of people's imagination.
And what's really cool is that in this digital world, there are a lot less boundaries, a lot
less constraints. There's nothing telling me that this pixel needs to be in this certain way.
I can draw whatever I want on these pixels on the screen.
Yeah. Yeah. And modern day, we have cloud computing and we have incredible computers. Like
the sky's the limit. It's really, really awesome. Also money. You don't have to go buy tons of hardware
for many things that we do. Right. So really cool. Now, how about today? What are you up to these days?
I'm doing a lot with software development, cloud-based development, a lot of websites,
a lot of web properties, ASP.net and Node on the backend, React and Vue on the front end.
Taking that into interesting modalities, I've started to play with Raspberry Pis and that's
really fun. And getting to dig into all the things. I've gotten really good at doing DevOps as well.
Part of my passion is being able to share this knowledge with others. So I do a lot with teaching
both at user groups and conferences and elsewhere mentoring. And so it's really fun to be able to
not only learn these new skills, but also pass it on to the next generation of developers too.
I love to say that it's not that I'm really good at it. It's just that I've been collecting things for a
while. So let me add to your collection too.
Well, I think one of the things that's really interesting about becoming an expert in programming,
people who are beginners or maybe don't do programming at all, they see that person as
incredibly talented and incredibly smart. And they may be, they often are, but I feel like the real
big difference is I've spent 10 years gathering up these little tips. Like, oh, I tried this.
That doesn't work very well. That crashes. You try to talk to the database that way. That's bad. Oh,
by the way, I've also built up a couple of examples of what databases are. And I've seen,
you just have this almost more experience than, I don't know, like innate skill, right? So it's
really cool. You can just kind of layer on these skills over your career. And the reason I think
that's powerful is it's, they're very easy to communicate back to other people, right? If,
you know, the way Nietzsche did philosophy or the way Euler did math, like you can't, or Bach did music,
like you can't easily communicate that to someone. Like if it's this crazy innate skill,
you can sort of communicate it, but it's not the same. But with programming, I think it's very easy
to transmit it on and pass it on and ways to help people like level up. It's super fun.
And it's really easy to get started. You know, programming languages have become much more
approachable of late. And so if you're new to programming and just starting to dabble in it,
you don't need to buy a big expensive thing. You know, the laptop that you're using to browse the
web is probably sufficient for building simple programs. And so, you know, dive in,
use free tools and just start building stuff. It's really approachable and really fun.
It absolutely is. And one of the things that just never ceases to blow my mind is I can be in a coffee
shop working on a relatively cheap laptop doing my coding. Git push, speaking of Git, something happens
on one part of the cloud. It triggers a web hook somewhere else that then grabs the code and could run
that on a tremendously powerful data center and computer or suite of computers, a cluster of
computers. And yet I get the experience of basically building this super powerful thing on my very wimpy
little laptop. It's just cool that you can create things like Facebook or Google, or you name these,
these really large, amazing apps, but you could kind of just do it on like a laptop.
Something that existed in my mind yesterday exists in the cloud and scaled to any user that wants it
tomorrow. Yeah. That is really fun.
Yeah. It's super, super fun. Before we move on, you also mentioned that you've been playing around with
Raspberry Pi.
So, something that I covered recently on Python Bytes, my other podcast, is somebody built a water-cooled
Raspberry Pi cluster computer. So, eight Raspberry Pis in one thing, all of them overclocked and water-cooled.
Have you seen people doing this stuff? It's crazy.
It's really cool. And as you start to get into clustering programming, clustered programming, you know,
multi-machine type of experiences, a Raspberry Pi is a really cheap barrier to entry. You know, for $40 or so,
you can get a Raspberry Pi, get three or four or five of them, cluster them together, and now you get the sense of
what does it take to build parallel machinery. And it is really, really fun. So, you know, to get an eight or ten or a hundred or a thousand,
node Raspberry Pi is pretty sweet.
Yeah, that's awesome. I mean, you can do something similar with Docker, right? Fire up a bunch of Docker containers, but it's not the same
feeling as like, there's actually eight of them over there, and they're actually talking to each other and working together. I think it's a very
different feeling. It's super cool.
Containers do help us start to approximate that. But yeah, there is some lying to ourselves to believe that all of these containers running in context on my one laptop are really a
distributed system. Yeah, absolutely. It's not the same, but it does let you sort of play around there a bit. Right. All right. So I want to talk about Git
primarily, and that's what your presentation at the Python web conference was about. And that's what we're going to center our conversation on. But you know, you and I have both been around the
industry for a lot of different things.
Yeah.
So maybe let's talk a little bit about the history of source control. You know, I think of source control as a spectrum from what source control all the way to get and distributed source control. Maybe, you know, there's, I've talked to people and I've seen it in action. Source control is I've got a file code file,
and I've called it version one version two version two edited version three version three final final two, you know, just like, or maybe if it's a lot of files, you zip the folder and you name it like that. Right. Like that's the beginning of source control. He's doing it wrong, but it's getting getting there. Right.
Well, it's doing it in exactly the way that you needed at that time. Copy folder versioning is definitely a thing. Dot bu dot date, you know, copy that content off to make sure that you have it. And that's really what we're after with version control is when we think of version control, we're really talking about two things.
One is archiving the history of my journey so that I can get back to a known good state if things go bad, but also communicating with my team to be able to convey the progress of this system.
Yeah.
And copy folder versioning does the first one real well. It doesn't do the second one real well. There are systems that I've worked on where, you know, to upgrade the system is to first copy all the things into the dot backup folder and then upgrade the primary thing. And if it doesn't work correctly, then you point the...
Put it back, put it back, put it back, put it back.
Yeah. They point the web server at the backup folder. And so now the system has been running out of the backup folder for, you know, six or eight months or a year. And now we go to upgrade and step one is to take, oh, wait, we just took down the site. Now we have no known good backup thing.
Yeah. Without some sort of source control, the real thing I think that falls apart, maybe you're doing the file versioning thing, which is still not that ideal, but the thing that really falls apart is collaboration.
Right. Soon as two people want to work on something, it's not okay to say, well, here's my zip version. Can you merge that back together? And probably you don't have merge tools either. So what does that even mean? Right.
So I quickly gets us into where I think people probably should be in some sort of version control, but back in the day, that was different stuff. For example, you know, maybe that was subversion. Actually, if you were on subversion, you were in a good place. I mean, a really good place.
Yeah. Subversion was really cool. Subversion was an upgrade to CVS where CVS would version each file or each folder separately. And so nested folders just happened to kind of be together in this clump.
And what subversion gave us was we're versioning the entire project together in one piece. Before that, we might've had source safe or other pieces. Team foundation server kind of fits into this realm as well.
And so it's that mechanism of versioning all of the pieces together and then being able to publish that to a central place. What makes all of these systems kind of unique, specific is that they're all really client server pieces.
So version was really good at being a client server piece.
I'm going to go out on a limb and say it was the best client server version control system that I'm aware of.
Yeah.
I think so.
These systems though, kind of a fundamental flaw because we want to use version control for those two pieces.
We want to use it to be able to back up the work so that I can get back to a known good state and to communicate with our team.
And the hard part with these client server version control systems is we're doing both every time we commit.
So when I commit a change to subversion, I'm immediately publishing it to all of you.
So the analogy that I like is when I'm rock climbing, I want to be able to put a carabiner in the wall as frequently as possible.
If I climb a foot and I fall, I'm only going to fall a foot.
If I climb six or eight or 12 feet and I fall, I'm going to fall 12 feet.
Well, actually the nature of the rope is that it's going to swing all the way down.
So I fall 24 feet and that's a long way to go.
I want to stick pieces in the wall as frequently as I can.
You don't want to see me spamming the thing every time I get there.
So I get to the point where it's like, okay, I finished the thought.
I'm good.
I want to mark this save point, but I'm not ready to publish it to all of you.
Yeah, because really the thing you should be working with most of the time is if I publish it to the rest of the team, it should be, it should at least run.
Right.
Yeah.
Probably the test should pass.
Maybe you can fix that.
Like you're going to work with somebody, but it shouldn't just mean nobody can build or even start the software at all.
Because you've got the save point in the middle of their work that is inconsistent or halfway there or whatever.
Right.
And so I've reached the stopping point, but I'm not done.
It doesn't work.
And so I have this moral dilemma.
Do I mark a save point and inflict that on all of you or do I not?
And that's when I fall back to a secondary version control system where I start doing copy folder versioning again, where it's like, I just want to take all my stuff and stick it in this spot so that I have this known good state.
And that's where we pivot to distributed version control systems of which Git is one of them, where we have a separation between the commit stage and the publish stage.
And that isn't the official terms that Git or any of the rest of them use, but there's a process of marking those save points.
And then there's a process of collecting all of the save points and publishing them to others.
It takes a bit of a mind shift to get used to it as well when you're working on it, because if you come from one of these other systems, I committed, so it's saved.
Right.
But commit in a distributed source control system means it's a local save point until you Git push or whatever other immacterial's equivalent of a Git push is.
Right.
Yeah.
An HG push.
And so it's exactly that.
It's marking save points however frequently you want and then combining those save points together into a cohesive story.
To publish to your colleagues.
And that's what makes distributed version control so powerful is separating those two concepts.
Mercurial, Git, Perforce.
There are other distributed version control systems.
And as the world was moving from subversion and TFS into this distributed world, we experimented with each of them.
You know, arguably Git wasn't the best.
We might have done a VHS and Betamax type of thing.
But clearly Git has become the de facto standard version control system.
It is distributed.
And now we can separate the save points from the publish points.
Talk Python to me is partially supported by our training courses.
At Talk Python, we run a bunch of web apps and web APIs.
These power the training courses as well as the mobile apps on iOS and Android.
If I had to build these from scratch again today, there's no doubt which framework I would use.
It's FastAPI.
To me, FastAPI is the embodiment of modern Python and modern APIs.
You have beautiful usage of type annotations.
You have model binding and validation with Pydantic.
And you have first class async and await support.
If you're building or rebuilding a web app, you owe it to yourself to check out our course, Modern APIs with FastAPI over at Talk Python Training.
It'll take you from curious to production with FastAPI.
To learn more and get started today, just visit talkpython.fm/FastAPI or email us at sales at talkpython.fm.
I think another really important thing to highlight for people who haven't been there, right at the Git homepage, they highlight Subversion, which we've been talking about.
But Perforce, ClearCase, SourceSafe, TFS, a lot of these things, there's two things.
One, they would lock files.
Like if you wanted to make a change to a file, you would claim it.
Like I'm editing main.py, well, no one else can interact with that file.
It's literally made read-only on your computer until, you know, until that person is done.
And they had better not forget and go on vacation while they got some files checked out.
That's the one thing.
The other is you need permission to participate in a project.
You have these gatekeepers and you need to sort of prove yourself to the gatekeepers.
So if I wanted to commit, I wanted to work on Flask, if it was under Subversion, I have to go.
Can I have permission to go read, get read-only access to Flask?
If I want to make a change, I literally have to say I need permission to commit back to Flask.
With the distributed ones, you clone it, you do your proof of work, your proposed idea.
And if you want, you can contribute it back or you could just go in a different way, right?
There's this very interesting separation of I can kind of work on it and then see if I want to contribute
it back rather than the other way around.
I have to get permission to contribute.
And I think that's a super critical thing in the open source space where there's a very
loose coupling of people and projects.
Like if somebody comes to me and says, I want to work on, I suppose I'm working on Flask.
They come to me, I'm in charge of Flask.
They come to me and say, I want to work on Flask.
Like, well, maybe.
What else have you done?
Show me.
This is a huge project.
We do not want you to mess up Flask.
But.
And we had a little bit of that with SourceForge.
You know, you could clone the repository in Subversion and just work on it locally, but you
weren't able to participate.
The moment that you wanted to help, it was a really frictionful process where, you know,
okay, so I have this diff.
Now, I don't have write permissions.
So am I going to, you know, bake this diff into an email and hope somebody reads it?
Do I just use it locally?
Do I fork the project and only have our corporate version of it?
You know, it was very difficult to participate.
And that's not a feature of Git per se, but rather the GitHub, the shared hosted mechanism
around Git that has grown up as well.
Yeah.
I mean, with Git, you can clone a thing and then work on it as long as you have read access.
But yeah, the additional mechanisms, the Git flow around it is certainly something created
by GitHub with like PRs and forks and the emerging upstreams and all that origin upstream stuff.
One thing I did want to ask you before we get to the details is why do you think Git won?
You did talk about this Betamax, VHS sort of thing, and there are other options out there
for distributed source control.
I have a theory, but what are your thoughts?
And I have a theory too.
I don't have the answer and maybe our listeners will help us discover what the correct answer
is, or maybe there isn't one.
In my mind, a lot of the time we were looking at ways to compete with things.
You know, we had things that would compete with CFS or subversion because, you know,
we wanted a little bit more or we wanted to make money on the process of source control.
And what's really interesting about Git is that it has become so pervasive.
And so we're not building competitors to Git, we're building integrations into Git.
All right.
We're building on top of Git.
Yeah.
Now, arguably GitHub helped with that too.
GitHub has a really, really powerful community mechanism for that.
And GitHub really only did Git.
But I would argue that Git is really cool because it's free and open source.
And because it's free and open source and it has that community mechanism around it,
we don't need to compete with it.
We don't need to try to make money on this.
Instead, we can build collaborations with it and mechanisms working with it and build up the
community together.
My thought as well was GitHub.
Yeah.
It's the thing that brought not just the server infrastructure to privately have code.
It brought the community and it brought the flow that allowed people to collaborate in
ways that could let them collaborate once they've proven they have something to collaborate.
Right.
Here's my PR where I've already shown you the thing that's amazing that I want to offer up
to you.
Well, that does look amazing.
Thank you.
Who are you?
Let's talk about this.
Right.
It's a different conversation than I've never seen you.
Why should I give you right access to Blask on SVN?
And it's exactly that.
GitHub has these magic levels to it where at the very first level, it is just an online
source code repository system.
And so how is that different from SourceForge or TFS before it?
It isn't at this level.
And so if that's what you're using GitHub for, then that's perfect.
You know, back up your local projects up to GitHub, get your content off of your machine
in case there's a disaster.
That is definitely the first level.
The next level starts to build workflows around it where we can say, I want to create issues.
I want to create project management things.
I want to create milestones.
I want to create goals.
And so that's kind of the next level.
Leveling up again, we can start to create a social community around that where we can start
to have conversations around the content where I can create a diff and we can all talk about
it and we can collaborate on it.
And once it's good enough, now we can pull it in.
Add to that then the mechanism around pull requests and things like that.
Git has a concept of push and pull.
You know, publish and receive, I guess, might be the terminology that matches here.
And what's interesting about a pull request, I don't have right access to your repository,
but I want to contribute.
So instead of pushing my content to you, I'm going to request that you pull it from me.
And so no longer do I need to create this email and write out all the content and hope you read the email.
I create this code up in my space and I request that you include it in your space.
And that made collaborating with projects really, really easy.
So with that comes the next level of GitHub where we have these communities that can socialize
and develop and hang out in this coding space.
And that's really what made GitHub so magical is that we have this community around coding.
Where previously with SourceForge or other environments, yeah, we had that online source control system,
but we didn't have those levels of interaction.
So pull requests or merge requests or whatever you're going to call it,
is that mechanism of being able to collaborate with low trust type of environments.
I want to offer up my solution to the community and see if that's going to fit into this ecosystem.
Yeah, I think that's why I get one as well.
And Verda Rose out there says,
open source is the best way to learn and improve technically and collaborate with people you don't know.
Yeah, and I think it's that the people that you don't know,
it makes it special because it allows you to create these connections with people all around the world
who you would otherwise not meet.
And you get a chance to work with them.
Even if you live in rural Canada and you want to do software development,
maybe no one around you is really good at whatever you're trying to do,
but go to GitHub, find a project.
You can collaborate with the best people in the world on that.
We can create these communities around our passions for technology
or the problems that we want to solve,
not necessarily based on the geographic boundaries that we find ourselves in.
Yeah, absolutely.
All right.
So that's the history of it a little bit.
I talked a little bit on why distributed source control is really powerful.
And I think it has really unlocked open source in a special way and on a much larger scale than it has.
And it is interesting to note that Git and GitHub are different.
GitHub uses Git under the covers to be able to build its social experiences.
But Git is a thing that is separate and distinct.
There is no pull request concept in Git, for example.
And with Git on your local machine in a cave, you can version and create those save points.
When you're ready to socialize, to publish your content, to communicate with your team,
you can use Git together with lots of services, GitHub or Bitbucket or GitLab,
or there's lots of private services as well that allow you to create that online community.
You know, GitHub has published their magic sauce to the world and lots of us have cloned it.
So GitHub is still the place where we code for the most part.
But if you prefer coding in another community, then that's totally fine.
You can still use Git and all of the tools to be able to create your save points and publish that content to others.
You could just publish it to a different server as well.
Git and GitHub are different.
It's easy to see them as the same thing.
But yeah, they're absolutely not.
We've got all these different locations.
I have mixed emotions, mixed feelings about if you have another project and you put it somewhere else,
I'm not going to name any particular service, but let's just say somewhere that's not GitHub.
That's totally good.
But at the same time, so much of the open source flow is around GitHub and the stuff that's happening there.
I don't know.
It's just really interesting to think why you might be at one place and not the other place and so on.
Yeah.
And a lot of people were worried when GitHub was bought by Microsoft, is this going to be the end of the community collaboration?
And I think Microsoft has been a really good steward of the GitHub community and really making sure that GitHub is still available to all of us and facilitating the success of that ecosystem.
Yeah.
There was a lot of hesitancy and concern within certain communities.
And I feel like they've done a great job.
Yeah.
What I didn't realize was that GitHub really needed some help from somebody.
financially, they were not doing as well.
And I looked at them like, oh, this place must be incredibly successful.
But what came out after some of the reports and stuff, it was kind of important that someone came along.
And if that's the case, then I was head over heels that Microsoft bought them.
Last thing I want to see is them go away.
And I think they've done a good job of just letting them be.
Don't go mess with them.
It's working really well.
So I think it's been a good deal that worked out there.
See also Docker for an example of a community that is amazing and contributing, but doesn't have a financial business model to be able to survive.
Yeah.
Hopefully things go well for Docker, but it's just tricky.
They tried the enterprise thing and then they're switching to other things.
Yeah.
I love their pivot back to focusing on developers in the community, which is wonderful.
But I still feel like they haven't found their spot that allows them to be business successful.
And the hard part is you can only do that for so long and then you need to pivot to something that can start to facilitate the business.
Yeah, absolutely.
All right.
Are you ready to go into the Git folder and find where the hidden magic lives?
Yes.
If you go into a project that you've Git cloned or you've Git inited and you create some files and you mess around there, you don't see anything different.
It looks just like any other folder that might have a project in it.
Right.
But in there actually is contained the almost the entire backup, the entire contents of all the versions of those files.
At least every branch that you've checked out hidden in the hidden .git file.
So .git on.
And it's not almost.
It is.
That is the entire history of the project.
So the way to back up a Git database, misusing that term, is to grab that .git folder and copy it.
Inside that .git folder is lots of files that describe the history of the project since its inception down to the current version.
And so, you know, kind of the only way that you can break Git is to open up that .git folder and change stuff.
By default, this folder is hidden on most systems.
So you may have to show hidden files and folders to be able to see the .git folder.
But it's there.
And it's really powerful.
Yeah.
And so on Windows, you go to the Explorer, there's like one of those little ribbon things that drops down.
It's a checkbox for show hidden folders and files.
On macOS, I learned you can hit shift command dot and that will show hidden files.
That I did not know.
And I was very delighted when users told me about that.
On Linux, I don't know.
I mean, you can go and do an LL in there on the terminal.
But there's probably some way to show it in the Explorer equivalent as well.
You can navigate into it from your terminal or wherever.
And once you're inside of it,
Yeah.
All of the files are right there.
Yeah.
So we go in here and we find things like head, config, description, hooks, index, info, logs, objects, hacked, refs, and refs.
You want to maybe give us a rundown of what each one of these are?
And then we can dive deeper with one of the tools that you built into maybe some of the things like refs and so on.
But yeah, also maybe hooks.
But yeah, wherever you want to start.
What's cool in this database is it is the entire history of your project.
And it's zlib compressed.
So for example, the 20-year history of Perl, the .git folder is ever so slightly larger than the checkout folder.
And that includes the entire history, including all of the changes and all of the authors and all of that is really nicely compressed into this folder.
Wow.
It breaks down into a couple of groups of things.
We have the content.
We have branches and tags, you know, references to the content.
We have configuration details around this repository.
We have index files.
We have temp files.
And then we have automation tools.
And so these are kind of the groups of things that we'll find in this folder.
A lot of them happen to be in their own folder, which is really nice.
So for example, hooks is the place that you go for automation.
Refs is the place where all of the content is.
No, refs is the place for branches.
Objects is the place for the content.
And so a lot of the things that we'll see will have their own folder, but some of them spill out.
Like configuration is in the config file, but there's also some stuff in the info folder for that.
Indexes, we've got the index file right there on the root directory, but we also end up with index files inside of pack folders.
And so, you know, it gets a little bit interesting.
The first one to dive into is probably the objects folder, because this is the stash of all of the content in your repository.
Now, as you commit something into Git, you'll first add it to the staging area, and then you'll commit it with a message.
And as you do so, you'll end up with content inside the objects folder.
Now, what's interesting to note here is if you look at a Git log, you'll see hexadecimal thing.
You know, it might be seven characters, or it might be much longer than that.
And as you do that log, you can take a look at that.
Inside the objects folder are folders with two digits.
Those are the first two digits of the commit number.
Inside that folder is all of the commits that happen to start with that two-digit number or letter.
So, you know, that means that not all of the files will be in one directory.
They'll kind of be arranged a little bit.
That gets around too many files in one directory.
But it's that objects folder that then stores all of the content there.
Now, what's interesting is I think of it, if I commit one, and that's where this talk was really cool.
When I commit one thing and I go look in that objects folder, I will have three different files.
Now, they are zlib compressed.
Yeah, you can't just open them up and look at them, right?
They're kind of scrambled up.
But it's not magic.
I built a tool that will unzlib compress one, which is pretty cool.
But once we identify a thing that we want to do, we can also use git catfile.
Git catfile allows us to look at both the type and the content in a particular node.
This is a directional, acyclical graph nodes, DAG nodes, that specify relationships between these things.
But what's cool is we...
Here's a branch.
Here's a file that's in that branch, something like that.
They're not branches, but they are folders.
Here's a file within a folder.
Here's the content.
So we have three different types of these nodes.
One is a commit.
And in the commit, we have the author's name and the date that it was committed, the message that we gave.
And also in that commit is a reference to the tree nodes that are part of that commit.
Now, each tree node can specify files or folders.
So a tree node can reference another tree node.
And inside the tree node, we have references to those files.
So I might have a tree node that references file1.txt.
The third type is a blob.
And so as we look at blobs, then that's the actual content in the thing.
So go back to the...
Click on...
Oh, I don't think I have a one to get back to the blob.
But the cool part about this app, hit refresh, and you'll get to that big blob of stuff.
Here's all of the commits in this repository.
So we had something visually to look at here, and it's about to pull up its rendering.
Yeah, it's not super performant.
That's all right.
You built this thing called Git-Explorer, which is a little web app that runs that you pointed at a Git repository.
And it lets you look at these things that you're describing visually and then click around on them, right?
Right.
So click on Show Type, and we see the three different colors emerge.
There are commits, trees, and blobs.
And it's like, okay, I have a whole bunch of files in my objects folder, and I can click on each one, and I'll use that Git cat file thing to go figure out what it is.
But it's like, you know, I really wish I had more stuff about it.
So that's where I click alphabetical, and that will put them all in order.
Click on Tags, and now you can see the name of that thing.
And I'm only showing the first seven digits of the commit here.
But now you can kind of get a sense for, here are all the objects, and click on each one and open it up.
Right, and these names are what often go by shahs in Git parlance, which is just the type of hash, S-H-A, whatever it is.
And I don't know how many people know this, but you can use sub pieces of the shah to refer to it in Git.
So you don't have to say the full, I don't know, what is that, 32 characters or whatever to describe a name.
As long as it's enough to be unique, it'll go, like, you can issue commands against these things in this abbreviated form, right?
Right, exactly.
So oftentimes, only two digits is necessary, sometimes three or four.
And that's why often when you're looking at Git history, it'll only show you the first seven.
Surely enough, yeah.
Now what we start to do as we're clicking through this is we get a feel for all of these green nodes.
That's the content in the files.
The blue nodes are the tree nodes.
And as I click on one of those blue tree nodes, then it references other files.
I can see their shahs, their Git hashes there in that list.
And then as I look at the red ones, the commits, that's my commit message.
That includes the parent node that was the commit right before this.
It also references the tree node that has the files for this.
And so wouldn't it be nice if we could, I don't know, arrange them in a way?
So let's, instead of going from alphabetical, let's click on parent-child and start to see the relationships.
We'll need to turn on lines now, and we probably want to also turn on tags.
And now we can take a look at those commits and see how each one references.
Now, if you have a very large repository, then I haven't built scrolling yet.
Sorry.
But you can see that the red commit nodes all reference each other and reference the previous
ones.
And then they go into these tree nodes that may reference other tree nodes.
And eventually those reference the file nodes.
That's part of my demo highlight that if we create the same file content and commit it in
two different directories, it's actually only one blob on disk.
There's only one green blob node.
But the cool part here is we were able to explore each of these objects in our repository and we
get a feel for how they work.
So if I change one line in a very big file, what gets committed?
Well, the entire file.
Yeah.
And I'd suspect that's probably why large binary files are not ideal to be committed here, even
though you technically can put them there.
Right.
So that's the first group of things is these objects.
So that's the top level objects folder in the .git folder.
Yeah.
Yes, exactly.
Now, there is a pack folder inside there.
If you run various commands, then Git will say, well, do I have too many commits, too many
of these objects that I need to pack together to make this repository smaller on disk?
And if so, then it'll automatically do a GC, a garbage collect, where it starts to pack those
into pack files.
Now, it's kind of a Zlib compressed group of Zlib compressed files.
So it gets very meta there.
But that's what the pack folder is inside the objects folder.
Yeah.
Okay.
So next up, let's talk about the refs folder.
Now, when we look at refs, we look at branches and tags and remotes.
These are files that reference commits.
So one example is the head folder in the root of the .git directory.
And inside that head folder, it will specify what head points to.
So if you do a Git log and you see that head has an arrow pointing to, I don't know, main
or trunk or develop or whatever, then if you open up that head file, you'll see the text
in that file is that file.
It's basically the SHA, right?
Is that what it is?
It is the SHA if your head is pointing at a SHA.
But typically, your head won't be pointing at a SHA.
It'll be pointing at a branch.
Oh, yeah.
Refs.
Mine right now is refs slash heads slash main, which is the default branch for this project.
So that's awesome.
Main being the branch.
Yeah.
Head says it goes to refs, heads, main.
So we can go into the refs folder.
We can go into the heads folder.
And we can open up main.
And what's in main is the SHA of the commit that main points to.
Okay.
What's cool here is that each of these refs, both head and all of these branches, is just
pointers to the commits in the objects folder.
Yeah.
So these are like the main file is just a text file that just literally has only the SHA that
is where that branch currently is.
Exactly.
Okay.
So technically, to create a branch, I just create a file that happens to be in refs, heads.
I name it something and I give it a SHA.
And now I have a branch that points at that thing.
Branches in Git are not these durable, fragile things like in TFS or in Subversion.
Branches in Git are just name tags.
They're pointers.
They're references to the commits in this tree of objects.
So the cool thing is we can move them around.
Right.
They're basically a path of these named commits through the history of the overall history
of it, right?
Right.
They're the labels that we give it so that we can understand it because communicating in
32-digit SHAs is not as much fun.
No, definitely not.
Definitely not.
One of the talks that I like to do is I do a Git log and I show that 32-digit hash and I
read it out.
And then I walk up to somebody in the audience and pretend they're the project manager.
And I go, can I ship it?
And they're like, yeah.
Thus, we have these labels.
Yeah, that's right.
In the heads folder is all of the branches.
In the tags folder is all of the tags.
And there are also just files pointing at commits.
Sorry, my repo is empty.
I don't have any.
But if you, you know, people might tag a release or a version or a beta version or something like
that.
So you can refer to it by name, by label instead of, you know, main with the SHA or
something weird like that.
Right.
And then we would have a remotes folder, which references where I last saw another copy of
this Git repository's branches.
Yep.
So in this case, you have one that says refs, remotes, origin, main, and that's perfect.
That's where I last saw this server, this server's main branch.
Now, in this case, I chose to call my main, my remote server origin.
Now, this could be a server that we've designated as the server.
It could be one of my coworkers.
It could be a network share.
You know, Git isn't really opinionated about what constitutes a remote repository other than
that it is in this one.
Yeah.
Okay.
How does it know what origin is?
As I create a remote, I'm going to name it.
Okay.
So as I clone, I'm going to say, Git clone this repository and it'll build one and it'll
by default call it origin.
But I could also say, Git remote add origin.
I just gave it a name and then give it a URL.
I could say, Git remote add upstream.
I could say, Git remote add Michael.
Now it's a reference from my repository to yours.
And so it's just in this case, in the refs, remotes folder, it's just a folder
referencing the branches that I saw on your machine.
Nice.
Is there somewhere where it stores like the URL?
It does.
And that is the next section that we may want to look at, which is configuration.
Let's open up the config file in the root of the .git folder.
All right.
Now this configuration file is really cool.
It includes all kinds of configuration details associated with our repository.
Now in this case, we have remote origin where we've named this one and here's the URLs that
we go to there.
In this case, it's github.com/talk Python.
We have other configuration details associated with this repository.
This .git config file is actually one of three on my machine.
And we'll start out with our config file that's installed when we install Git.
So it's probably in program files or it's in user local bin or somewhere off in the ether
of how we install it.
We probably don't want to touch that one.
But that's the base configuration of all the options that we chose when we installed Git.
So if I run a command, if I were to say something like git email global, something like that,
you know, the .g command, maybe it's modifying that one.
Well, the one that we just talked about was the system one.
The second one is the global one, which is user specific.
I find that name a little confusing.
But my user specific, the .git config in my user home directory.
So, you know, see users rob or user or the tilde slash directory Mac and Linux.
That .git config overrides any settings in my system configuration.
And so oftentimes when you first install Git, you'll say git config dash global user.email user.name.
And so if you open up that .git config in your user home directory, you'll see those settings.
You'll see your username, your name, your email, and all of the details that you've configured there.
And then the third one is the config file here in your repository that will override any of those settings.
So it doesn't make sense for us to have origin in our system, in our user specific configuration file,
because, well, each repository will have a different origin.
But it probably does make sense to put our name and email in our system, in our user specific directory,
because that would apply to all the repositories on our machine.
Yeah, absolutely.
Almost all of them.
You might be doing home-based open source work, and you might be doing corporate button-up work,
and your formal corporate place might not love your corporate email on the open source project.
Exactly.
Or maybe you don't have it.
Exactly.
Yeah.
So when I have that scenario where I need to set my email address,
maybe my name differently in different repositories,
I can set it in my .git config in my user home directory,
and then I can override it in each repository.
Just copy those couple of lines, set them in your config file here,
and now you've set this repository to track your email differently.
Is there a git command to change it so I don't actually go into the .git folder,
and I say, like, git email but not global, or git config email?
Yeah.
Leave off the --global.
Yeah.
Okay.
Perfect.
Then you don't even have to know how.
You just know I do git email and what my email is.
Right.
Now, there are other configuration files here in the .git folder,
but the config file is really the big one that we like to talk about.
Yeah.
Okay.
But you'll see a description file here.
That's a configuration file.
Git InstaWeb is a web server baked into Git
that allows you to kind of browse through your repository.
Now, Git InstaWeb works pretty well on Linux and not so great on Windows.
I bet you've never used InstaWeb in most scenarios.
I'd never heard of it until you brought it up the other day.
Yeah, but this configuration file is the name of the website
when you launch Git InstaWeb.
Yeah, so Git ships with a web server that can be the host of that Git repository.
Yeah.
Now, why would I ever do that?
Why wouldn't I just use GitHub?
Exactly, which is why you've never heard of Git InstaWeb.
Yeah.
I mean, you might say we want a private Git server or a public Git server
or something like that.
That might be.
But yeah, usually, yeah, I've never heard of it.
So very interesting.
All right.
What else is in this list here?
Yeah.
So we've talked about the content in the objects folder.
We've talked about the branches and tags in the rest folder.
We've talked about configuration.
Let's go poke in the hooks folder.
Yeah.
Hooks is interesting.
Yeah.
It is really cool.
The hooks folder is where we do automation.
Yeah.
So people probably heard of pre-commit hooks, right?
Like probably the most popular example in the Python space is to run the black formatter.
So it automatically formats your code before it checks it in.
So indentation, white space, like between a comma and an argument or something.
It's always consistent.
So you don't get these like back and forth editor driven, you know, merge issues.
There's no real change.
But I format it in my editor.
You format it in yours.
And back and forth, it goes between spaces with a comma and no spaces with a comma,
spaces with a comma.
And so you could set up a pre-commit hook to canonicalize it before it goes in.
But there's more than pre-commit, right?
Yeah.
I could set up a pre-commit hook to make sure all my unit tests pass before I commit.
I could set up.
And so what we see here in this hooks directory is all different kinds of automation things.
So a pre-commit hook, a pre-merge hook, a pre-push hook, a pre-rebase hook.
And each of these are shell scripts.
Well, with one exception, it's a Perl script.
But you see at the very top, it says slash bin slash sh.
Well, I'm on a Windows box.
Is this shell script still going to work?
Well, yeah.
Get ships with enough Linux-y, Unix-y, Bash-like stuff to be able to kick off these shell scripts
and run them as it would on any Linux system.
Okay.
Interesting.
So there's basically like a little mini Bash that comes with it.
I remember people using that Bash shell from Git.
It'd be more Unix-like on Windows.
Exactly.
So here in this shell script, I could do all kinds of things.
Maybe I'm calling a PowerShell script.
Maybe I'm calling a Python script.
Maybe I'm calling a Node formatter.
I can just call into whatever tasks I want to accomplish.
And that will then accomplish that task whenever this event happens.
So what I love to do in my demo is remove all the dot sample pieces so that they're actual scripts.
And then just merely the presence of that file will be able to kick off that automation.
All right.
So there's a bunch of files that are sample shell scripts named things like pre-commit.sample or pre-merge commit sample.
If I just called it pre-commit but not the dot sample, now it's going to be active?
Exactly.
Okay.
Nice.
Now the cool part about these is that I have all my automation set up.
I'm running the formatters.
I've got my unit test passing and it's great.
But this file is inside my dot git folder.
So I can't commit these.
It's not one of the files that is available for me to add to the staging area.
Right.
It would be Inception if you tried to commit stuff in the dot git folder.
Right.
So often we'll create shell scripts outside the dot git folder and commit them and then have something here inside the dot git folder that calls into that other shell script.
Yeah.
And you mentioned some kind of node-based tool that you can use, right, that will manage that stuff, right?
Right.
There's lots of packages.
The one that I show is git hooks that is an npm package.
And once you install git hooks, it will actually create all those aliases from the folder where you actually build the scripts that you can commit into this hooks directory so that then they'll run.
Just installing this package installs those hooks into place.
I see.
So basically, if you just install the package once, it will find those other external scripts and make those be the ones that git sees with the advantage that you can commit them into GitHub.
And if somebody makes a change, that change will propagate to everyone else.
Yes.
You can commit them into git, push them up to GitHub, and they will run.
Okay.
Yeah.
Fantastic.
Yeah.
Very neat.
Okay.
What else have we got here?
What else have we got?
I think maybe index, maybe?
That's an interesting one.
Yeah.
Index is really interesting.
As we look through index, if we just pop it open in an editor, it's just a bunch of gobbledygook.
And we're like, what is this?
It's a file, right?
Yeah.
This isn't the only index, but this is one of the really cool indexes where git keeps track of interesting stuff.
That's nice.
Yeah.
Check out this blown up.
If I try to look at it, it's like a binary blob exploded and died on my terminal.
But there are file names in there somewhere, so it must be something to do with that.
Yeah.
I think it's git ls-files, where you can go look through this index.
And if we pass in flags to that, then it'll be able to show the status of those files.
But this is looking through that index.
And the cool part about looking through that index is that git, if it wants to do a quick thing,
like which files have changed, needs to know the blob that is checked out in my working directory.
You know, which blob did I start with?
Right.
As we look through those objects, we saw a big tree of things.
And so opening up each commit node, finding all the tree nodes, opening up each tree node,
finding all the blob nodes, that takes a while.
And so this is a cache, an index, of all the files that I checked out in my working directory.
This allows git to move really fast as it looks through my folder and identifies any files that have changed or new files or things like that.
So that's what this index file is for.
Yeah.
And my git incantations are not pulling it up here, but I think you can get it to show the shah of each file as well, right?
Right.
In which case, then instead of traversing the whole history and actually looking at the file on the hard drive and saying,
well, what is its hash?
Do I have an update for this file?
I could just look in this binary file and get that answer, right?
Exactly.
Nice.
Yeah.
The next section of files that we want to look at are logs.
And the cool thing about git's logs is they keep track of where all of our branches have been.
So if we cat.git slash logs slash head, then we get a thing that kind of looks really weird.
We've got really long lines in this.
And in our first line, it says a whole bunch of zeros.
And then we've got the git shah of the commit that it went to and a little bit about that commit.
This is a log of where our branches have been.
And so we'll have a file for each of our branches.
In this case, we're looking at the head file.
So we see that head started out nowhere and ended up at ed13fc.
And then it has my username, my email, and then some other stuff.
Yeah.
The really interesting thing is this log can be really useful if, for example, I switch branches
and forgot where I was.
Or I commit something and then I uncommit it.
That's a thing.
And I want to get back to it.
Or I delete a branch before I merged it in.
Or, you know, those types of things.
If I do that quickly enough, you know, remember git's going to do that garbage collect and go prune nodes that aren't used anymore.
If I get there quickly enough, I can use this log to go back through my refs and go find that commit.
The objects are still there.
I just don't have any refs pointing to them anymore.
And so the command that we can use on the command line is called git ref log.
And we can pass git ref log a particular branch we want to look at.
But by default, if we just say git ref log, all one word, then it will show the history of head.
Now, in this case, we didn't move it very far.
But we can see there, oh, and here's the branch that I just deleted.
And here's the SHA for this one.
And so at that point, then we can git checkout that commit and get back to the content that we had created and then lost the reference to.
Right. Okay. Nice.
There's a little bit of recovery, kind of an undelete if you had to in there.
Yeah.
Nice.
The funny thing about this, the command is git ref log.
But I've also heard it pronounced git ref log.
And I'm like, so I've got this cat of nine tails.
And I'm like, no, you can't.
Git ref log.
Exactly.
Do it again.
But once you understand how the refs folder works, then git ref log makes a whole lot of sense.
We're looking at what those ref files have said in the past.
Here's what it was before we changed it.
Here's what it became after we changed it.
And a little bit more context around it.
Where you're currently working is where the head is pointing.
Often that's some point in a branch.
And this is like, where's the history of that bin throughout the branch that it's on?
Yes.
Yeah.
Very cool.
So we're getting sort of short on time here.
What else should we be talking about?
What else should we close this out with in terms of content of our .git file?
The only other section in here is temp files.
So if we've committed stuff, we might see a commit underscore MSG file.
Or maybe it's called commit underscore message.
We might see other temp files.
We have a temp folder sometimes baked into things.
And so that's the last group of files here in the .git folder is temp files.
Temp files, configuration, objects, refs, hooks.
These are all the pieces that come together to make this git database.
And once again, you really can't break git.
You know, it's like, well, I did this incantation and it's broken.
Well, no.
You can use ref log to get back to a particular commit.
Or you can use various commands, checkout to get back to where you need to.
Maybe you'll use reset to, you know, kind of get your working directory back in shape.
But that structure of git, the double entry bookkeeping inside this repository, is really
good at keeping track of the things.
And so you really can't break git.
Yeah.
And back this up.
You back it up, right?
You back up this folder.
You back up basically everything, right?
All right.
Now, it might be easier to back it up, not by just backing up this folder, but by publishing
your changes to another repository.
And that's where we have great workflows.
Like, I will push all of these changes to another server.
Maybe I'll call that server origin.
Yeah, absolutely.
And that is automatic if you check out from somewhere like, clone it from somewhere like
GitHub.
Right.
GitHub.
So there's just a couple other things maybe I want to touch on really quickly while we
have a moment.
When you talked about breaking git, there's an interesting little design thing called dangit,
git, or even better.
Maybe I'll link to the better version, the not safe for work version where you're frustrated
and it's like, oh no, I just did something terribly wrong.
Please tell me how to do it.
And reflog is right at the top of these things.
I committed and immediately realized I need to make a change or I need to change my commit
message.
And yeah, anyway, that's a pretty interesting one.
Another thing we've talked a lot about GitHub.
And what we haven't really talked about is gitignore, right?
As much as you want to track stuff, you don't want to automatically track a bunch of things
that are working files, you know, build stuff from C++ or maybe node underscore modules
or high charm working files or all sorts of things should not go into your project, right?
Your vn directory.
Yeah.
Yes, exactly.
Your vn directory.
Absolutely.
So there's gitignores.
Any content that you download, any content that you compile, any of that content shouldn't
be in your repository because it changes too infrequently and it's usually easier to either
rebuild it or redownload it.
All those things should be ignored.
Yeah.
It's a huge merge nightmare as well.
Even if you could keep it, right?
Suppose I check in my vn directory and you go on Windows.
Well, you can't have the same contents as mine because mine is the macOS version.
So you change it, put your Windows version in there and I get it back out and it breaks
my Mac versions.
I got right.
So there's stuff you should ignore.
Absolutely.
And when you create a new project on GitHub, it very handily says, hey, what kind of project
is this?
We can get you far down the road with your gitignore.
Is this a Python project?
Is it a node project or whatever, right?
What I wanted to point out is that dropdown list.
There's actually a GitHub project called gitignore that has the ignore for all of these different
languages.
So if you want to make a change to say Python's gitignore, you can go there and pull it up
and see it.
And you could technically do a PR against it to say there's this new thing that's common
in the community now.
Please fix it.
That's pretty cool.
And these things aren't perfect.
You know, most of them will exclude everything that starts with or ends with or contains
log.
But your iLogger or your log handler might get excluded by that as well.
So you may need to adjust this to get it the way you want.
Yeah.
But it is nice to know that at least it'll give you a bit of a start and that it's a thing
that you can contribute back to.
It's not just magic inside of GitHub, but it's its own GitHub open source repository.
Right.
Yeah.
Quite neat.
Let's see.
What else should we cover really quick?
I think maybe just one other thing I think that's maybe worth throwing out there that was
interesting, but it's pretty specific.
But you've mentioned Windows a couple of times.
Maybe two things, actually.
One is on the shell that you saw on my screen just a minute ago, when I was inside of a git
repository, it would actually put what branch it was on and the git state and so on.
And I have that because I have OhMyZShell installed.
Which is a really nice shell for Mac and Linux that gives you things like branch awareness
and number of changes and so on.
I saw your talk.
You had something like that for PowerShell, the new Microsoft terminal.
What were you using for that one?
It's called OhMyPosh.
And Scott Hanselman has a really cool video about OhMyPosh where he walks us through how
to get it installed.
There are various themes into OhMyPosh, but the theme that I really enjoy actually puts the
cursor on the next line.
One of the things that I frequently do in command prompt is I have all of the path to get to
this folder.
And so the command that I'm trying to teach ends up getting wrapped to the next line.
And so OhMyPosh or OhMyZSH gives you that additional context of how's your git repository
doing?
You could also show your remote.
It's basically just running a shell script behind the scenes.
And so you can modify that shell script.
Scott Hanselman is diabetic and so needs to check his blood sugar a lot.
And so he actually has built into his OhMyPosh script, his blood sugar number, because it's
really easy to miss.
And it's one of those things that's really important not to miss.
So it's in his terminal all the time.
Probably even color code it, right?
If it's out of range, make it red.
If it's not out of range, you make it green, something like that.
Yes.
Wow.
How interesting.
Yeah, this looks fantastic.
I've never played with this before, but yeah, it looks really nice.
You recommend it?
Yeah, I do.
Cool, cool.
All right.
Well, I guess the one other thing that I was going to throw out there is I heard of this
thing called VSF for Git.
We talked about large files and this sounds like it's very much a Windows only thing, but
it's a neat idea.
This virtual file system for Git that if you have a really large repository, it's kind of
like the smart sync for Dropbox or something.
It only pulls the files and interacts with the files that you actually touch, but it does
that behind the scenes without you knowing it.
Have you seen this?
Yeah.
And we actually said VSF for Git, but it's actually VFS for Git, virtual file system.
It's great when your repository is just massively huge.
And 98% of our repositories are not.
But when you have the code base of, I don't know, Windows, then you need something like
this because you can't Git clone the entire thing.
GitHub, not GitHub.
Google is famous for having their corporate monorepo.
And I suspect that's bigger than you could Git clone onto each machine as well.
And so the cool part is one of the benefits of subversion that we lost as we moved to Git
was I could clone only part of a repository.
And VFS kind of gives us that ability back.
Most of the time we don't need it.
But if you've been really bad and you've committed a whole bunch of binary files to your repository,
it's interesting.
It might be worth kicking the tires.
It isn't necessarily Windows only.
It is plug-in to Git itself.
But it allows you to put that checkout directory somewhere else.
So, for example, on a shared network drive.
Now I have all of those objects, all of those blobs in one place,
and I don't need to copy each of those to my machine.
Yeah.
Interesting.
The Windows people that were switching to Git said it was really a nightmare.
So, for example, the source code for Linux repo is something like 600 megs or 0.6 gigs.
Windows is like 270 gigs.
So it's really ginormous.
And they said to do a clone took 12 hours.
To do a checkout took three hours.
To do a Git status took eight minutes.
And to do an add and commit took 30 minutes before they made this change.
So they were suffering some hard pains to go down this path for sure.
I guess it probably is worth it for them.
Right.
All right.
Well, I guess we probably should put a bow on it.
We're more or less out of time there, Rob.
But I'll ask you the two questions I always ask at the end of the show.
If you're going to write some code, what editor do you use?
It depends on the code that I'm trying to write.
In most cases, I'll reach for VS Code.
But I'll also reach for Visual Studio.
Right.
If you're going to be doing ASP.NET stuff, like you said.
Sometimes I'm also known to reach for...
If you're doing like ASP.NET or something you were talking about like that or something you could...
Maybe something like WPF where the tools are built in.
You have to basically...
Not have to.
Almost have to use them.
But sometimes I also reach for Sublime Text or TextEdit.
Cool.
And then often ask for a Python package library recommendation.
Maybe we could make it your Git script.
The one that runs the pre-commit stuff.
The one that moves that outside the Git file.
What was that called again?
It's called Git Hooks.
Git Hooks.
And let me grab a link to it.
It's actually a Node package, but exactly.
Yeah.
You just install it wherever.
And it's good to go, right?
Yes.
And so if you have maybe a Flask server and you want to...
As part of your Flask server, maybe you have a React or a Vue app or you need to pull down
jQuery as part of your client-side dependencies, then you may have enough Node stuff to be able
to leverage this as well.
Yeah.
That makes a lot of sense.
If you're already using NPM because you're doing front-end stuff, then you might as well,
right?
Yes.
Yeah.
Very cool.
One of the things that we didn't talk about, and it's really cool how this happened,
Git workflows.
What's beautiful about Git is it's really unopinionated about how you do your workflow.
Are you going to do GitFlow?
Are you going to do GitHub Flow?
Are you going to do something else?
Git can work for all of those scenarios because it is just a mechanism of committing and sharing
files.
It doesn't impose a specific branching or naming convention.
You can choose to put those on top, but Git's workflow is really open to whatever you need
it to do.
Yeah.
Well, when I was first getting familiar with this whole PRs and merging and those kinds
of things, I felt like, oh, that's a Git thing.
That's a GitHub thing.
It has nothing to do with Git, right?
It just Git facilitates that on top of it.
So you can choose however you want to work, right?
Right.
Quite cool.
All right.
Well, I don't normally close out this show with a joke, but Robinson had a good one here
in the live stream.
So I'm going to put this up here for us as our parting thought.
And then I'll ask you for one more as well, maybe.
Yeah.
So he said, there's a programmer who once told him, couldn't use Git.
He was afraid to commit.
He was afraid of the Git commitment.
Oh, that's awesome.
Yeah.
Thank you for that.
Thanks for making us laugh.
All right.
Find a call to action.
People want to go a little bit deeper than Git.
Maybe they just do the three commands, Git clone, I don't know, Git add, Git commit,
Git push.
Like that's four commands.
Like beyond that, like how do you get more into this world?
What's really interesting is as we're coming off of those other systems, we want to kind
of build up that tribal knowledge that we had.
And so we're going to go grab those three or five commands and we're going to stick them
to the post-it under our keyboard.
Take the next step to go figure out, you know, what is the next command that I want to do?
Or how does this command work?
What we did today was we explored through that .git folder so that we could take that next level
to see how it works.
Git isn't a black box.
It's not magic.
It just works a little bit differently than the source control system you might have been
familiar with.
So definitely get familiar with it.
Google the terms that you're looking for and really start to embrace that mechanism and
get really powerful with Git.
I'm confident that you can get past just those few commands and you can make it just an inherent
process in your workflow and use it to be really, really powerful.
Specifically, separating the save points from the publish points.
That's the thing you couldn't do before that you can now do with Git.
Yeah, well said.
Definitely agree with all of that.
I think getting really good with source control and source control these days really means Git
almost.
It allows you to be fearless with your code, right?
So often people are like, oh, I would like to try this, but what if I break it?
What if it doesn't go right?
Well, if you know how to create your branches, work locally, do all sorts of stuff, roll back,
you can just go crazy and just explore things.
And if it doesn't work, throw it away.
No harm, no foul.
It's lovely.
And if you get really stuck, hit me up on Twitter at Rob underscore Rich and show me the code where
you got stuck and let's get you unstuck because I would love to continue this conversation and
really help you be successful.
All right.
Well, thank you for taking the time and being here.
It's been great to chat, Git with you.
Most definitely.
Thanks for having me on.
Yeah.
See you later.
This has been another episode of Talk Python to Me.
Our guest on this episode was Rob Richardson.
It's been brought to you by our courses over at Talk Python Training.
Want to level up your Python?
We have one of the largest catalogs of Python video courses over at Talk Python.
Our content ranges from true beginners to deeply advanced topics like memory and async.
And best of all, there's not a subscription in sight.
Check it out for yourself at training.talkpython.fm.
Be sure to subscribe to the show.
Open your favorite podcast app and search for Python.
We should be right at the top.
You can also find the iTunes feed at /itunes, the Google Play feed at /play and the direct
RSS feed at /rss on talkpython.fm.
We're live streaming most of our recordings these days.
If you want to be part of the show and have your comments featured on the air, be sure to subscribe to our YouTube channel at talkpython.fm/youtube.
This is your host, Michael Kennedy.
Thanks so much for listening.
I really appreciate it.
Now get out there and write some Python code.
I'll see you next time.
Bye.
Thank you.