-
MOSH HAMEDANI: In
this course, you're
-
going to learn everything you
need to get started with Git.
-
If you're an absolute
beginner or if you
-
have been using Git for a while
but never really understood
-
how Git works, this
tutorial is for you.
-
You're going to learn all the
fundamental concepts as well
-
as the essential commands
that you need to know.
-
These are the commands that you
would use every day at work.
-
So by the end of
this tutorial, you
-
will have a good
grasp of the basics,
-
and you'll be
ready to learn more
-
about the intermediate
to advanced concepts.
-
I'm Mosh Hamedani, and I'm super
excited to be your instructor.
-
If you're new here, be sure
to subscribe as I upload
-
new tutorials every week.
-
Now let's jump in
and get started.
-
-
So what is Git?
-
And why is it so popular?
-
Git is the most popular version
control system in the world.
-
A version control system records
the changes made to our code
-
over time in a special
database called repository.
-
We can look at our
project history
-
and see who has made what
changes, when, and why.
-
And if you screw
something up, we
-
can easily revert our project
back to an earlier state.
-
Without a version
control system,
-
you will have to
constantly store
-
copies of the entire
project in various folders.
-
This is very slow and
doesn't scale at all,
-
especially if
multiple people have
-
to work on the same project.
-
You would have to
constantly toss around
-
the latest code via email
or some other mechanisms,
-
and then manually
merge the changes.
-
So in a nutshell, with a
version control system,
-
we can track our project
history and work together.
-
Now, version control systems
fall into two categories,
-
centralized and distributed.
-
In a centralized
system, all team members
-
connect to a central server to
get the latest copy of the code
-
and to share the
changes with others.
-
Subversion and Microsoft
Team Foundation Server
-
are examples of centralized
version control systems.
-
The problem with a
centralized architecture
-
is the single point of failure.
-
If the server goes offline,
we cannot collaborate or save
-
snapshots of our project, so we
have to wait until the server
-
comes back online.
-
In distributed systems, we
don't have these problems.
-
Every team member has a copy
of the project with its history
-
on their machine, so we can
save snapshots of our project
-
locally on our machine.
-
If the central
server is offline,
-
we can synchronize our
work directly with others.
-
Git and Mercurial are examples
of distributed version control
-
systems.
-
Out of all these, Git is the
most popular version control
-
system in the world because it's
free, open source, super fast,
-
and scalable.
-
Operations like
branching and merging
-
are slow and painful in
other version control
-
systems like Subversion or TFS,
but they are very fast in Git.
-
We'll talk about this later.
-
So Git is almost everywhere.
-
More than 90% of software
projects in the world use Git.
-
That's why almost every job
description for software
-
developer mentions Git.
-
So if you're looking for a
job as a software developer,
-
Git is one of the skills you
must have on your resume.
-
You should know it inside out.
-
You should know how
it works and how
-
to use it to track
your project history
-
and collaborate with
others effectively.
-
And that's exactly what you're
going to learn in this course.
-
[MUSIC PLAYING]
-
-
Let's talk about
various ways to use Git.
-
We can use Git on
the command line.
-
So we open a terminal
or command prompt window
-
to execute Git commands.
-
This is the fastest and
sometimes the easiest way
-
to get the job done.
-
That's why a lot of people
use the command line.
-
Now, if you don't
like the command line,
-
well, you're in luck, because
most modern code editors
-
and IDEs have built-in support
for basic Git features.
-
For example, in VS Code, we
have the source control panel,
-
which gives us the
essential Git features.
-
There are also extensions
available for bringing
-
additional Git features.
-
For VS Code, the most
popular extension is GitLens.
-
It brings a ton of Git
features in VS Code.
-
There are also graphical user
interfaces specifically made
-
for using Git.
-
Here on the Git
website, you can find
-
the complete list of these
tools for different platforms.
-
We have tools for Windows,
Mac, Linux, Android, and iOS.
-
Out of all these, the
two most popular tools
-
are GitKraken and Sourcetree.
-
GitKraken is my personal
favorite GUI tool for Git.
-
It's beautifully designed.
-
It works across
different platforms,
-
and it integrates with
other GitKraken products,
-
such as GitKraken Boards
for issue tracking
-
and GitKraken Timelines
for project management.
-
It's free for open
source projects,
-
but for commercial projects,
you have to pay an annual fee.
-
Just to let you know, I'm not
an affiliate of GitKraken.
-
I'm just a fan.
-
The other option is Sourcetree.
-
It's completely
free, but is only
-
available for Windows and Mac.
-
So if you're a
Linux user, you have
-
to use GitKraken or
another GUI tool.
-
In this course, we'll be
spending most of our time
-
on the command line for
a couple of reasons.
-
The first reason is that pretty
much all of these GUI tools
-
have some limitations.
-
They support the Git
commands that people
-
use most of the time.
-
So even if you want
to use a GUI tool,
-
there are times you would
have to roll up your sleeves
-
and get back to the command
line to get the job done.
-
The other reason is that
the command line is always
-
available, but there are
situations where a GUI tool may
-
not be available to you.
-
You might connect to
a server remotely,
-
and you may not have permission
to install a GUI tool.
-
If you don't know how to use the
command line, then you're stuck.
-
In practice, a lot of
people, including myself,
-
use both the command
line and a GUI tool.
-
And that's what I'm going
to show you in this course.
-
There are times that
it really makes sense
-
to use a GUI tool and
not a command line,
-
but there are other times
that using the command line
-
is faster and easier, so
we'll use the command line.
-
At the end of the
day, you should
-
use the right tool for the job.
-
Don't be like this guy.
-
You probably know him.
-
Our popular superstar
developer called John Smith.
-
He thinks he's
better than everyone
-
else because he does
everything in the command line.
-
He never uses a GUI tool, and
he looks down at people who do.
-
Well, let him think
whatever he wants
-
if that's what makes him happy.
-
Who cares.
-
So we'll be spending most of
our time on the command line.
-
But when it makes sense
to use a GUI tool,
-
I'll be showing you examples
in VS Code and GitKraken
-
because those are the
most popular tools.
-
Now, if you have never worked
with a command line before,
-
don't worry.
-
I'm going to hold your
hand and teach you
-
everything step by step.
-
It's a lot easier
than you think.
-
So next we're going
to install Git.
-
-
All right.
-
Let's see if you have
Git on your machine
-
or not, and if yes, what
version you have installed.
-
To do this, you have to open
a terminal or a Command Prompt
-
window.
-
If you're on Mac, press
Command and Space and then type
-
"terminal."
-
If you're on Windows, click
the Search icon on the bottom
-
navigation bar and type "cmd."
-
So here's my Terminal
or Console window.
-
Your Terminal window
might look different.
-
It doesn't matter.
-
This is where we're going
to execute Git commands.
-
So let's look at the version
of Git on this machine.
-
We type git --version.
-
So on this machine I'm
using Git version 2.19.2.
-
But the latest version at the
time of recording this video is
-
2.27.0.
-
So I highly encourage you
to download and install
-
the latest version.
-
Just head over to
git-scm.com/downloads.
-
Over here you can
find instructions
-
for installing Git on
different operating systems.
-
It's really easy.
-
You're not going to
have any problems.
-
Now if you're on Windows,
once you install Git,
-
you're going to get
this application called
-
Git BASH, which is short
for Bourne-Again SHell.
-
This is basically a
command prompt window,
-
like this one over here, but
it emulates Unix or Linux
-
environments.
-
So throughout this
course, I encourage
-
you to use Git BASH instead
of the built-in command
-
prompt window.
-
So what you see on
the screen looks
-
closer to what I'm going
to show you in this course.
-
So go ahead and install Git.
-
In the next lesson,
I'm going to show you
-
how to customize
our Git environment.
-
-
The first time we use
Git we have to specify
-
a few configuration settings.
-
We have to specify our name,
email, default editor, and how
-
Git should handle line endings.
-
We can specify this
configuration settings
-
at three different levels.
-
At the very top, we
have the system level.
-
The settings that we have
here apply to all users
-
of the current computer.
-
Below this level we
have the global level.
-
The settings here apply
to all repositories
-
of the current user.
-
And below this level we
have the local level.
-
The settings here apply
to the current repository
-
or the repository in
the current folder.
-
So we can have
different settings
-
for different repositories
or different projects.
-
So here in the terminal
window we type git config.
-
Then we type --global to
specify the level at which we
-
are defining these settings.
-
Next, we should specify the
setting we want to configure,
-
so user.name.
-
Here we type double
quotes and type our name.
-
Now the reason we're
adding double quotes
-
is because we have a
space in this value.
-
So that was the first setting.
-
Once again, git config --global.
-
This time we're going
to set user.email.
-
Now because we don't
have a space in emails,
-
here we don't need
double quotes.
-
So let's add our email.
-
All right.
-
Next, we need to specify
our default editor.
-
If we don't set this
on Mac, by default,
-
Git is going to use Vim
which is a scary editor.
-
A lot of people are
freaked out by it.
-
In this course, I'm going to use
Visual Studio Code or VS Code.
-
You can use any editor
that you prefer,
-
but if you want to
follow along with me,
-
I highly encourage
you to download
-
the latest version
of Visual Studio Code
-
from code.visualstudio.com.
-
Now on this machine, I've added
Visual Studio Code to my path.
-
So I can open it from
any folder on my machine
-
without specifying
the full path.
-
So if I type "code,"
here's VS Code.
-
If this doesn't work
on your machine,
-
you have to troubleshoot
the issue yourself.
-
Depending on your
operating system,
-
there are different instructions
for adding VS Code to your path.
-
So back to the terminal.
-
Let's set the default
editor, git config --global.
-
The setting we want to
configure is core.editor.
-
Once again, we
need double quotes
-
because here we're
going to have a space.
-
The value for this setting
is code space --wait.
-
With a wait flag, we
tell the terminal window
-
to wait until we close
the new VS Code instance.
-
So let's go ahead.
-
Now all these
configuration settings
-
are stored in a text file.
-
We can edit that file
using our default editor,
-
in this case, VS Code.
-
So we can type git
config --global -e.
-
This will open
our default editor
-
to edit all the global settings.
-
Let me show you.
-
All right, here's our
configuration file.
-
You can see the full path
to this file on the top.
-
The name of this
file is Git config.
-
Now in this file we
have different sections.
-
So we have the user section with
two settings, name and email.
-
We have the core section with
these two settings and so on.
-
Now back in the
terminal window, you
-
can see the terminal is waiting
for us to close VS Code.
-
So let's close this window.
-
Now we are back in
the terminal, and we
-
can execute the next command.
-
Next we're going
to configure how
-
Git should handle end of lines.
-
This is a very important setting
that a lot of people miss.
-
So on Windows, end
of lines are marked
-
with two special characters,
carriage return and line feed.
-
On Mac and Linux
systems, end of lines
-
are indicated with line feed.
-
So that means if we don't
handle end of lines properly,
-
we're going to run into some
weird issues down the road.
-
To prevent this, we have to
configure a property called
-
core.autocrlf, which is short
for carriage return line feed.
-
So let me walk you
through a real scenario.
-
Let's say we have two people
here, John and Julie, working
-
with the same repository.
-
John uses a Windows machine.
-
Julie uses a Mac.
-
As I told you, on
Windows, end of lines
-
are marked with carriage
return and line feed.
-
So when John wants to check in
his code into the repository,
-
Git should remove the
carriage return character
-
from end of lines.
-
Similarly, when he checks out
his code from the repository,
-
Git should update end of lines
and add the carriage return
-
character.
-
To achieve this behavior,
we should set this property
-
to true.
-
On the other hand, when
Julie checks out the code,
-
she doesn't want the
carriage return character.
-
So Git shouldn't
touch end of lines.
-
However, if carriage
return is accidentally
-
added to end of lines,
perhaps because of the editor
-
that Julie is using,
Git should remove it
-
when storing the code
in the repository.
-
To achieve this behavior,
we should set this property
-
to input, which means Git
should only modify end of lines
-
when storing code
in the repository.
-
So back in the
terminal, we type git
-
config --global core.autocrlf.
-
If you're on Windows, you
should set this to true.
-
If you're on Mac or Linux,
you should set this to input.
-
-
Let me show you a
few different ways
-
to get help about Git commands.
-
Let's say you want to learn
more about the config command.
-
You can simply
Google Git config.
-
On this page, you can see
the full documentation
-
of this command.
-
You can see various
options and how they work.
-
We can also access the same
page on the terminal window.
-
We simply type
Git config --help.
-
This is exactly the
same information
-
you saw a second ago.
-
Now here we can press Space
to go to the next page and Q
-
to exit.
-
Now if you don't need
a full-blown help,
-
just need a quick refresher,
you can type Git config -h.
-
This gives us a short summary
of this command and its options.
-
-
So we're done with the
introductory stuff.
-
Starting from the
next section, we're
-
going to cover a
lot of Git commands.
-
Now below this video,
you can download
-
a PDF of all the commands we're
going to cover in this course.
-
If you're starting out,
don't worry too much
-
about memorizing these commands.
-
Instead, try to
understand how they work.
-
As you practice
getting the real world,
-
all these commands are going
to become second nature to you,
-
trust me.
-
So download the cheat
sheet below this video.
-
And then I will see you
in the next section.
-
[MUSIC PLAYING]
-
The first thing
you need to use Git
-
effectively is how
to take snapshots
-
of your project, which
is what we're going
-
to talk about in this section.
-
We'll be talking about the
fundamental concepts in Git
-
that are often misunderstood.
-
So make sure to watch every
lesson in this section,
-
even if you think the basics.
-
A lot of people use
the basic Git commands
-
without having a proper
understanding of how Git works,
-
and that's why they
constantly get stuck.
-
So watch every lesson
in this section.
-
Now let's jump in
and get started.
-
-
All right.
-
The first thing
we're going to do
-
is create a directory
for our project.
-
You can call this
directory anything
-
and put it anywhere
on your machine.
-
It doesn't matter.
-
I'm currently in the
projects directory.
-
So let's create a
directory called Moon
-
and then go into this directory.
-
So let's imagine this is
our project directory.
-
And here we can have tens
or hundreds of files.
-
The first time we want to add
these files to a Git repository
-
we have to initialize
a new empty repository.
-
So we type Git init.
-
Look at this message--
-
initialized empty
Git repository in--
-
and here's the full path.
-
So we have the Moon directory.
-
And inside this directory, we
have a subdirectory called .git.
-
By default, this subdirectory
is hidden because you're not
-
supposed to touch it.
-
So if we type ls to list all
the files and directories here,
-
we don't see anything.
-
But if we type ls -a,
which is short for all,
-
we can see the Git subdirectory.
-
If you're on Mac, you can
open this with finder.
-
And if you're on
Windows, you can open it
-
with Windows Explorer
or File Explorer.
-
I'm not sure what it's
called these days.
-
So let's open .git.
-
Take a look.
-
So here's our Git directory
or Git repository.
-
This is where Git stores
information about our project
-
history.
-
So we have directories like
branches, hooks, info, objects,
-
and references.
-
Now, as someone using
Git, you don't really
-
need to understand
this structure.
-
This is purely an
implementation detail.
-
It's how Git stores information.
-
It's not our business.
-
That's why this directory is
hidden, so you don't touch it.
-
If you corrupt or
remove this directory,
-
you're going to lose
your project history.
-
Let me show you.
-
So back in the terminal,
look at this green marker.
-
It says Git.
-
That means we have a Git
repository in this directory.
-
Now if you want to have a
pretty colorful terminal
-
window like this, on Mac, you
need to install ZSH or Z shell.
-
And on Windows, you need
to install posh-git.
-
But don't worry about it now.
-
These tools are completely
optional to use Git.
-
It's just for making
things pretty.
-
So here we have
a Git repository.
-
Now if I remove the
Git subdirectory,
-
we're going to lose this
repository, so rm -rf .git.
-
Look, the green marker is gone.
-
We don't have a Git
repository here anymore.
-
So don't touch this directory.
-
Now once again, let's
initialize a Git repository.
-
Beautiful.
-
So now that we have
a repository, next
-
we're going to talk about
the basic Git workflow.
-
-
Now that we have
a Git repository,
-
let's talk about the
basic Git workflow.
-
What we do on a daily
basis when using Git.
-
So here's our project directory.
-
And here's our Git
repository, which
-
is actually a hidden
subdirectory in our project
-
directory.
-
Now every day, as part of
working on various tasks,
-
we modify one or more files.
-
When our project reaches
a state we want to record,
-
we commit those changes
into our repository.
-
Creating a commit is like taking
a snapshot of our project.
-
Now in Git, we
have a special area
-
or a special
intermediate step that
-
doesn't exist in most other
version control systems.
-
It's called the staging
area or the index.
-
It's essentially what we're
proposing for the next commit
-
or the next snapshot.
-
So when we're done
making changes,
-
we add the modified files to
the staging area or index,
-
review our changes.
-
And if everything is good,
then we'll make a commit.
-
The proposed snapshot will
get permanently stored
-
in our repository.
-
So the staging area allows
us to review our work
-
before recording a snapshot.
-
If some of the changes
shouldn't be recorded
-
as part of the next snapshot, we
can unstage them and commit them
-
as part of another snapshot.
-
That's the basic Git workflow.
-
Now let me walk you
through a real example.
-
This example is crucial,
so pay close attention
-
all the way to the end, even if
you think you know the basics.
-
Our project directory
is currently empty,
-
so we add a couple
of files here.
-
Now we're ready to
record this state.
-
So we use the add command to add
these files to the staging area.
-
Now these files are
in the staging area.
-
This is the state we're
proposing for the next commit.
-
We review these files.
-
Everything is good.
-
So we use the commit command to
permanently store this snapshot
-
in the repository.
-
As part of this, we supply
a meaningful message
-
to indicate what this
snapshot represents.
-
This is essential for
having a useful history.
-
So as we fix bugs, implement new
features, and refactor our code,
-
we make commits, and
each commit clearly
-
explains the state of the
project at that point in time.
-
So now we have one
commit in our repository.
-
Now, a common
misconception about Git
-
is that once we
commit the changes,
-
the staging area becomes empty.
-
This is not correct, and I think
this is why a lot of people
-
find Git confusing.
-
So what we currently
have in the staging area
-
is the same snapshot that
we stored in the repository.
-
So this staging area
is actually very
-
similar to a staging environment
we use when releasing software
-
to production.
-
It's either a reflection
of what we currently
-
have in production or
the next version that's
-
going to go in production.
-
So let's continue
with our example.
-
Let's say as part
of fixing a bug,
-
we make some changes to file1.
-
Note that what we currently
have in the staging area
-
is the old version
of file1, because we
-
haven't staged the changes yet.
-
So once again we use the add
command to stage the changes.
-
Now what we have in the staging
area is the same content
-
we have in our
working directory.
-
So let's make a commit
to record this date.
-
Now we have two commits
in our repository.
-
Also look at the commit message.
-
It's describing the
bug that we just fixed.
-
Now let's say we realize
that we no longer need file2.
-
It contains unused code.
-
So we delete it from
our working directory.
-
But this file is still
in the staging area.
-
So once again, we should
use the add command
-
to stage this change, in
this case, the deletion.
-
This is the interesting part.
-
Even though we're
saying add file2,
-
Git knows that file2
is actually deleted.
-
So it will delete this
file from the staging
-
area or the next snapshot.
-
Again, we make a commit to
permanently record this state.
-
Now we have three commits
in our repository.
-
Each commit contains
a unique identifier
-
that gets generated by Git.
-
It's like a revision number.
-
Each commit also contains
information about
-
what was changed, by
who, when, as well as
-
a complete snapshot
of our project
-
at the time it was created.
-
So unlike many other
version control systems,
-
Git doesn't store the
deltas or what was changed.
-
It stores the full content.
-
With this, it can quickly
restore the project
-
to an earlier snapshot without
having to compute the changes.
-
Now, you might
ask, but hey, Mosh,
-
wouldn't storing the full
content in every snapshot
-
waste a lot of space?
-
No, because Git is very
efficient in data storage,
-
it compresses file contents and
doesn't store duplicate content.
-
Now as someone using
Git, you don't really
-
need to know how
Git stores data.
-
That's implementation detail and
may even change in the future.
-
What you need to know is
that each commit contains
-
a complete snapshot
of our project,
-
and this allows us to quickly
get back to a previous state.
-
So that's the basic idea.
-
Over the next few
lessons, you're
-
going to see this
workflow in action.
-
-
Let's start by adding a couple
of files to our project.
-
To do that, we're going
to use the echo command.
-
This is not a Git
command, it's just
-
a standard Unix or Linux command
for writing content to a file.
-
So here we're going to
write hello to file1.txt.
-
So here I'm working
with a text file
-
because I don't want this course
to be specific to people who
-
know a particular programming
language, like Python
-
or JavaScript.
-
What I'm going to show you
in terms of the workflow
-
applies to any
programming languages.
-
So we write hello to file1.txt.
-
Good.
-
Now let's execute this command
one more time and change
-
file1 to file2.
-
So now we have two
files in our project.
-
Now look at this
question mark here.
-
That means we have
new files here
-
that are not tracked by Git.
-
Because the first time you
initialize a Git repository
-
in a directory, Git is not
going to automatically track
-
your files.
-
So if you have a thousand
files in your project,
-
you have to instruct
Git to track them.
-
So here we're going
to run Git status
-
to see the status of the working
directory and the staging area.
-
Take a look.
-
So we don't have
any commits yet.
-
We have untracked files
which are file1 and file2.
-
They're indicated by red because
they are not in the staging area
-
yet.
-
To add these files
to the staging area,
-
we use the Git add command.
-
Here we can list a single file
like file1.txt or multiple files
-
separated by a space.
-
We can also use
patterns, so star.txt.
-
That means all the files
with the txt extension.
-
We also have period, which
adds the entire directory
-
recursively.
-
Now you have to be a little
bit careful with this
-
because sometimes there
are files you don't
-
want to add to your repository.
-
Perhaps large files like large
binary files or log files,
-
you don't want to add these
files to your repository
-
because they increase the
size of your repository.
-
I will show you how to
ignore these files later
-
in this section.
-
So just remember, add period
adds the entire directory
-
recursively.
-
In this demo, I'm going
to go with this command
-
because we only have two
files in this directory.
-
Now our green indicator
changed to yellow,
-
which means we have
stuff in the staging area
-
that are ready to be committed.
-
So if we run Git status again,
look, we have two new files.
-
And they're indicated
by green, which means
-
they're in the staging area.
-
Now let me show you
something interesting.
-
I'm going to modify a file1.
-
So once again, we're going
to use the echo command
-
to echo world.
-
But here instead of
one greater than sign,
-
I'm going to use two greater
than signs, which means append.
-
So we're going to append
world to file1.txt.
-
Now let's run Git status again.
-
Look what happened.
-
We have two files
in the staging area
-
because they're
indicated by green.
-
But we also have one modified
file in our working directory.
-
So you might be
asking but hey, Mosh,
-
didn't we already add
file1 to the staging area?
-
Yes, we did.
-
But when we ran the add command,
Git took a snapshot of file1
-
and added that snapshot
to the staging area.
-
So here's the current situation.
-
In the staging area, we have
the first version of file1.
-
We change this file after we
added it to the staging area.
-
So what we currently have
in our working directory
-
is the second
version of this file.
-
It has some changes
that are not staged yet.
-
So back to the terminal, we
run Git add period or Git
-
add file1.txt one more time.
-
Now look at the status
of our working directory.
-
Both these files are
in the staging area,
-
and we don't have
any unstaged changes.
-
So next I'm going
to show you how
-
to commit this snapshot
to permanently store it
-
in our Git repository.
-
-
Now we have a snapshot
in the staging
-
area ready to be permanently
stored in our repository.
-
So we type Git commit
-m for message.
-
And here in double quotes
we type a short description
-
that identifies what
this snapshot represents.
-
So here I'm going to
say initial commit.
-
Now there are times that a short
one-liner description is not
-
sufficient.
-
You want to explain some
details to give context.
-
For example, if
you worked on a bug
-
and there were some
constraints at the time you
-
committed your
code, you may want
-
to explain those constraints.
-
This is very valuable to
both you and your coworkers.
-
So in situations like
this, we drop the message.
-
We just type Git commit.
-
Now, when we press Enter,
this opens our default editor,
-
in this case, VS Code because
at the beginning of the course,
-
I configured my default
editor to be VS Code.
-
So here we're trying to edit
this file COMMIT_EDITMSG, which
-
is stored in our
Git subdirectory.
-
So on the top, we can
type a short description.
-
Ideally this should be
less than 80 characters.
-
Then we add a line break.
-
And after that, we can
type a long description.
-
Now these lines that start
with a pound sign or comment,
-
they're going to get ignored.
-
So we type whatever
we want here.
-
In this case, I'm going
to say initial commit.
-
And this is our first commit.
-
Of course, this is repetitive.
-
We don't want to have
commit messages like this.
-
But for this demo, I'm going
to go with this message.
-
So we save the changes.
-
Then we close this window.
-
Back in the terminal our
snapshot is committed.
-
And here we have
basic statistics
-
about what was changed.
-
So two files were changed
which are file1 and file2,
-
and we have three insertions.
-
Three lines were inserted.
-
In file1, we insert a
two lines, hello world.
-
And in file2, we
inserted one line.
-
Now look at this indicator.
-
It turned green because our
working directory is now clean.
-
It doesn't have any new changes.
-
So what we have in
our working directory
-
is exactly the same
content we have
-
in our staging area, which is
exactly the same content we
-
have in the last commit.
-
-
Let's talk about the best
practices for committing code.
-
First of all, your
commits shouldn't
-
be too big or too small.
-
We don't want to make a commit
every time we update a file.
-
That's just useless,
because we'll
-
end up with commits
like update file1,
-
update file2, update file3.
-
It's just useless.
-
On the other hand, we don't
want our commits to be too big.
-
We don't want to wait and
implement a feature end
-
to end before committing it.
-
We don't want to code for three
days and then make a commit,
-
because the whole
point of committing
-
is to record
checkpoints as we go.
-
So if you screw
up, we can always
-
go back and recover our code.
-
So try to commit often.
-
In the real world, you might
commit five to 10 times
-
a day or even more, depending on
the kind of work you are doing.
-
But this is just
a basic guideline.
-
Don't take it as a rule.
-
Don't try to aim for
five or 10 commits a day.
-
So as you're
coding, as you reach
-
a state you want to
record, then make a commit.
-
Also, each commit
should represent
-
a logically separate chain set.
-
So don't mix things up.
-
For example, if
you're fixing a bug
-
and then you accidentally
find a typo in your app,
-
you shouldn't commit both
these changes in one commit.
-
You should have two
separate commits,
-
one commit for the typo,
another one for the bug fix.
-
Now, if you accidentally
stage both these changes,
-
you can easily unstage them.
-
I will show you how to do
this later in this section.
-
Next, you should give
yourself the habit
-
of creating meaningful
commit messages,
-
because all of these messages
are going to show up in history.
-
So if your messages
are cryptic, they're
-
not going to be helpful to
you or other team members.
-
Now, if you've followed
my previous advice,
-
if your commit represents
a single unit of work,
-
it would be easier to come up
with a message for your commit.
-
If you're doing too many
things in one commit,
-
you're not going to come
up with a good message.
-
Now in terms of the
wording, most people
-
prefer to use the present
tense in their commit messages.
-
So instead of "Fix the bug,"
you should say, "Fixed the bug."
-
If you don't like this
convention, that's totally fine.
-
But whatever convention
you use, make
-
sure that you and other
team members stick to it.
-
So always take this
best practices in mind
-
when committing code.
-
-
Hey, guys.
-
Mosh here.
-
I just want to let you know that
this video you've been watching
-
is actually the first hour of
my complete Git mastery course
-
and covers only the basic stuff.
-
So after you finish this video,
if you want to learn more,
-
take a look at my full course.
-
The complete course
is five hours long
-
and covers intermediate to
advanced level concepts.
-
It comes with a
certificate of completion,
-
downloadable summary notes, and
a 30-day money-back guarantee.
-
So if you're not happy,
you can ask for a refund.
-
You will learn all about
browsing history, branching
-
and merging, collaborating with
others using Git and GitHub,
-
and rewriting history.
-
So by the end of
this course, you
-
will be able to
use Git like a pro
-
and work effectively
with others in your team.
-
If you're interested,
click on the link
-
below this video to enroll.
-
-
One of the common questions
a lot of beginners have is,
-
do we always have to stage our
changes before committing them?
-
Well, the answer is no.
-
And in this video,
I'm going to show you
-
how to skip the staging area.
-
But do this only if you
know what you're doing,
-
if you're 100% sure that
your code, your changes
-
don't need to be reviewed,
because that's the whole point
-
of having a staging area.
-
So let's modify file1 and
then commit it in one step.
-
We're going to say
echo test to file1.txt.
-
Once again, we're appending
this line to file1.txt.
-
All right.
-
Now we have a yellow indicator
because our working directory
-
is dirty.
-
So instead of running
Git add and then
-
committing it in two steps,
we're going to commit.
-
Here we're going to supply the
option -a, which means all.
-
That means all modified files.
-
And then, just like before,
we supply a message,
-
or we can combine
these two options.
-
So let's supply a message.
-
Fix the bug that prevented
the users from signing up.
-
Let's go.
-
Our code is committed.
-
One file was changed, and
we have one insertion.
-
So this is how we can
skip the staging area.
-
But once again, do this only
if you know what you're doing.
-
99% of the time
you should always
-
stage your code before
committing it to the repository.
-
-
Let's say that we
just discovered
-
that we no longer need
file2 in our project,
-
because it contains unused code.
-
So to remove this file,
we type rm file2.txt.
-
Again, this is not a
Git command because it
-
doesn't start with Git.
-
It's just a standard
Unix command.
-
So let's go with this.
-
Now we have a yellow
indicator, which means
-
our working directory is dirty.
-
So let's run Git status.
-
We have one change that
is not staged for commit.
-
So we remove file2 from
our working directory
-
but still exists in
the staging area.
-
Let me prove it to you.
-
So we type Git ls-files.
-
These are the files
in our staging area.
-
So file2 is still here
even though we removed it
-
from our working directory.
-
So as I told you before,
every time we make changes,
-
we have to stage those
changes using the add command.
-
So here we type Git
add file2.txt to stage
-
this change or this
deletion more accurately.
-
Now let's run Git
ls-files one more time.
-
So file2 is no longer
in the staging area.
-
Beautiful.
-
Let's run Git status.
-
We have one change that
is ready to be committed.
-
And as you can see, it's
indicated by green, which
-
means it's in the staging area.
-
So let's commit this change.
-
And here we're going to
say remove unused code.
-
So to remove a file,
we have to remove
-
it from both our
working directory
-
as well as the staging area.
-
Because this is a
very common operation,
-
Git gives us a command that does
both of these steps in one-go.
-
Let me show you.
-
So we type Git rm.
-
So instead of using the
standard rm command in Unix,
-
we use Git rm.
-
Here we list the file
name, like file2.txt.
-
We can also specify
multiple files.
-
We can also use patterns,
like, all text files.
-
When we execute
this command, Git
-
removes this file from
both the working directory
-
as well as the staging area.
-
-
Now let's talk about
renaming or moving files.
-
So currently, we have a single
file in our working directory,
-
and that is file1.txt.
-
Let's rename this to main.js.
-
So we use the move
command in Unix
-
to rename file1.txt to main.js.
-
So with this command,
we can rename or move
-
files and directories.
-
Now our working
directory is dirty.
-
So let's run Git status.
-
We have two changes,
and both these changes
-
are unstaged because
they're indicated by red.
-
We have a delete operation.
-
We deleted file1.txt.
-
And under untracked
files, we have a new file.
-
So as you saw at the
beginning of this section,
-
Git doesn't automatically
track all your new files.
-
Every time you have a
new file in your project,
-
you have to add it
to the staging area,
-
so Git starts tracking it.
-
So once again, we have
to use the add command
-
to stage both these changes.
-
Git add file1.txt This is
for staging the deletion.
-
And now let's add the new
untracked file main.js.
-
Now let's run Git
status one more time.
-
Look, Git recognized that we've
renamed file1.txt to main.js.
-
And this item is indicated
by green, which means
-
this is in the staging area.
-
So renaming or moving files
is a two-step operation.
-
First, we have to modify
our working directory,
-
and then we have to stage
two types of changes,
-
an addition and a deletion.
-
So similar to
removing files, Git
-
gives us a special command
for renaming or moving files.
-
That is Git move.
-
So instead of using the
standard move command in Unix,
-
we're going to use Git move.
-
Now let's rename
main.js to file1.js.
-
And then run Git
status one more time.
-
So we have a rename operation
for renaming file1.txt
-
to file1.js.
-
So when we use the move
command, the changes
-
are applied to both the working
directory and the staging area.
-
Now let's commit the changes.
-
For the message, I'm going
to say refactor code.
-
Now look at the statistics.
-
One file was changed.
-
We have zero insertions because
we haven't added any new lines
-
to any of our files.
-
And we also have zero deletions
because we haven't removed
-
any lines from any files.
-
-
In almost every
project, we should
-
tell Git to ignore certain
files and directories.
-
For example, we don't want to
include log files or binary
-
files that get generated as a
result of compiling our code.
-
Adding these files is
just going to increase
-
the size of our repository
without providing any values.
-
Every developer can have
their own log files.
-
So log files are not something
we want to share and synchronize
-
with other team members.
-
So for this demo, let's create
a directory called logs and then
-
add a log file here.
-
Once again, we can use the
echo command to write hello
-
to logs/dev.log.
-
Now let's run Git status.
-
So Git is saying that we have an
untracked directory called logs.
-
But we don't want to add
this to the staging area
-
because we don't want
Git to track this.
-
So to prevent this, we have to
create a special file called
-
.gitignore.
-
So this file has no name.
-
It only has an
extension, and it should
-
be in the root of your project.
-
So let's echo logs/ .gitignore.
-
Now I'm going to open this
file using VS Code, so
-
code gitignore.
-
So in this file we have a single
entry logs/ which indicates
-
a directory.
-
We can list as many files
and directories we want here.
-
For example, we can
include main.log.
-
We can also use patterns,
like, all log files and so on.
-
Once we are done, we save the
changes, back in the terminal.
-
Now if you run Git
status one more time,
-
Git no longer says that we
have a new directory called
-
logs because it's ignoring it.
-
Instead it says we have a
new file called .gitignore.
-
So let's add this file
to the staging area
-
and then commit our code.
-
So add gitignore.
-
So this is how we can ignore
files and directories in Git.
-
Just remember, this only
works if you haven't already
-
included a file or a
directory in your repository.
-
In other words, if you
accidentally include
-
a file in your repository and
then later add it to gitignore,
-
Git is not going to ignore that.
-
Let me show you.
-
So let's create a new
directory called bin.
-
Let's imagine that
this directory contains
-
our compiled source code.
-
So using the echo command,
I'm going to write hello
-
to bin/app.bin.
-
-
Now let's run Git status.
-
So we have a new directory.
-
Now we want to accidentally
commit this to our repository.
-
So we add all the changes
and then commit our code.
-
Add bin.
-
Here's the problem.
-
Every time we compile our code,
Git is going to say that this
-
file bin/app.bin is changed.
-
So we have to stage
it and then commit it.
-
It doesn't make sense.
-
Why do we have to commit
this file every time we
-
compile our application?
-
So back to gitignore.
-
Let's add the bin
directory here as well.
-
Now back in the terminal,
let's run Git status.
-
So we have modified gitignore.
-
Beautiful.
-
Let's stage and commit this
change, so Git add period,
-
and then Git commit include
bin/ and Git ignore.
-
Now in this case,
Git is not going
-
to ignore the changes
in this directory
-
because it's already
tracking this directory.
-
So let's modify our bin file
by saying echo helloworld
-
to bin/app.bin.
-
Git status.
-
Look, Git is saying that
this file is modified.
-
This is not what we want.
-
To solve this problem, we
have to remove this file
-
from the staging area,
which is what we're
-
proposing for the next commit.
-
So earlier we talked
about Git ls-files.
-
This command shows the
files in our staging area.
-
So as you can see, this bin
file or the bin directory
-
is already in the staging area.
-
We should remove it here.
-
How?
-
Well, earlier we talked
about the Git remove command.
-
I told you that
with this command,
-
we can remove a
file or a directory
-
from both the working directory
as well as the staging area.
-
But in this case, we don't
want to remove this file
-
from our working
directory because that's
-
how we launch our application.
-
So we want to remove this file
only from the staging area.
-
How?
-
Well, let's add -h
for a quick help.
-
So we type Git rm.
-
Then we can add zero
or more options.
-
Now here we have this
option called --cached.
-
With this, we can remove
stuff only from the index.
-
Index is the old term
for the staging area.
-
So when you look at Git
documentation, most of the time
-
you see index.
-
So using this option we can
remove the bin directory from
-
the index, so Git
rm --cached bin/.
-
Now we get an error
saying not removing
-
bin recursively without -r.
-
So one more time, let's look
at the help for this command.
-
We have another option called
-r for recursive removal.
-
So we want to remove the entire
bin directory from the staging
-
area.
-
To do that, we type Git
rm --cached -r bin/.
-
Beautiful.
-
Now this entire directory is
removed from the staging area.
-
Let's verify it.
-
So Git ls-files.
-
Our bin directory
is no longer here.
-
Now let's run Git status.
-
Look, we have one change that
is ready to be committed.
-
This directory is deleted
from our staging area.
-
So let's commit the change.
-
Remove the bin directory that
was accidentally committed.
-
From this point forward,
Git is no longer
-
going to track the
changes in this directory.
-
So if we echo test
to bin/app.bin,
-
you can see our working
directory is still clean.
-
We don't have any changes.
-
We can verify it using
Git status as well.
-
So this is how we can ignore
files and directories in Git.
-
Now if you head over to
github.com/github/gitignore,
-
you can see various Git
ignore templates for different
-
programming languages.
-
For example, let's look
at the template for Java.
-
So for Java projects,
it's a great idea
-
to exclude all the class
files because these files get
-
automatically generated
when you compile your code.
-
So there is no need to include
them in your repository.
-
So here we have various
patterns like all the class
-
files or all the log files.
-
The lines that start with a
hash sign, these are comments,
-
so they get ignored by Git.
-
-
So you have learned how to
get the status of the working
-
directory and the staging
area using the status command.
-
The output of this command
is very comprehensive,
-
but it's also very wordy.
-
So as an alternative, we
can supply the short status
-
flag or -s.
-
Let me walk you
through a few examples.
-
So for this demo, we're going to
modify one of our existing files
-
and then add a new file.
-
So echo sky to file1.js.
-
So we're appending
a sky to file1.js.
-
Now let's create a new file.
-
So once again, echo
sky to file2.js.
-
Now let's run Git status.
-
We have modified file1, and
we have a new untracked file.
-
So as you can see, the
output of this command
-
is very comprehensive
but also very wordy.
-
Now let's run Git status -s.
-
This is much easier to dice.
-
So let me show you
how this works.
-
Here we have two columns.
-
The left column represents
the staging area,
-
and the right column represents
the working directory.
-
So we have modified file1.
-
And that's why we have a red
M in the right column, which
-
is the working directory.
-
So we have some changes
here, but these changes
-
are not in the staging area.
-
That's why we don't have
anything in the left column.
-
Now, file2 is a new file.
-
That's why we have two question
marks in both these columns.
-
Now, let's add file1 to the
staging area, so Git add file1.
-
And then do another
short status.
-
Look.
-
For file1, we have a green M in
the left column or the staging
-
area column.
-
So all the changes that
we had in the working area
-
are now in the staging area.
-
In the right column,
we don't have anything.
-
We don't have any extra changes.
-
Now, earlier in this
section, I told you
-
that when new
staging a file, Git
-
takes a snapshot of that file
and puts it in the staging area.
-
So if you modify
that file after,
-
we have to restage the changes.
-
Let me show you
this one more time.
-
So I'm going to modify
file1 more time.
-
Let's echo ocean to file1.js
and then run Git status -s.
-
Look what we have here.
-
So in the left column,
we have a green M,
-
which means we have some
changes in the staging area,
-
but we have some
additional changes
-
in the working
directory that are not
-
added to the staging area.
-
So let's add file1 to
the staging area one more
-
time and then run Git status -s.
-
Now all the changes that we
had in the working directory
-
are now in the staging area.
-
So we're done with file1.
-
Let's look at file2.
-
So I'm going to add file2
to the staging area as well.
-
And then run Git status -s.
-
For file2, we have a green
A in the left column,
-
which represents added.
-
So file2 is added,
and file1 is modified.
-
This is how the short
status output works.
-
-
So we have staged a
couple of changes.
-
Now before committing what
we have in the staging area,
-
we need to review
our code because we
-
don't want to commit bad code or
broken code to our repository.
-
So as a best practice,
always review
-
what you have in the staging
area before making a commit.
-
Now the status
command only shows
-
the files that have been
affected, but how can
-
we see the exact lines of
code that we have staged?
-
We use the diff command.
-
So we type Git diff
--staged to see
-
what we have in the
staging area that
-
is going in the next commit.
-
So let's take a look here.
-
Now quite frankly comparing
files using the terminal window
-
is not really the
best way to do this.
-
Quite often we use
visual tools, and I'm
-
going to talk about
that in the next video.
-
But I think it's
essential for you
-
to understand the
output of this command,
-
because there are
times that you may not
-
have access to a visual tool.
-
Or at least you may go to an
interview and you may get asked,
-
what is the output
of this command?
-
So you need to be
able to explain it.
-
So on the top, you can see
that the diff utility was
-
called with these arguments.
-
So we are comparing
a/file1.js with b/file1.js.
-
So we're comparing two
copies of the same file.
-
The first copy is
the old copy, which
-
is what we have in
the last commit.
-
And the second copy,
which is the newer copy,
-
is what we currently
have in the staging area.
-
Now below that we
have index whatever.
-
This is just some metadata.
-
It doesn't really matter.
-
After that we have a legend.
-
So changes in the old copy
are indicated by a minus sign,
-
and changes in the new copy
are indicated by a plus sign.
-
After that we have this section.
-
This is a header with some
information about what
-
parts of our file is changed.
-
So currently our
files are very short.
-
They have only a
few lines of text.
-
But in the real
world, your file might
-
have hundreds of lines of code.
-
If you change only
a couple of lines,
-
Git is not going to
show the entire file.
-
It's going to divide
that file into chunks.
-
And what we have here
is just a single chunk.
-
So every chunk has a header
with some information
-
that gives you context.
-
So let's see what we have here.
-
We have two segments.
-
The first segment is
prefixed with an minus sign.
-
So this gives us information
about the old copy, what
-
we have in the last snapshot.
-
The second segment is
prefixed with a plus sign.
-
So this contains information
about the new copy
-
which is what we have
in the staging area.
-
So in the old copy,
starting from line 1,
-
three lines have been
extracted and shown here.
-
In the new copy, once again
starting from the first line,
-
five lines have been
extracted and shown here.
-
So these are all
these lines over here.
-
Now you can see
that these two lines
-
are prefixed with a plus sign.
-
So these are the lines that
we have added in the new copy.
-
So we have added these
lines in the staging area.
-
They are green, which
means they're new lines.
-
So pretty straightforward.
-
Now after that, we have another
call to the diff utility.
-
This time we're comparing
two copies of file2.
-
Now in this case,
look at the legend.
-
We don't have an old
copy because this
-
is an entirely new file.
-
So in the last commit, we
didn't have a file called file2.
-
That is why in this
header we have 0, 0,
-
which means starting
from line 0,
-
zero lines have been
extracted because there
-
is no old copy of this file.
-
Now what if you want to see the
changes in our working directory
-
that are not staged yet?
-
To do that, we run Git
diff without any arguments.
-
So this compares what we have in
the working directory with what
-
we have in the staging area.
-
Take a look.
-
There is no output here because
we have staged all the changes
-
in our working directory.
-
We can also verify this using
our short status command.
-
So all the changes in
our working directory
-
are now in the staging area.
-
So for this demo, I'm going
to make a change to file1.
-
So let's open it with VS
Code or our favorite editor.
-
So I'm going to change the
first line to hello world.
-
Save.
-
Now, let's run
another short status.
-
So for file1, we have some
changes in our working directory
-
that are not in
the staging area.
-
Let's look at these changes
using the diff command.
-
So Git diff without
any arguments.
-
Take a look.
-
So here we're comparing
two copies of file1.
-
The old copy is
what we currently
-
have in the staging area.
-
And the new copy is what we
have in the working directory.
-
Now take a look.
-
In the old copy, which is
indicated by a minus sign,
-
we have this line, hello, which
is removed because it's red.
-
And in the new
copy, which is what
-
we have in the
working directory,
-
we have this new
line, hello world.
-
So to recap, if we run Git
diff without any argument,
-
we can see unstaged changes.
-
And if we pass
--staged, we can see
-
the state changes that are
going to go in the next commit.
-
In the next lesson,
I'm going to show you
-
how to use a visual tool
to easily compare files.
-
-
As I told you in the
last lesson, quite often
-
we use visual diff tools
for comparing files.
-
There are so many visual
diff tools out there.
-
The most popular ones
are KDiff and P4Merge,
-
which are cross-platform
and WinMerge that
-
runs only on Windows.
-
In this lesson, I'm
going to show you
-
how to use VS Code
for comparing files.
-
If you want to use a different
tool or a different editor,
-
you have to look up the
instructions yourself.
-
So here in the
terminal, first we
-
have to tell Git that we want to
use VS Code as our default diff
-
tool.
-
So we have to set two
configuration settings.
-
So once again we type
Git config --global.
-
So the global settings apply
to all of our repositories.
-
Now the setting we're
going to set is diff.tool.
-
We're going to set
that to VS Code.
-
So with this command, we're just
giving a name, in this case VS
-
Code, to our default diff tool.
-
Next, we need to tell Git
how to launch VS Code.
-
So once again, Git
config --global.
-
Here we set difftool.vscode.cmd.
-
-
We set this to double
quotes, because we're
-
going to have a space.
-
Now on my machine, I've
added code to my path
-
so I can run it
from any directory.
-
If this doesn't work
on your machine,
-
you have to look up the
instructions yourself depending
-
on your operating system.
-
So we're going to launch
code with a few arguments.
-
The first one is --wait.
-
This tells the
terminal window to wait
-
until we're done with
VS Code, so until we
-
have compared the changes and
closed the VS Code instance.
-
The second argument is --diff.
-
This tells VS Code
that we want to use it
-
for diffing or comparing files.
-
Then we have two more
arguments, $LOCAL in capital
-
and $REMOTE in capital.
-
These are placeholders for the
old and new copies of a file.
-
So let's set that.
-
Now let's make sure that you
have got this step right.
-
So we're going to run
Git config --global -e.
-
As I told you at the
beginning of the course,
-
with this command, we can
edit our global configuration
-
settings in our default
editor, which is VS Code.
-
So take a look.
-
So all the settings are stored
in this file .gitconfig,
-
which is stored
in this directory.
-
So we have the
user section, which
-
we set earlier in the course.
-
Now, here's a diff
section that we just set.
-
In this section, we have
set the tool to VS Code.
-
This is just a name.
-
Then we have difftool vscode.
-
And here's the
command that should
-
be run for comparing
files with VS Code.
-
So we have code with
--wait, then --diff.
-
Now those two placeholders
that I added, for some reason,
-
they're lost.
-
So let's add them real
quick, $LOCAL and $REMOTE.
-
Make sure to get this
right, otherwise things
-
are not going to
work on your machine.
-
Now we're done.
-
So let's close this window.
-
Back in the terminal, instead
of using the diff command,
-
we're going to use difftool.
-
This will launch our visual
diff tool for comparing files.
-
Now if you don't
supply any arguments,
-
we're going to see
our on stage changes.
-
So this will
compare what we have
-
in the working
directory with what
-
we have in the staging area.
-
If you want to look
at our stage changes,
-
we supply --staged,
exactly the same way
-
we use the diff command.
-
So let's look at the changes we
have in our working directory.
-
We have modified
only a single file.
-
That is why we have one out
of one, and that is file1.js.
-
So Git is asking, if
you want to launch
-
VS Code, which is the name that
we assign to our default diff
-
tool, let's go ahead.
-
Take a look.
-
So here's the old
copy, which is what
-
we have in the staging area.
-
And here's a new
copy, which is what we
-
have in the working directory.
-
As you can see, we can easily
tell that this line has
-
been replaced with this line.
-
It's much easier
to see the changes.
-
Now the terminal window
is waiting for us
-
to close the VS Code instance.
-
So let's close this window.
-
Back to the terminal.
-
Now let's look at
the staged changes.
-
So Git difftool --staged.
-
Two files have been affected
in the staging area.
-
The first one is file1.js.
-
Let's look at the changes.
-
All right.
-
In this case, the old copy is
what we have in the last commit.
-
And the new copy is what we
have in the staging area.
-
So these are the
changes that are
-
going to go in the next commit.
-
We can easily tell that we
have added two lines here.
-
Now, let's close this tab.
-
Back in the terminal.
-
Git is asking if you want to
look at the changes in file2.js.
-
In this case, I'm
going to ignore that.
-
So no.
-
Now quite honestly, we don't use
diff tools so much these days.
-
I just covered it because I want
my course to be comprehensive.
-
These days, most
editors and IDEs
-
allow us to view the staged
and unstaged changes as part
-
of our development environment.
-
I will show you how to do
this later in this section.
-
-
We have made a few
commits so far, but where
-
are these commits?
-
Let me show you.
-
So we use the log command
to look at our history.
-
Take a look.
-
So here are all the
commits we have created,
-
sorted from the latest
to the earliest.
-
So here's our last
commit on top.
-
Each commit has a
unique identifier.
-
This is a 40-character
hexadecimal string that Git
-
automatically generates for us.
-
You can think of it
like a revision number.
-
But unlike a revision
number, it doesn't increase.
-
It's just a unique identifier.
-
Now next to that we have
HEAD pointing to master.
-
What is this?
-
Well, we're going to talk
about this a lot in the future.
-
But master is the main branch
or the main line of work in Git.
-
In some other version control
systems, it's called trunk.
-
In Git, we can have
multiple branches,
-
so we can work on multiple
features or multiple bug fixes
-
in parallel and then
combine our code.
-
We'll talk about that
later in the course.
-
Now, HEAD is a reference
to the current branch.
-
So this is how Git knows
what branch we're currently
-
working on.
-
Again, we're going to talk
about this a lot in the future.
-
Now, for each
commit, you can see
-
the author, the
name of the author
-
as well as their email, the date
and time the commit was created,
-
as well as the
oneline description.
-
Now here we have
multiple commits
-
that are spread
across multiple pages.
-
We can press Space to
go to the next page.
-
And again, now to
quit, we can press Q.
-
Now, the log command has
a few interesting options.
-
One of them is one line.
-
This shows us a short
summary of the commit.
-
So here we have the
unique identifier
-
that is shortened
to seven characters.
-
And we only have the
oneline description.
-
So we don't have the author
as well as the date and time
-
of each commit.
-
We have another option for
reversing the sort order.
-
Let me show you.
-
So Git log oneline, and
then we add --reverse.
-
Now you can see the first
commit being on top,
-
and here's the last commit.
-
Now the log command
is very powerful.
-
So in the future, we're
going to talk a lot about it.
-
In fact, we have a complete
section on browsing history.
-
I'm going to show you
various ways to get reports
-
from the history.
-
For now, let's just
stick to the basics.
-
-
So viewing the list
of commits is great.
-
But what if you want
to see what exactly we
-
have changed in a given commit?
-
That's when we use
the show command.
-
For example, let's
say we want to look
-
at the content of
this commit over here.
-
We type git show.
-
Now here we need to specify
the commit we want to inspect.
-
There are two ways to
reference a commit.
-
We can reference it using
its unique identifier.
-
So we type d601b90.
-
Now we don't have to type
all the seven characters.
-
We can type fewer
characters as long
-
as we don't have
another commit whose ID
-
starts with these characters.
-
So that's one way to
reference a commit.
-
Another way is to
use the HEAD pointer.
-
So look, HEAD is currently
in front of the last commit.
-
So to view the last
commit, we can type HEAD.
-
Or to look at previous
commits, we can type a tilde
-
and then specify how many
steps we want to go back.
-
So if we type 1, we
start from HEAD, which
-
is here we go one step back.
-
And this references
this commit over here.
-
Let's take a look.
-
So on the top, we
can see the author
-
and the date of this commit
as well as its message.
-
Below that we have a
diff of what is changed.
-
So in this commit, we
have changed a single file
-
that is gitignore.
-
Over here we can see
that we removed this line
-
and added these two lines.
-
So this is very useful.
-
Now what if we don't want
to see the differences?
-
We want to see the final
version, the exact version that
-
is stored in this commit.
-
Well, we bring up the last
command, Git show HEAD tilde 1.
-
Then we type a colon.
-
And here we specify the
full path to a file.
-
For example, we
can say .gitignore.
-
Or if this file is in a
subdirectory, we type,
-
for example, bin/app.bin.
-
Now let's look at gitignore.
-
So this is the exact version
stored in this commit.
-
Now, earlier, I told
you that each commit
-
contains a complete snapshot
of a working directory,
-
not just changes.
-
But when we run
the show command,
-
we only see the differences,
what has changed.
-
What if you want to
see all the files
-
and directories in a commit?
-
Well, for that we're going to
use a different command that's
-
called ls-tree.
-
Now, why is this called a tree?
-
Well, a tree is a data
structure for representing
-
hierarchical information.
-
So in a tree, we can have
nodes, and these nodes
-
can have children.
-
Now a directory
on the file system
-
can be represented using a tree.
-
Because each directory
can have children,
-
these children can be files
and other subdirectories.
-
If you want to learn
more about this concept,
-
you should take my
data structures course.
-
So ls-tree means list
all the files in a tree.
-
Now here we specify the
commit we're interested in,
-
HEAD tilde 1.
-
And now look, these are all
the files and directories
-
stored in this commit.
-
So we have gitignore.
-
Right before that, we
have a unique identifier
-
that is generated based on
the content of this file.
-
So in Git's database, we
have an object with this ID.
-
Below that we have bin.
-
Again, it has a
unique identifier
-
that is generated based on
the content of this directory.
-
Now look at the
type of this object.
-
It's a tree.
-
So files are
represented using blobs,
-
and directories are
represented using trees.
-
All of these are objects that
are stored in Git's database.
-
Using the show
command, we can easily
-
view an object in
Git's database.
-
For example, if we
type Git show and then
-
specify this unique
identifier, or we
-
can type only the
few characters,
-
as long as there
is no ambiguity.
-
So here's the content
of our gitignore file.
-
As another example, let's
look at this object,
-
this tree, the bin directory.
-
So Git show 64629.
-
Here we have a tree.
-
In this tree, we have
this file, app.bin.
-
So using the show
command, we can view
-
an object in Git's database.
-
These objects can be commits,
blobs, which represent files,
-
and trees, which represent
directories, as well as tags.
-
We'll talk about
tags in the future.
-
-
So I told you that you
should always review
-
the stuff that you have
in the staging area
-
before making a commit.
-
So let's say we
review these changes,
-
and we realize that
the changes in file1
-
shouldn't go in the
next commit, perhaps
-
because these
changes are logically
-
part of a different task.
-
So we don't want to have
a commit that represents
-
changes for different tasks.
-
So in this case, we want
to undo the add operation,
-
because earlier we used the
add command to add file1
-
to the staging area.
-
Now we want to undo
this operation.
-
How do we do this?
-
Well, in the past, we
used the reset command.
-
But a lot of people found
this command confusing,
-
especially with options
such as hard or soft.
-
That's why we have a new
command called restore.
-
Now make sure you're using
the latest version of Git.
-
Otherwise, what
I'm going to show
-
you is not going to
work on your machine.
-
So here I'm using
Git version 2.28.
-
And with this, we
can easily restore
-
files in different environments
in working directory
-
or in staging area.
-
So Git restore.
-
We want to restore file1
in the staging area.
-
So we type --staged.
-
And then we specify
the file name.
-
We can list multiple files here.
-
We can also use patterns.
-
Or if you want to restore
everything in the staging area,
-
we simply use a period.
-
So here I'm going
to restore file1.js.
-
Now when we run
Git status again,
-
we are not going to
see a green M here
-
because all the changes that
we had in the staging area
-
are now in the
working directory.
-
Take a look.
-
So Git status -s.
-
Look.
-
We no longer have any changes
for file1 in the staging area.
-
All the changes are in
the working directory.
-
Now it's essential
for you to understand
-
how the restore command works.
-
The restore command
essentially takes the copy
-
from the next environment.
-
So in case of the
staging environment,
-
what is the next environment?
-
The last commit, what we
have in the repository.
-
So when we restore file1
in the staging area,
-
Git took the last copy of this
file from the last snapshot
-
and put it in the staging area.
-
That is what happened.
-
Now look at file2.
-
File2 is a new file
because here we
-
have a green A which
is short for added.
-
So we have this file.
-
We have this new file
in the staging area.
-
But this file doesn't
exist in the last commit.
-
So what do you think will
happen when I restore this file?
-
Well, because we don't
have a copy of this file
-
in our repository or
in our last commit,
-
Git is going to remove this
file from the staging area
-
and take it back to its
previous state, which
-
is a new untracked file.
-
Let me show you.
-
So Git restore
--staged file2.js.
-
Now let's run Git status again.
-
So file2 is a new untracked file
because we have two question
-
marks.
-
-
There are times that we have
some code in our working
-
directory that we
want to throw away.
-
Let's say we made
some changes, but we
-
didn't like those changes.
-
So we want to scratch
everything and start over.
-
We can discard the local changes
using the restore command.
-
So here we have some
local changes in file1.js.
-
To undo these changes, we
type Git restore file1.js.
-
When we execute
this command, Git
-
is going to take the
version of this file
-
in the next environment, which
is our staging environment,
-
is going to take that
version and copy it
-
to our working directory.
-
We can also use a period
here, and this will
-
undo all the local changes.
-
Now let me show you something.
-
So the command is executed.
-
Now let's run
another short status.
-
But file2 is still here.
-
Why is that?
-
Well, this is a
new untracked file,
-
so Git hasn't been
tracking this.
-
So when we tell Git
to restore this file,
-
Git doesn't know where to get a
previous version of this file.
-
It doesn't exist in
our staging environment
-
or in our repository.
-
So to remove all these
new untracked files,
-
we have to type Git clean.
-
Now take a look.
-
By default, we get
this fatal error saying
-
require force defaults to true.
-
And neither of these
switches were given.
-
So basically Git is
telling us that, hey, this
-
is a dangerous operation.
-
If you accidentally remove
these untracked files,
-
there is no way you
can recover them.
-
So let's run Git clean
-h for a quick help.
-
Here we have this option
-f, which forces Git
-
to remove this untracked files.
-
We also have -d for
removing whole directories.
-
So quite often we
type Git clean -fd.
-
Now, let's run
short status again.
-
File2 is gone.
-
So this is how we
undo local changes.
-
-
So now you know that
once Git tracks a file,
-
it stores every version of
that file in its database.
-
And that means if
you screw things,
-
we can always restore
a file or a directory
-
to a previous version.
-
So in this demo, I'm
going to delete a file
-
and then show you
how to restore it.
-
It's very easy.
-
So we're going to
delete file1.js.
-
Now I told you that if we
use the rm command in Linux
-
or Unix-based systems, this
will only remove the file
-
from the working directory.
-
So then we'll have to stage
the change or the deletion.
-
A better way is to use
the Git rm command.
-
This will remove the file from
both the working directory
-
as well as the staging area.
-
Now let's get a short status.
-
So in the staging area,
we have a deleted file.
-
Now, let's make a
commit delete file1.js.
-
All right.
-
Now let's say, shoot.
-
We shouldn't have
deleted this file.
-
So what can we do here?
-
Well, we have a few options.
-
We can undo or revert
the last commit.
-
We're going to talk about
that later in the course.
-
But in this lesson,
I want to talk
-
about restoring a file
to a previous version,
-
not undoing a commit.
-
So let's look at our history.
-
All right.
-
So here's our history.
-
We want to restore file1 to the
commit before the last commit.
-
That is this commit over here.
-
So we type Git restore.
-
Now let's have a quick
look at the documentation.
-
The restore command takes
three types of arguments.
-
We can supply a
bunch of options.
-
We can supply a source.
-
We haven't done this so far.
-
So by default, Git
will restore that file
-
from the next environment
or the next area.
-
So if the file we
want to restore
-
is in the working directory,
Git will restore it
-
from the staging area.
-
And if the file is
in the staging area,
-
Git will restore it
from the last snapshot
-
or the last commit.
-
Now in this case, we want to
change the default behavior.
-
We want to restore a file from
the commit before the last one.
-
So we type Git restore --source.
-
We set it to HEAD
tilde 1, and then
-
we specify the full path to the
file, in this case, file1.js.
-
Now, let's get a short status.
-
So we have a new untracked file.
-
So this is how we can restore
a file to a previous version.
-
-
Hey, guys.
-
Mosh here.
-
As I said before, this
video is the first hour
-
of my complete Git
mastery course.
-
The complete course
is five hours long
-
and covers intermediate to
advanced level concepts.
-
It comes with a
certificate of completion,
-
downloadable summary notes, and
a 30-day money-back guarantee.
-
So if you're not happy,
you can ask for a refund.
-
You will learn all about
browsing history, branching
-
and merging, collaborating with
others using Git and GitHub,
-
and rewriting history.
-
So by the end of
this course, you
-
will be able to
use Git like a pro
-
and work effectively
with others in your team.
-
If you're interested,
click on the link
-
below this video to enroll.
-
[MUSIC PLAYING]
-