< Return to Video

Git Tutorial for Beginners: Learn Git in 1 Hour

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

more » « less
Video Language:
English
Duration:
01:09:13

English subtitles

Revisions