n5321 | 2024年11月16日 09:02

Tags:


Git is the most popular version control system in the world。records the changes made to our code over time in a special database called repository we can look at our project history and see who has made what changes when and why and if we screw something up we can easily revert our project back to an earlier state without a version control system we'll have to constantly store copies of the entire project in various folders this is very slow and doesn't scale at all especially if multiple people have to work on the same project you would have to constantly toss around the latest code via email or some other mechanisms and then manually merge the changes

so in a nutshell with a version control system we can track our project history and work together now version control systems fall into two categories centralized and distributed in a centralized system all team members connect to a central server to get the latest copy of the code and to share their changes with others subversion and microsoft team foundation server are examples of centralized version control systems the problem with the centralized architecture is the single point of failure If the server goes offline, we cannot collaborate or save snapshots of our project. So we have to wait until the server comes back online. In distributed systems, we don't have these problems. Every team member has a copy of the project with its history on their machine. So we can save snapshots of our project locally on our machine. If the central server is offline, we can synchronize our work directly with others.


Git and Mercurial are examples of distributed version control systems. Out of all these, Git is the most popular version control system in the world because it's free, open source, super fast, and scalable. Operations like branching and merging are slow and painful in other version control systems like Subversion or TFS, but they're very fast in Git. We'll talk about this later.


So Git is almost everywhere. More than 90% of software projects in the world use Git. That's why almost every job description for a software developer mentions Git. So if you're looking for a job as a software developer, Git is one of the skills you must have on your resume. You should know it inside out, how it works, and how to use it to track your project history and collaborate with others effectively. And that's exactly what you're going to learn in this course.


Let's talk about various ways to use Git. We can use Git on the command line. So we open a terminal or command prompt window to execute Git commands. This is the fastest and sometimes the easiest way to get the job done. That's why a lot of people use the command line. Now if you don't like the command line, well, you're in luck because most modern code editors or IDEs have built-in support for basic Git features. For example, in VS Code, we have this source control panel which gives us the essential Git features. There are also extensions available for bringing additional Git features for VS Code. The most popular extension is GitLens; it brings a ton of Git features in VS Code.


There are also graphical user interfaces specifically made for using Git. Here on the Git website, you can find the complete list of these tools for different platforms.

We have tools for Windows, Mac, Linux, Android, and iOS. Out of all these, the two most popular tools are GitKraken and SourceTree.


GitKraken is my personal favorite GUI tool for Git. It's beautifully designed, works across different platforms, and integrates with other GitKraken products such as GitKraken Boards for issue tracking and GitKraken Timelines for project management. It's free for open-source projects, but for commercial projects, you have to pay an annual fee. Just to let you know, I'm not an affiliate of GitKraken; I'm just a fan.


The other option is SourceTree. It's completely free but only available for Windows and Mac. So if you're a Linux user, you have to use GitKraken or another GUI tool.


In this course, we'll be spending most of our time on the command line for a couple of reasons. The first reason is that pretty much all these GUI tools have limitations; they support the Git commands that people use most of the time. So even if you want to use a GUI tool, there are times you would have to revert back to the command line to get the job done. The other reason is that the command line is always available, whereas a GUI tool may not be accessible in certain situations.


Many people, including myself, use both the command line and a GUI tool. In this course, I'll show you when it makes sense to use a GUI tool and when the command line is faster and easier.


At the end of the day, you should use the right tool for the job. Don't be like this guy, you probably know him, our popular superstar developer called John Smith. He thinks he's better than everyone else because he does everything in the command line and looks down on people who use GUI tools. Let him think whatever he wants; if that makes him happy, who cares?


We'll be spending most of our time on the command line, but I'll show you examples in VS Code and GitKraken when it makes sense to use a GUI tool because those are the most popular tools.


If you've never worked with a command line before, don't worry; I'll guide you step by step. It's a lot easier than you think.


Next, we're going to install Git. Let's see if you have Git on your machine or not and, if yes, what version you have installed. To do this, open a terminal or command prompt window. If you're on Mac, press Command and Space, then type Terminal. If you're on Windows, click the search icon on the bottom navigation bar and type CMD.


Your terminal window might look different, but it doesn't matter. This is where we're going to execute Git commands.


Let's look at the version of Git on this machine. Type `git --version`. In this machine, I'm using Git version 2.19.2, but the latest version at the time of recording this video is 2.27.0. I highly encourage you to download and install the latest version. Head over to git-scm.com/download for instructions on installing Git on different operating systems. It's really easy, and you're not going to run into any problems.


If you're on Windows, once you install Git, you'll get an application called Git Bash, which is short for "Bourne Again Shell."

This is basically a command prompt window like this one over here but it emulates Unix or Linux environments. So throughout this course, I encourage you to use Git Bash instead of the built-in command prompt window, so what you see on the screen looks closer to what I'm going to show you in this course.

So, go ahead and install Git. In the next lesson, I'm going to show you how to customize our Git environment. The first time we use Git, we have to specify a few configuration settings. We have to specify our name, email, default editor, and how it should handle line endings.

We can specify these configuration settings at three different levels. At the very top, we have the system level. The settings that we have here apply to all users of the current computer. Below this level, we have the global level. The settings here apply to all repositories of the current user. And below this level, we have the local level. The settings here apply to the current repository or the repository in the current folder. So we can have different settings for different repositories or different projects.

So here, in the terminal window, we type git config, then we type --global to specify the level at which we are defining these settings. Next, we should specify the setting we want to configure. So, user.name. Here we type double quotes and type our name. Now the reason we're adding double quotes is because we have a space in this value. Okay, so that was the first setting.

Once again, git config --global. This time we're going to set user.email. Now because we don't have a space in emails here, we don't need double quotes. So, let's add our email.

Alright, next, we need to specify our default editor. If you don't set this on Mac, by default Git is going to use Vim, which is a scary editor a lot of people are freaked out by. In this course, I'm going to use Visual Studio Code or VS Code. You can use any editor that you prefer, but if you want to follow along with me, I highly encourage you to download the latest version of Visual Studio Code from code.visualstudio.com.

Now, on this machine, I've added Visual Studio Code to my path so I can open it from any folder on my machine without specifying the full path. So if I type code, here's VS Code. If this doesn't work on your machine, you have to troubleshoot the issue yourself. Depending on your operating system, there are different instructions for adding VS Code to your path.

So back to the terminal, let's set the default editor. git config --global, the setting we want to configure is core.editor. Once again, we need double quotes because here we're going to have a space. The value for this setting is code --wait. With the --wait flag, we tell the terminal window to wait until we close the new VS Code instance. Okay, so let's go ahead.

Now, all these configuration settings are stored in a text file. We can edit that file using our default editor, in this case, VS Code. So we can type git config --global -e. This will open our default editor to edit all the global settings. Let me show you.

Alright, here's our configuration file. You can see the full path to this file at the top. The name of this file is .gitconfig. In this file, we have different sections. So we have the user section with two settings, name and email. We have the core section with these two settings, and so on. Now back in the terminal window, you can see the terminal is waiting for us to close VS Code. So as we close it, now we're back in the terminal and we can execute the next command.

Next, we're going to configure how Git should handle end of lines. This is a very important setting that a lot of people miss. So on Windows, end of lines are marked with two special characters: carriage return and line feed. On Mac and Linux systems, end of lines are indicated with line feed. So that means if we don't handle end of lines properly, we're going to run into some weird issues down the road. To prevent this, we have to configure a property called core.autocrlf, which is short for "carriage return line feed".

Let me walk you through a real scenario. Let's say we have two people here, John and Julie, working with the same repository. John uses a Windows machine, Julie uses a Mac. As I told you, on Windows, end of lines are marked with carriage return and line feed. So when John wants to check in his code into the repository, Git will remove the carriage return character from end of lines. Similarly, when he checks out his code from the repository...

To achieve the desired behavior regarding end of lines and carriage return characters in Git, you should set the following properties:

  • For updating end of lines and adding the carriage return character:

    • Set the property to true.
  • When Julie checks out the code and doesn't want the carriage return character:

    • Git shouldn't touch the end of lines.
  • If carriage return characters are accidentally added to end of lines, perhaps because of the editor that Julie is using:

    • Git should remove them when storing the code in the repository.
    • Set this property to input.

To configure these settings, use the following command in the terminal:

bash
git config --global core.autocrlf

# For Windows:
git config --global core.autocrlf true

# For macOS or Linux:
git config --global core.autocrlf input

For information on Git commands and configurations:

  • To learn more about a specific command like git config, you can Google it or use git config --help in the terminal for detailed information.
  • For a quick summary, use git config -h.

In the next section, you'll learn about taking snapshots (commits) in Git, an essential part of the workflow. Make sure to grasp the fundamental concepts as they are often misunderstood by beginners.

To get started with a project in Git:

  1. Create a project directory.
  2. Initialize a new Git repository using git init.
  3. Understand the Git repository structure and avoid modifying the .git directory.
  4. Add and commit changes using the staging area to create snapshots of your project.

The basic Git workflow involves modifying files, staging changes, reviewing them, and committing them to the repository. The staging area allows you to review and organize your changes before committing them. Remember, each commit represents a snapshot of your project at a specific point in time.

When working with a staging environment similar to releasing software to production, it reflects either the current state in production or the upcoming version destined for production.

For instance, during bug fixing, changes are made to file one. The staging area initially holds the old version of file one until these changes are staged using the add command. Subsequently, a commit is made to record this state, resulting in two commits in the repository.

If a decision is made to delete file two, even though it's removed from the working directory, it remains in the staging area until the deletion is staged using the add command. Another commit is then made to permanently store this deletion, resulting in three commits in the repository.

Each commit in the repository contains a unique identifier generated by Git, along with information about the changes made, the author, the timestamp, and a complete snapshot of the project at that time. Git doesn't store just the changes made (deltas), but the full content of each snapshot, facilitating quick restoration to previous states without needing to compute changes.

The key to Git's efficiency in data storage lies in its compression of file contents and avoidance of storing duplicate content. This approach allows users to revert to any previous state quickly. While Git users don't need to know the specifics of how data is stored, understanding that each commit contains a complete snapshot of the project is crucial for leveraging the version control system effectively.

When fixing a bug and finding a typo in your app, avoid mixing changes in one commit. Make separate commits for each - one for the typo and another for the bug fix. If you accidentally stage both changes, you can easily unstage them as shown later. Create meaningful commit messages; cryptic messages are unhelpful. Committing single units of work makes crafting messages easier.

Use present tense for commit messages, e.g., "Fix the bug," for clarity and consistency. Stick to a message convention for team cohesion. Always consider best practices when committing code.

For advanced Git learning beyond this video, check out my full course covering intermediate to advanced topics, with a certificate, notes, and refund guarantee. Enroll via the link below.

You don't always have to stage changes before committing. Learn how to skip the staging area cautiously. Remove unnecessary files with rm and git rm. Use git mv for renaming or moving files.

To ignore files/directories, create a .gitignore in the project root. Add entries like logs/ to exclude certain files. Remember, Git won't ignore files already committed.

Here's the problem

Every time we compile our code, Git detects that the bin/app.bin file is changed, so we have to stage it and commit it. This doesn’t make sense. Why do we have to commit this file every time we compile our application?

Adding bin to .gitignore

To solve this, let’s add the bin directory to .gitignore. Back in the terminal, let’s run git status. Now, we have modified .gitignore.

Steps:

  1. Stage and commit the change:
    bash
    git add . git commit -m "Include bin in .gitignore"
  2. However, Git still tracks the changes in this directory because it’s already being tracked.

Removing bin from the staging area

Let’s modify the bin file by adding some content, for example:

bash
echo "Hello World" > bin/app.bin

Then run git status. Git will still say this file is modified, which is not what we want. To fix this, we need to remove this file from the staging area.

Use the git rm command with the --cached option to remove it only from the staging area, not from the working directory:

bash
git rm --cached bin/

If you see an error saying "Not removing bin recursively without -r," add the recursive option:

bash
git rm --cached -r bin/

Now, the entire directory is removed from the staging area. Verify this by running git ls-files. The bin directory is no longer there. Run git status again, and you’ll see one change ready to be committed—removing the directory from the staging area.

Commit the change:

bash
git commit -m "Remove bin directory from tracking"

From this point forward, Git will no longer track changes in the bin directory. You can still modify files like bin/app.bin, and your working directory will remain clean.


GitHub .gitignore templates

GitHub provides various .gitignore templates for different programming languages. For example, in Java projects, it’s a good idea to exclude .class files, as these are automatically generated during compilation. Visit the GitHub .gitignore templates repository for more examples.


Simplified output with git status -s

The git status command provides detailed but verbose output. Using the short format with git status -s makes it easier to interpret:

  • The left column represents the staging area.
  • The right column represents the working directory.

Example:

bash
echo "Sky" >> file1.js echo "Sky" > file2.js git status -s

Output:

  • M (modified): A file has been modified but not staged.
  • ?? (untracked): A new file not being tracked by Git.

Reviewing changes before committing

Before committing, always review what’s in the staging area to ensure no bad or broken code gets committed. Use this command to check the staged changes:

bash
git diff --staged

In the output:

  • Lines prefixed with - show what’s being removed.
  • Lines prefixed with + show what’s being added.

This allows you to ensure everything is correct before making a commit.

Understanding git diff and git difftool

Comparing file versions with git diff

In this example, we're comparing two copies of file2.

  • Legend clarification:
    • We don’t have an old copy of file2 because it’s a new file.
    • The header 0,0 indicates that starting from line 0, no lines have been extracted since there is no old version of this file in the last commit.

Viewing changes in the working directory

To see changes in the working directory that are not staged:

  1. Run git diff without arguments:
    This compares the working directory with the staging area.

    • If there are no changes, there will be no output.
    • If there are untracked changes, they will appear in the output.
  2. Verify with git status -s:
    Use this to check the working directory and staging area status.

Example:

  1. Modify a file (file1):
    Open file1 in an editor (e.g., VS Code). Change the first line to:

    plaintext
    Hello World

    Save the file.

  2. Run git status -s:

    • Shows changes in the working directory not yet staged.
  3. Run git diff:

    • This compares the staging area (old copy) with the working directory (new copy).
    • Lines prefixed with - are removed (old content).
    • Lines prefixed with + are added (new content).

Recap:

  • Use git diff to see unstaged changes.
  • Use git diff --staged to see staged changes ready for the next commit.

Using Visual Diff Tools

Popular tools:

  • Cross-platform: kdiffp4merge
  • Windows-only: WinMerge

Using VS Code as the default diff tool:

  1. Configure VS Code as your default diff tool:

    bash
    git config --global diff.tool vscode git config --global difftool.vscode.cmd "code --wait --diff $LOCAL $REMOTE"
  2. Check the global configuration:

    bash
    git config --global -e
    • This opens the .gitconfig file for editing.
    • Verify the diff section includes the tool and command you set.
  3. Using git difftool:

    • Run git difftool to compare changes in the working directory with the staging area.
    • Add --staged to compare staged changes.

Example with VS Code:

  1. Modify file1.js.

  2. Run git difftool:

    • Opens VS Code, showing the old copy (staged) and new copy (working directory).
    • Review changes visually.
  3. Close VS Code to return to the terminal.

Summary:

  • git diff: Command-line diff comparison.
  • git difftool: Launches visual diff tools like VS Code for easier file comparison.

    Two files have been affected in the staging area. The first one is file1.js. Let’s look at the changes.

    In this case, the old copy is what we had before, and the new copy is what we have in the staging area. These are the changes that will be included in the next commit. From this, we can easily tell that two lines have been added.

    Now, let's close this tab. Back in the terminal, Git is asking if we want to look at the changes in file2.js. In this case, I’ll ignore it and type no.

    Quite honestly, we don’t use diff tools as much these days. I covered it here because I want my course to be comprehensive. Modern editors and IDEs allow us to view staged and unstaged changes as part of our development environment. I’ll show you how to do this later in the course.

    Viewing Commit History

    We’ve made a few commits so far. But where are these commits? Let me show you. Use the log command to look at the history:

    bash
    git log

    Take a look! Here are all the commits we’ve created, sorted from the latest to the earliest.

    The most recent commit is at the top. Each commit has a unique identifier, a 40-character hexadecimal string generated automatically by Git. Think of it like a revision number, but instead of incrementing, it’s unique and randomly generated.

    Next to that, we see HEAD pointing to master. What does this mean?

    • Master: The main branch or main line of work in Git. Other version control systems might call this the “trunk.”
    • HEAD: A reference to the current branch, indicating where we are working.

    For each commit, we can see:

    1. Author: The name and email of the author.
    2. Date and time: When the commit was created.
    3. Description: A one-line summary.

    To navigate through the log:

    • Press space to move to the next page.
    • Press q to quit.

    Log Options

    The log command has a few useful options:

    1. One-line Summary:

      bash
      git log --oneline

      This shows a short summary of each commit with the identifier shortened to 7 characters and the description only.

    2. Reverse Order:

      bash
      git log --oneline --reverse

      This displays the commits from the oldest to the newest.

    Viewing Specific Commits

    If you want to see the exact changes in a specific commit, use the show command. For example, to inspect the most recent commit:

    bash
    git show <commit_id>

    Alternatively, you can use the HEAD reference:

    • To view the last commit:
      bash
      git show HEAD
    • To view the second-to-last commit:
      bash
      git show HEAD~1

    In the commit details, you’ll see:

    • Author and date: Information about the commit.
    • Diff: What was removed or added.

    If you want to see the exact file version stored in a commit:

    bash
    git show HEAD~1:<path_to_file>

    Viewing Files in a Commit

    To list all files and directories in a specific commit:

    bash
    git ls-tree <commit_id>

    This displays all the files and directories (as a tree structure) in the commit. Files are represented by blobs, and directories by trees.

    For example, to view a file or directory:

    bash
    git show <object_id>

    Managing Staged Changes

    Let’s say we reviewed the changes in the staging area and realized that the changes in file1.js shouldn’t be in the next commit (perhaps they belong to a different task). To undo the staging of this file:

    bash
    git restore --staged file1.js

    This restores file1.js to its state before it was staged. It’s worth noting that older Git versions used the reset command for this purpose, but the restore command simplifies the process.

    Make sure you’re using Git 2.28 or later, as the restore command won’t work in older versions.

    To restore a file in the staging area, use the --staged flag followed by the file name. You can list multiple files here or use patterns. If you want to restore everything in the staging area, simply use a period (.). For example:

    bash
    git restore --staged file1.js

    After running this command, if you check the status again with git status, you’ll notice that the green "M" indicating a modified file is gone. All changes in the staging area are now in the working directory. For a short status:

    bash
    git status -s

    You’ll see that file1 no longer has any changes in the staging area, as those changes have moved to the working directory.

    The git restore command works by taking a copy of the file from the next environment. For files in the staging area, this next environment is the last commit in the repository. For example, restoring file1.js copies it from the last snapshot into the staging area.

    Now let’s look at file2. It's a new file, indicated by a green "A" (added) in the staging area. However, since this file doesn’t exist in the last commit, restoring it will remove it from the staging area and return it to its previous state as an untracked file. Here's how:

    bash
    git restore --staged file2.js

    After running git status, you’ll see file2 marked with "??" as an untracked file.

    If you have code changes in the working directory that you want to discard, you can also use git restore. For instance:

    bash
    git restore file1.js

    This command copies the version of the file from the staging area back into the working directory, effectively discarding local changes. You can use a period (.) to undo all local changes:

    bash
    git restore .

    However, note that git restore won’t affect untracked files (e.g., file2). To clean up untracked files, you use the git clean command. By default, Git requires you to force this operation since it is irreversible. Use:

    bash
    git clean -fd

    This command removes all untracked files and directories. Checking the status again with git status -s will show that file2 is gone.

    Git tracks all versions of a file once it's committed, meaning you can always restore a file or directory to a previous version. For example, let’s delete file1.js. Using the rm command in Unix-based systems only removes the file from the working directory. To remove it from both the working directory and the staging area, use:

    bash
    git rm file1.js

    After staging this change, you can commit it:

    bash
    git commit -m "Delete file1.js"

    If you later decide you shouldn’t have deleted the file, you can restore it to a previous version. For example, to restore file1.js from the commit before the last one, identify the commit using git log, then run:

    bash
    git restore --source=HEAD~1 file1.js

    This command restores file1.js to its state in the specified commit (HEAD~1 refers to the commit before the last one). After restoring, the file will appear as an untracked file.









In this course, you're going to learn

everything you need to know to get started with Git.

If you're an absolute beginner or if you have been using git for a while but

never really understood how git works this tutorial is for you you're going to

learn all the fundamental concepts as well as the essential commands that

you need to know these are the commands that you would use

every day at work so by the end of this tutorial you will have a good grasp of

the basics and you'll be ready to learn more about the intermediate to advanced

concepts i'm adani and i'm super excited to be

your instructor if you're new here be sure to subscribe as i upload new

tutorials every week now let's jump in and get started so what is git and why is it so popular

git is the most popular version control system in the world

a version control system records the changes made to our code over time

in a special database called repository we can look at our project history and

see who has made what changes when and why

and if we screw something up we can easily revert our project back to an

earlier state without a version control system we'll

have to constantly store copies of the entire project in various

folders this is very slow and doesn't scale at

all especially if multiple people have to work on the same project

you would have to constantly toss around the latest code via email or some other

mechanisms and then manually merge the changes so

in a nutshell with a version control system we can

track our project history and work together now version control

systems fall into two categories centralized and distributed in a

centralized system all team members connect to a central

server to get the latest copy of the code

and to share their changes with others subversion and microsoft team foundation

server are examples of centralized version

control systems the problem with the centralized

architecture is the single point of failure

if the server goes offline we cannot collaborate or save snapshots of our

project so we have to wait until the server

comes back online in distributed systems we don't have

these problems every team member has a copy of the project with its

history on their machine so we can save snapshots of our project

locally on our machine if the central server is offline we can

synchronize our work directly with others

git and mercurial are examples of distributed version control systems

out of all these git is the most popular version control system in the world

because it's free open source super fast and scalable

operations like branching and merging are slow and painful in

other version control systems like subversion or tfs

but they're very fast and git we'll talk about this later

so git is almost everywhere more than 90 of software projects in the world use

get that's why almost every job description

for software developer mentions git so if you're looking for a job as a

software developer git is one of the skills you must have on your resume

you should know it inside out you should know how it works and how to use it to

track your project history and collaborate with others effectively

and that's exactly what you're going to learn in this course let's talk about various ways to use git

we can use git on the command line so we open a terminal or command prompt

window to execute git commands this is the fastest and sometimes the

easiest way to get the job done that's why a lot of people use the

command line now if you don't like the command line

well you're in luck because most modern code editors on ides have built-in

support for basic git features for example in vs code we have this

source control panel which gives us the essential git features there are

also extensions available for bringing additional git features for vs code the

most popular extension is gitlands it brings

a ton of git features in vs code there are also graphical user interfaces

specifically made for using git here on the git website you can find the

complete list of these tools for different platforms

we have tools for windows mac linux android and ios out of all these the two

most popular tools are git kraken and sourcetree git kraken is my personal

favorite gui tool for git it's beautifully designed it works

across different platforms and it integrates with other git

cracking products such as get cracking boards for issue tracking

and git cracking timelines for project management it's free for open source

projects but for commercial projects you have to

pay an annual fee just to let you know i'm not an

affiliate of git cracking i'm just a fan the other option is sourcetree it's

completely free but it's only available for windows and

mac so if you're a linux user you have to use git kraken or another

gui tool in this course we'll be spending most of our time on

the command line for a couple of reasons the first reason is that pretty much all

of these gui tools have some limitations they support the git commands that

people use most of the time so even if you want to use a gui tool

there are times you would have to roll up your sleeves

and get back to the command line to get the job done the other reason

is that the command line is always available but there are situations where

a gui tool may not be available to you you might connect to a server remotely

and you may not have permission to install a gui tool if you don't know how

to use the command line then you're stuck in practice a lot of

people including myself use both the command line and a gui tool

and that's what i'm going to show you in this course

there are times that it really makes sense to use a gui tool and not the

command line but there are other times that using the

command line is faster and easier so we'll use the command line

at the end of the day you should use the right tool for the job

don't be like this guy you probably know him our popular

superstar developer called john smith he thinks he's better than everyone else

because he does everything in the command line he never

uses a gui tool and he looks down at people who do

well let him think whatever he wants if that's what makes him happy

who cares so we'll be spending most of our time on the command line

but when it makes sense to use a gui tool i'll be showing you examples in vs

code and git kraken because those are the most popular tools

now if you have never worked with a command line before

don't worry i'm going to hold your hand and teach you everything step by step

it's a lot easier than you think so next we're going to install git all right let's see if you have git on

your machine or not and if yes what version you have installed to do

this you have to open a terminal or a command prompt window

if you're on mac press command and space and then type terminal

if you're on windows click the search icon on the bottom navigation bar

and type cmd so here's my terminal or console window

your terminal window might look different it doesn't matter this is

where we're going to execute git commands

so let's look at the version of git on this machine we type git

dash dash version so in this machine i'm using git

version 2.19.2 but the latest version at the time of recording this video is

2.27.0 so i highly encourage you to download

and install the latest version just head over to git scm.com download

over here you can find instructions for installing git on different operating

systems it's really easy you're not going to

have any problems now if you're on windows

once you install git you're going to get this application called

git bash which is short for born again shell

this is basically a command prompt window like this one over here

but it emulates unix or linux environments so throughout this course

i encourage you to use git bash instead of the built-in command prompt window

so what you see on the screen looks closer to what i'm going to show you in

this course so go ahead and install git in the next

lesson i'm going to show you how to customize our git

environment the first time we use git we have to

specify a few configuration settings we have to specify our name email

default editor and how it should handle line endings we

can specify this configuration settings at three different levels

at the very top we have the system level the settings that we have here

apply to all users of the current computer below this level we have the

global level the settings here apply to all

repositories of the current user and below this level we have the local

level the settings here apply to the current repository

or the repository in the current folder so we can have different settings for

different repositories or different projects

so here in the terminal window we type git config

then we type dash dash global to specify the

level at which we are defining these settings next we should specify the

setting we want to configure so user that name here we type

double quotes and type our name now the reason we're adding double quotes

is because we have a space in this value okay

so that was the first setting once again git config

dash global this time we're going to set user.email

now because we don't have a space in emails here we don't need double quotes

so let's add our email all right next fill it to specify our

default editor if you don't set this on mac by default

git is going to use vim which is a scary editor a lot of

people are freaked out by it in this course i'm going to use visual

studio code or vs code you can use any editor that you prefer

but if you want to follow along with me i highly encourage you to download the

latest version of visual studio code from

code.visualstudio.com now on this mission i've added visual studio code to

my path so i can open it from any folder on my

machine without specifying the full path so if i type code here's vs code

if this doesn't work on your machine you have to troubleshoot the issue yourself

depending on your operating system there are different instructions for

adding vs code to your path so back to the terminal

let's set the default editor git config global the setting we want to configure

is core that editor once again we need double

quotes because here we're going to have a space

the value for this setting is code space dash dash weight with the weight flag we

tell the terminal window to wait until we close the new vs code instance

okay so let's go ahead now all these

configuration settings are stored in a text file

we can edit that file using our default editor in this case vs code

so we can type git config dash dash global dash e this will open our default

editor to edit all the global settings let me

show you so all right here's our configuration

file you can see the full path to this file

on the top the name of this file is git config now in this file we have

different sections so we have the user section with two

settings name and email we have the core section with

these two settings and so on now back in the terminal window

you can see the terminal is waiting for us to close vs code

so as close as we know now we're back in the terminal and we

can execute the next command next we're going to configure how git

should handle end of lines this is a very important setting that a

lot of people miss so on windows end of lines are marked

with two special characters carriers return and line feed on mac and

linux systems end of lines are indicated with line

feed so that means if we don't handle end of lines properly

we're going to run into some weird issues down the road

to prevent this we have to configure a property called core.autocrlf which is

short for carriage return line fit so let me walk you through a

real scenario let's say we have two people here john

and julie working with the same repository

john uses a windows machine julie uses a mac

as i told you on windows end of lines are marked with carriage return

and line feed so when john wants to check in his code into the repository

get to remove the carriage return character from end of lines

similarly when he checks out his code from the repository

get should update end of lines and add the carriage return character

to achieve this behavior we should set this property to true

on the other hand when julie checks out the code she doesn't want the carrier's

return character so git shouldn't touch end of lines

however if carrie's return is accidentally added to end of lines

perhaps because of the editor that julie is using

git should remove it when storing the code in the repository

to achieve this behavior we should set this property to input

which means it should only modify end of lines when storing code in the

repository so back in the terminal we type git

config dash dash global core dot auto

crlf if you're on windows you should set this to true

if you're on mac or linux you should set this to input let me show you a few different ways to

get help about git commands let's say you want to learn more about

the config command you can simply google git config on this page you can see the

full documentation of this command you can see various options and how they

work we can also access the same page on the

terminal window we simply type git config dash dash

help this is exactly the same information you saw a second ago

here we can press space to go to the next page

and queue to exit now if you don't need a full blown help you just need a quick

refresher you can type git config dash h

this gives us a short summary of this command and its options so we're done with the introductory

stuff starting from the next section we're going to cover

a lot of git commands now below this video we can download

a pdf of all the commands we're going to cover in this course

if you're starting out don't worry too much about memorizing these commands

instead try to understand how they work as you practice getting the rail board

all these commands are going to become second nature to you trust me

so download the cheat sheet below this video and then i will see you in the

next section the first thing you need to know to use

git effectively is how to take snapshots of your project

which is what we're going to talk about in this section we'll be talking about

the fundamental concepts and git that are often misunderstood so make

sure to watch every lesson in this section

even if you think you know the basics a lot of people use the basic git commands

without having a proper understanding of how git works and that's why they

constantly get stuck so watch every lesson in this section

now let's jump in and get started alright the first thing we're going to

do is create a directory for our project you can call this directory anything and

put it anywhere on your machine it doesn't matter

i'm currently in the projects directory so let's create a directory called

moon and then go into this directory so let's imagine this is our project

directory and here we can have tens or hundreds of

files the first time we want to add this file to a git repository

we have to initialize a new empty repository

so we type get init look at this message initialized empty git repository in and

here's the full path so we have the moon directory and inside

this directory we have a sub directory called

dot git by default this subdirectory is hidden because you you're not supposed

to touch it so if we type ls to list all the

files and directories here we don't see anything but if we type

ls-a which is short for all we can see the git subdirectory if

you're on mac you can open this with finder and if you're on

windows you can open it with windows explorer or file explorer i'm not sure

what it's called these days so let's open dot get

take a look so here's our git directory or

git repository this is where git stores information about our project history

so we have directories like branches hooks info

objects and references now as someone using git

you don't really need to understand this structure this is purely implementation

detail it's how git stores information it's not

of our business that's why this directory is hidden so

you don't touch it if you crop or remove this directory you're going to lose your

project history let me show you so back in the terminal look at this

green marker it says git that means we have a git

repository in this directory now if you want to have a pretty

colorful terminal window like this on mac you need to install zh or z shell

and on windows you need to install poshkit but don't worry about it now

these tools are completely optional to use git it's just for making things

pretty so here we have a git repository now if

i remove the git sub directory we're going to lose this repository so

rm dash rf dot get

look the green marker is gone we don't have a git repository here anymore

so don't touch this directory now once again

let's initialize a git repository beautiful

so now that we have a repository next we're going to talk about the basic git

workflow now that we have a git repository let's

talk about the basic git workflow what we do on a daily basis when using

git so here's our project directory and here's our git repository which is

actually a hidden sub directory in our project directory

now every day as part of working on various tasks we modify one or more fans

when our project reaches a state we want to record we commit those changes into

our repository creating a commit is like taking a

snapshot of our project now in git we have a special area or a

special intermediate step that doesn't exist in most other version

control systems it's called the staging area or the

index it's essentially what we're proposing for the next commit

or the next snapshot so when we're done making changes

we add the modified files to the staging area or index

review our changes and if everything is good then we'll make a commit

the proposed snapshot will get permanently stored in our repository

so the staging area allows us to review our work before recording a snapshot

if some of the changes shouldn't be recorded as part of the next snapshot

we can unstage them and commit them as part of another snapshot

that's the basic git workflow now let me walk you through a real example

this example is crucial so pay close attention

all the way to the end even if you think you know the basics

our project directory is currently empty so we add a couple of files here

now we are ready to record this state so we use the add command

to add these files to the staging area now these files are in the staging area

this is the state we're proposing for the next commit

we review these files everything is good so we use the commit command

to permanently store this snapshot in the repository

as part of this we supply a meaningful message to indicate what the snapshot

represents this is essential for having a useful

history so as we fix bugs implement new features

and refactor our code we make commit and each commit clearly

explains the state of the project at that point in time so now we have one

commit in our repository now a common misconception about git is

that once we commit the changes the staging area becomes empty this is

not correct and i think this is why a lot of people find git confusing

so what we currently have in the staging area is the same snapshot that we stored

in the repository so this staging area is actually very

similar to a staging environment we use when releasing software to production

it's either a reflection of what we currently have in production

or the next version that's going to go in production so let's continue with our

example let's say as part of fixing a bug we

make some changes to file one note that what we currently have in the

staging area is the old version of file one

because we haven't staged the changes yet so once again we use the add command

to stage the changes now what we have in the staging area is

the same content we have in our working directory

so let's make a commit to record this date now we have two commits in our

repository also look at the commit message it's

describing the bug that we just fixed now let's say we realize that we no

longer need file to it contains unused code so we delete it from our

working directory but this file is still in the staging

area so once again we should use the add command to stage

this change in this case the deletion this is the interesting

part even though we're saying add file to it knows that file 2 is

actually deleted so it will delete this file from the

staging area or the next snapshot again we make a commit to permanently

record this date now we have three commits in our

repository each commit contains a unique identifier that gets generated by git

it's like a revision number each comment also contains information about what was

changed by who when as well as a complete

snapshot of our project at the time it was created

so unlike many other version control systems git doesn't store the deltas

or what was changed it stores the full content

with this it can quickly restore the project to an earlier snapshot without

having to compute the changes now you might ask but hey mosh when

storing the full content in every snapshot

waste a lot of space no because git is very efficient in data storage

it compresses file contents and doesn't store duplicate content

now someone using git you don't really need to know how it stores data

that's implementation detail and may even change in the future

what you need to know is that each commit contains a complete snapshot of

our project and this allows us to quickly get back

to a previous state so that's the basic idea

over the next few lessons you're going to see this workflow in action let's start by adding a couple of files

to our project to do that we're going to use the echo command

this is not a git command it's just a standard unix or linux command

for writing content to a file so here we're going to write

hello to file1.txt so here i'm working with a text file

because i don't want this course to be specific to people who know

a particular programming language like python or javascript

what i'm going to show you in terms of the workflow applies to any programming

languages okay so we write hello to file1.txt

good now let's execute this command one more time

and change file 1 to file 2. so now we have two files in our project

now look at this question mark here that means we have new files here that are

not tracked by git because the first time you initialize a

git repository in a directory git is not going to automatically track

your files so if you have a thousand files in your project you

have to instruct it to track them okay so here we're gonna run git status

to see the status of the working directory and the staging area

take a look so we don't have any commands yet we have untracked files

which are file one and file two they're indicated by red

because they are not in the staging area yet to add these files to the staging

area we use the git add command here we can

list a single file like file one the txt or multiple files

separated by a space we can also use patterns so

star.txt that means all the files with the txt extension

we also have period which adds the entire directory recursively

now you have to be a little bit careful with this because sometimes there are

files you don't want to add to your repository

perhaps large files like large binary files or log files you don't want to add

this faster repository because they increase the size of your

repository i will show you how to ignore these files later in this section

so just remember add period adds the entire directory recursively

in this demo i'm going to go with this command because we only have two files

in this directory okay now our green indicator changed to

yellow which means we have stuff in the staging area

that are ready to be committed so if we run git status again

look we have two new files and they're indicated by green which means

they're in the staging area now let me show you something interesting

i'm gonna modify file one so once again we're gonna use the echo command

to echo world but here instead of one greater than sign

i'm gonna use two greater than science which means append

so we're going to append world to file one the txt

now let's run git status again look what happened

we have two files in the staging area because they're indicated by green

but we also have one modified file in our working directory

so you might be asking but hey marsh didn't we already add file 1 to staging

area yes we did but when we ran the add

command git took a snapshot of file 1 and added that snapshot to the staging

area so here's the current situation in the staging area we have the first

version of file one we changed this file after we added it

to the staging area so what we currently have in our working

directory is the second version of this file

it has some changes that are not staged yet so back to the terminal

we run git add period or git add file one the txt one more time

now look at the status of our working directory

both these files are in the staging area and we don't have any unstaged changes

so next i'm going to show you how to commit this snapshot to permanently

store it in our git repository now we have a snapshot in the staging

area ready to be permanently stored in our repository

so we type git commit dash m for message and here in double quotes we

type a short description that identifies what this snapshot represents so here

i'm going to say initial commit now there are times that

a short one-liner description is not sufficient

you want to explain some details to give context for example if you worked on a

bug and there were some constraints at the

time you committed your code you may want to explain those

constraints this is very valuable to both you and your co-workers

so in situations like this we drop the message

we just type get commit now when we press enter

this opens our default editor in this case vs code

because at the beginning of the course i configured my default editor to be vs

code okay so here we're trying to edit this

file commit underline edit message which is stored

in our git sub directory so on the top we can type a short

description ideally this should be less than 80

characters then we add a line break and after that we can type a long

description now these lines that start with the

pound sign are comments they're going to get ignored

so we type whatever one here in this case i'm going to say

initial commit and this is our first comment of course this is

repetitive we don't have commit messages like this

but for this demo i'm going to go with this message so

we save the changes then we close this window

back in the terminal our snapshot is committed and here we have basic

statistics about what was changed so two files were changed which are file

one and file two and we have three insertions three lines

were inserted in file one we inserted two lines hello

world and in file two we inserted one line now

look at this indicator it turned green because our working

directory is now clean it doesn't have any new changes so what

we have in our working directory is exactly the same content we have in

our staging area which is exactly the same content we

have in the last commit let's talk about the best practices for

committing code first of all your comments shouldn't be too big or too

small we don't want to make a commit every

time we update a file that's just useless because we'll end up with

comments like update file one update file to object

five three it's just useless on the other hand we don't want our

comments to be too big we don't wanna wait and

implement a feature end to end before committing it we don't want to code for

three days and then make it commit because the whole point of committing is

to record checkpoints as we go so if you screw up we can always go back

and recover our code so try to commit often in the real world

you might commit five to ten times a day or even more

depending on the kind of work you are doing but this is just a basic guideline

don't take it as a rule don't try to aim for five or ten commits a day

so as you're coding as you reach a state you wanna record then make a commit

also each commit should represent a logically separate change set

so don't mix things up for example if you're fixing a bug

and then you accidentally find a type on your app you shouldn't commit both these

changes in one commit you should have two separate commits one

commit for the typo another one for the bug fix now if you

accidentally stage both these changes you can easily unstage them i will show

you how to do this later in this section next you should give yourself the habit

of creating meaningful commit messages because all of these messages are going

to show up in history so if your messages are cryptic

they're not going to be helpful to you or other team members now if you

followed my previous advice if your commit represents a single unit

of work it would be easier to come up with a message for your commit

if you're doing too many things in one commit you're not going to come up with

a good message okay now in terms of the wording most

people prefer to use the present tense in their commit messages

so instead of fix the bug you should say fix the bug

if you don't like this convention that's totally fine but whatever convention you

use make sure that you and other team

members stick to it so always take these best practices in mind

when committing code hey guys mosh here i just wanted to let

you know that this video you've been watching

is actually the first hour of my complete get mastery course

and covers only the basic stuff so after you finish this video

if you want to learn more take a look at my full course the complete course is 5

hours long and covers intermediate to advanced

level concept it comes with a certificate of completion

downloadable summary notes and a 30-day money-back guarantee

so if you're not happy you can ask for a refund you will learn all about browsing

history branching and merging collaborating with

others using git and github and rewriting history so by the end of

this course you would be able to use git like a pro

and work effectively with others in your team if you're interested click on the

link below this video to enroll one of the common questions a lot of

beginners have is do we always have to stage our changes before committing them

well the answer is no and in this video i'm going to show you how to skip the

staging area but do this only if you know what you're

doing if you're 100 sure that your code your changes don't need to be reviewed

because that's the whole point of having a staging area

so let's modify file 1 and then commit it in one step

we're gonna say echo test to file one.txt

once again we're appending this line to file1.txt okay

all right now we have a yellow indicator because our working directory is dirty

so instead of running git add and then committing it in two steps

we're going to commit here we're going to supply the option

dash a which means all that means all modified files

and then just like before we supply a message or we can combine

these two options so let's supply a message

fix the bug that prevented the users from signing up let's go

our code is committed one file was changed and we have one insertion

so this is how we can skip the staging area but once again

do this only if you know what you're doing 99 of the time you should always

stage your code before committing it to the repository let's say that we just discovered that

we no longer need file 2 in our project because it contains

unused code so to remove this file we type rm

file2.txt again this is not a git command because it doesn't start with

git it's just a standard unix command okay

so let's go with this now we have a yellow

indicator which means our working directory is dirty so let's

run git status we have one change that is not staged

for commit so we remove file 2 from our working directory

but still exists in the staging area let me prove it to you

so we type get ls files these are the files in our staging area

so file2 is still here even though we removed it from our

working directory so as i told you before

every time we make changes we have to stage those changes using the add

command so here we type git add file to

txt to stage this change or this deletion more accurately

now let's run git ls files one more time so file two is no longer in the staging

area beautiful let's run git status we have one change

that is ready to be committed and as you can see it's indicated by green which

means it's in the staging area so let's commit

this change and here we're going to say remove

unused code so to remove a file we have to

remove it from both our working directory

as well as the staging area because this is a very common operation

git gives us a command that does both of these steps in one go

let me show you so we type get rm so instead of using the standard rm

command in unix we use git rm here we list a file name

like file2.txt we can also specify multiple files we

can also use patterns like all text files when we execute this

command git removes this file from both the

working directory as well as the staging area

now let's talk about renaming or moving fast so currently we have a single file

in our working directory and that is file1.txt let's rename this

to main.js so we use the move command in unix to

rename file1.txt domain.js so with this command we can

rename or move files and directories okay now our

working directory is dirty so let's run git status we have two

changes and both these changes are unstaged

because they're indicated by red we have a delete operation we deleted

51. txt and under untracked files we have a new

file so as you saw at the beginning of this

section git doesn't automatically track all your new files

every time you have a new file in your project you have to add it to the

staging area so git starts tracking it so once again we have to use the add

command to stage both these changes git add file1.txt this is for staging

the deletion and now let's add the new untracked file

main.js now let's run git status one more time

look git recognized that we renamed file1.txt

to main.js and this item is indicated by green

which means this is in the staging area so renaming or moving files is a

two-step operation first we have to modify our working

directory and then we have to stage two types of changes an addition and a

deletion so similar to removing files git gives

us a special command for renaming or moving files that is git

move so instead of using the standard move command in unix

we're going to use git move now let's rename main.js

to file1.js and then run git status one more time

so we have a rename operation for renaming file on the txt

the file on the js so when we use the move command

the changes are applied to both the working directory and the staging area

now let's commit the changes for the message i'm going to say

refactor code now look at the statistics one file was changed we have zero

insertions because we haven't added any new lines to any of our files and we

also have zero deletions because we haven't removed any lines

from any files in almost every project we should tell

git to ignore certain files and directories

for example we don't want to include log files or binary files that get generated

as a result of compiling our code adding these files is just going to increase

the size of our repository without providing any values every

developer can have their own log files right

so log files are not something we want to share and synchronize with other team

members so for this demo let's create a

directory called logs and then add a log file here once again

we can use the echo command to write hello to logs dev.log

now let's run git status so git is saying that

we have an untracked directory called logs but we don't want to add this to

the staging area because we don't want git to track this

so to prevent this we have to create a special file called

dot git ignore so this file has no name it

only has an extension and it should be in the root of your

project so let's echo logs forward slash to dot

git ignore now i'm going to open this file using vs code

so code git ignore so in this file we have a single entry

logs forward slash which indicates a directory we can list

as many files and directory as we want here

for example we can include main.log we can also use

patterns like all log files and so on once we are done we save the changes

back in the terminal now if you run git status one more time

git no longer says that we have a new directory called logs

because it's ignoring it instead it says we have a new file called

dot get ignore so let's add this file to the staging area

and then commit our code so add git ignore

so this is how we can ignore files and directories in git

just remember this only works if you haven't already included a file or a

directory in your repository in other words if you accidentally

include a file in your repository and then later added to git ignore git

is not going to ignore that let me show you so let's create a new

directory called bin let's imagine that this directory

contains our compiled source code so using the echo command i'm going to

write hello to bin app.bin

now let's run git status so we have a new directory

now we want to accidentally commit this to our repository so

we add all the changes and then commit our code

add bin here's the problem every time we compile our code git is

going to say that this file bin app.bin is changed so we have to

stage it and then commit it it doesn't make sense why do we have to

commit this file every time we compile our application

so back to git ignore let's add the bin directory here as well

now back in the terminal let's run git status so we have modified git ignore

beautiful list stage and commit this change so git add

period and then git commit include in slash and git ignore

now in this case git is not going to ignore the changes in this directory

because it's already tracking this directory so let's modify our bin

file by saying echo hello world to bin slash app.bin

git status look git is saying that this file is modified this is not

what we want to solve this problem we have to remove this file from the

staging area which is what we're proposing for the next commit

so earlier we talked about get ls files this command shows the files in

our staging area so as you can see this bin file or the

bin directory is already in the staging area

we should remove it here how well earlier we talked about

the git remove command i told you that with this command we can remove a file

or a directory from both the working directory as well as the staging area

but in this case we don't want to remove this file from our working directory

because that's how we launch our application so we want to remove this

file only from the staging area how well

let's add dash h for a quick help so we type

git rm then we can add zero or more options

now here we have this option called dash dash cache

with this we can remove stuff only from the index

index is the old term for the staging area so when you look at git

documentation most of the time you see index so using

this option we can remove the bin directory from the

index so git rm dash dash cached bin

forward slash now we get an error saying not removing bin recursively without

dash r so one more time let's look at the help

for this command we have another option called dash

r for recursive removal so we want to remove the entire bin directory from the

staging area to do that we type git rm dash dash

cache dash r bin forward slash

beautiful now this entire directory is removed from the staging area

let's verify it so get ls files our bin directory is no longer here now

let's run git status look we have one change that is ready to

be committed this directory is deleted from our

staging area so let's commit the change

remove the bin directory that was accidentally

committed okay from this point forward git is no longer going to track the

changes in this directory so if we encode test to bin

slash app.bin you can see our working directory is still clean we don't have

any changes we can verify it using git status as

well so this is how we can ignore files and directories in git

now if you head over to github.com github

get ignore you can see various git ignore templates for different

programming languages for example let's look at the template

for java so for java projects it's a great idea

to exclude all the class files because these files

get automatically generated when you compile your code so there is no need to

include them in your repository so here we have various patterns like

all the class files or all the log files the lines that start with a high sign

these are comments so they get ignored by git

so you have learned how to get the status of the working directory and the

staging area using the status command the output of this command is very

comprehensive but it's also very wordy so as an alternative we can supply the

short status flag or dash s let me walk you through a few examples

so for this demo we're going to modify one

of our existing files and then add a new file so echo sky

2 file 1.js so we're appending a sky to 51.js now let's create a new file

so once again echo sky to file to the js now let's run git status we have

modified file one and we have a new on-track file so as

you can see the output of this command is very

comprehensive but also very wordy now let's run git status dash s this is

much easier to dice so let me show you how this works here

we have two columns the left column represents the staging

area and the right column represents the working directory

so we have modified file one and that's why we have a red

m in the right column which is the working directory so we have some

changes here but these changes are not in the staging

area that's why we don't have anything in the left

column now file two is a new file that's why we have two question marks in

both these columns now let's add file one to the staging

area so github file 1 and then do another short

status look for file 1 we have a green m in the

left column or the staging area column so all the changes that we had in the

working area are now in the staging area in the right column we don't have

anything we don't have any extra changes now earlier in this section i told you

that when we stage a file git takes a snapshot of that file

and puts it in the staging area so if you modify that file after

we have to restage the changes let me show you this one more time

so i'm going to modify file one one more time let's echo ocean

to fileone.js and then run git status dash s look what we have here

so in the left column we have a green l which means we have some changes in the

staging area but we have some additional changes in

the working directory that are not added to the staging area

okay so let's add file one to the staging area

one more time and then run git status dash

s now all the changes that we had in the working directory

are now in the staging area so we're done with file one

let's look at file two so i'm gonna add file two

to the staging area as well and then run git status dash s for file two we have a

green a in the left column which represents

added so file two is added and file one is modified this is how the

short status output works so we have staged a couple of changes

now before committing what we have in the staging area we need to review our

code because we don't want to commit bad code or broken code

to our repository so as a best practice always review what you have in the

staging area before making a commit now the status

command only shows the files that have been affected

but how can we see the exact lines of code that we have staged

we use the diff command so we type get div dash dash staged to see what we have

in the staging area that is going in the next commit

so let's take a look here now quite frankly comparing files using the

terminal window is not really the best way to do this

quite often we use visual tools and i'm going to talk about that in the next

video but i think it's essential for you to

understand the output of this command because there are times that you may not

have access to a visual tool or at this you may go to an interview

and you may get asked what is the output of this command so you need to be able

to explain it so on the top you can see that the diff

utility was called with these arguments so we are comparing

a slash file1.js with b file1.js

so we're comparing two copies of the same file the first copy

is the old copy which is what we have in the last commit

and the second copy which is the newer copy

is what we currently have in the staging area okay now

below that we have index whatever this is just some metadata it doesn't really

matter after that we have a legend so changes

in the old copy are indicated by a minus sign and

changes in the new copy are indicated by a plus sign after that

we have this section this is a header with some

information about what parts of our file has changed so

currently our files are very short they have only a few lines of text

but in the real world your file might have hundreds of lines of code

if you change only a couple of lines git is not gonna show the

entire file it's gonna divide that file into chunks

and what we have here is just a single chunk so every chunk

has a header with some information that gives you context

so let's see what we have here we have two segments the first segment

is prefix with a minus sign so this gives us information about the old copy

what we have in the last snapshot the second segment

is prefixed with a plus sign so this contains information about the new copy

which is what we have in the staging area

so in the old copy starting from line one

three lines have been extracted and shown here

in the new copy once again starting from the first line

five lines have been extracted and shown here

so these are all these lines over here now you can see that these two lines

are prefixed with a plus sign so these are the lines that we have added in the

new copy so we have added these lines in the

staging area they're green which means they're new lines

so pretty straightforward now after that we have

another call to the diff utility this time we're comparing

two copies of file two now in this case look at the legend we don't have an old

copy because this is an entirely new file so

in the last commit we didn't have a file called

file2 that is why in this header we have 0 comma 0

which means starting from line 0 0 lines have been extracted

because there is no old copy of this file okay now what if you want to see

the changes in our working directory that are not staged yet to do that we

run git div without any arguments so this compares what we have in the

working directory with what we have in the staging area

take a look there is no output here because we have staged

all the changes in our working directory we can also verify this using our short

status command so all the changes in our working

directory are now in the staging area so for this demo i'm going to make a

change to file 1. so let's open it with vs code or our

favorite editor so i'm going to change the first line

to hello world save now let's run another short status

so for file 1 we have some changes in our working directory that are not in

the staging area let's look at these changes using the

dev command so git diff without any arguments take a

look so here we're comparing two copies of

file one the old copy is what we currently have in the staging area

and the new copy is what we have in the working directory

now take a look in the old copy which is indicated by a minus sign

we have this line hello which is removed because it's red

and in the new copy which is what we have in the working directory

we have this new line hello world so to recap

if we run git diff without any argument we can see

unstate changes and if we pass dash dash staged

we can see this state changes that are going to go in the next commit

in the next lesson i'm going to show you how to use a visual tool to easily

compare files as i told you in the last lesson quite

often we use visual div tools for comparing files

there's so many visual div tools out there the most popular ones are kdiff

and p4 merge which are cross platform and win merge

that runs only on windows in this lesson i'm going to show you how

to use vs code for comparing files if you want to use a different tool or a

different editor you have to look up the instructions yourself

so here in the terminal first we have to tell git that we want to use vs code as

our default devtool so we have to set two configuration

settings so once again we type git config dash global so the global

settings apply to all of our repositories

okay now the setting we're going to set is diff

dot tool we're going to set that to vs code so with this command

we're just giving a name in this case vs code to our default div tool

next we have to tell git how to launch vs code

so once again git config dash global here we set div tool dot vs code

dot cmd we set this to double quotes because we're going to have a space

now on my machine i've added code to my path so i can run it from any

directories if this doesn't work on your machine you

have to look up the instructions yourself

depending on your operating system so we're going to launch code with a few

arguments the first one is dash dash wait this

tells the terminal window to wait until we're done with vs code so until we have

compared the changes and close the vs code instance the

second argument is dash div this tells vs code that we want

to use it for diffing or comparing files then we have two more

arguments dollar sign local in capital and dollar

sign remote and capital these are

placeholders for the old and new copies of a file okay so let's

set that now let's make sure that you've got this

step right so we're gonna run git config dash dash

global e as i told you at the beginning of the

course with this command we can edit our global configuration settings

in our default editor which is vs code so take a look so all these things are

stored in this file dot git config which is

stored in this directory so we have the user

section which we said earlier in the course

now here's a diff section that we just set in this section we have set the tool

to vs code this is just a name then we have diff tool

vs code and here's the command that should be run for comparing files with

vs code so we have code with dash weight then

dash diff now those two placeholders that i added

for some reason they're lost so let's add them real quick

dollar sign local and dollar sign remote make sure to get this right otherwise

things are not going to work on your machine

now we're done so let's close this window

back in the terminal instead of using the div command we're going to use

div tool this will launch our visual div tool for comparing files

now if we don't still play any arguments we're going to see our on state changes

so this will compare what we have in the working directory with what we have in

the staging area if you want to look at our state changes

we supply dash dash stage exactly the same way we

use the diff command okay so let's look at the changes we

have in our working directory we have modified only a single file that

is why we have one out of one and that is file1.js

so git is asking if you want to launch vs code which is the name that we

assigned to our default div tool let's go ahead take a look

so here's the old copy which is what we have in the staging area

and here's a new copy which is what we have in the working directory

as you can see we can easily tell that this line

has been replaced with this line it's much easier to see the changes

now the terminal window is waiting for us to close the vs code instance

so let's close this window back to the terminal

now let's look at the state changes so get div tool

dash dash staged two files have been affected in the staging area

the first one is file1.js let's look at the changes

all right in this case the old copy is what we have in the last command

and the new copy is what we have in the staging area so these are the changes

that are going to go in the next commit you can easily tell that we have added

two lines here now let's close this tab back in the

terminal git is asking if you want to look at the

changes in file2.js in this case i'm going to ignore that so

no like quite honestly we don't use diff tools so much these days i just covered

it because i want my course to be comprehensive

these days most editors and ids allow us to view the staged and unstate changes

as part of our development environment i will show you how to do this later in

this section we have made a few commits so far but

where are these commits let me show you so we use the lock command to look at

our history take a look so here are all the commits we have

created sorted from the latest to the earliest

so here's our last commit on top each commit has a unique identifier

this is a 40 character hexadecimal string that git automatically generates

for us you can think of it like a revision

number but unlike a revision number it doesn't

increase it's just a unique identifier okay now next to that we have

head pointing to master what is this well we're going to talk about this a

lot in the future but master is the main branch or the

main line of work in git in some other version control systems

it's called trunk and git we can have multiple branches

so we can work on multiple features or multiple bug fixes in parallel

and then combine our code we'll talk about that later in the course

now head is a reference to the current branch

so this is how git knows what branch we're currently working on

again we're going to talk about this a lot in the future

now for each commit you can see the author the name of the author as well as

their email the date and time the commit was created

as well as the one-line description like here we have multiple commits that

are spread across multiple pages we can press space to go to the next

page and again now to quit we can press q

now the log command has a few interesting options one of them is

one line this shows us a short summary of the commit

so here we have the unique identifier that is shortened to seven characters

and we only have the one line description so we don't have the author

as well as the date and time of each commit we have another option for

reversing the sort order let me show you so git log one line and then we add dash

dash reverse now you can see the first

command be on top and here's the last commit now

the law command is very powerful so in the future we're going to talk a

lot about it in fact we have a complete section on browsing history

i'm going to show you various ways to get reports from the history

for now let's just stick to the basics so viewing the list of commits is great

but what if you want to see what exactly we have changed in a given commit

that's when we use the show command for example let's say we want to look at the

content of this commit over here we type git show now here we need to

specify the commit we want to inspect there are two ways to reference the

commit we can reference it using its unique identifier

so we type d601b 90. now we don't have to type all the

seven characters we can type fewer characters as long as

we don't have another commit whose id starts with these characters so

that's one way to reference a commit another way is to use the head pointer

so look head is currently in front of the

last commit so to view the last commit we can type head

or to look at previous commit we can type a tilde

and then specify how many steps we want to go back so if we type one

we start from head which is here we go one step back and

this references this command over here let's take a look

so on the top we can see the author and the date of this commit

as well as its message below that we have a diff of what has changed

so in this commit we have changed a single file that is git ignore

over here we can see that we removed this line

and added these two lines so this is very useful

now what if we don't want to see the differences we want to see the final

version the exact version that is stored in this commit

well we bring down the last command git show

head tilde one then we type a colon and here we specify

the full path to a file for example we can say

dot git ignore or if this file is in a subdirectory

we type for example bin slash app.bin okay now let's look at git ignore

so this is the exact version stored in this commit now earlier i told you that

each commit contains a complete snapshot of a

working directory not just changes but when we run the

show command we only see the differences but it's

changed what if you want to see all the files and directories in a

commit well for that we're going to use a different

command that's called ls tree now why is this called a tree well

a tree is a data structure for representing hierarchical information

so in a tree we can have nodes and these nodes can have children

now a directory on the file system can be represented using a tree

because each directory can have children these children can be files

and other subdirectories if you want to learn more about this concept

you should take my data structures course so lst means

list all the files in a tree now here we specify the comments we are interested

in head tilde one and now look these are

all the files and directories stored in this commit

so we have git ignore right before that we have a unique identifier

that is generated based on the content of this file

so in git's database we have an object with this id

below that we have bin again it has a unique identifier that is generated

based on the content of this directory now look at the type of this object it's

a tree so files are represented using blobs and

directories are represented using trees all of these are objects that are stored

in git's database using the show command we can easily

view an object in git's database for example if we type git show and then

specify this unique identifier or we can type

only the few characters as long as there is no ambiguity so

here's the content of our git ignore file

as another example let's look at this object this tree

the bin directory so git show 64629 here we have a tree

in this tree we have this file app.bin so using the show command we can view an

object in git's database these objects can be commits

blobs which represent files and trees which represent directories

as well as tags we'll talk about tags in the future so i told you that you should always

review the stuff that you have in the staging area

before making a commit so let's say we reviewed these changes

and we realized that the changes in file one shouldn't go in the next commit

perhaps because these changes are logically part of a different task

so we don't want to have a commit that represents changes for different tasks

right so in this case we want to undo the add operation

because earlier we use the add command to add file 1 to the staging area

now we want to undo this operation how do we do this well

in the past we used the reset command but a lot of people found this command

confusing especially with options such as hard or

soft that's why we have a new command called

restore now make sure you're using the latest version of git

otherwise what i'm going to show you is not going to work on your machine

so here i'm using git version 2.28 and with this we can easily restore

files in different environments in working directory or in staging area

so git restore we want to restore

file 1 in the staging area so we type dash dash staged and then we specify

the file name we can list multiple files here

we can also use patterns or if you want to restore everything in the staging

area we simply use a period so here i'm going

to restore file1.js now

when we run git status again you're not going to see a green m here because all

the changes that we had in the staging area

are now in the working directory take a look so

git status dash s look we no longer have any changes for file one

in the staging area all the changes are in the working directory

now it's essential for you to understand how the restore command works

the restore command essentially takes the copy from the next

environment so in case of the staging environment

what is the next environment the last commit what we have in the repository

so when we restored file one in the staging area git took the last copy of

this file from the last snapshot and put it in the staging area that is

what happened now look at file two file two is a new file because here we

have a green a which is short for added so we have this file we have this new

file in the staging area but this file doesn't exist

in the last commit so what do you think will happen when i restore this file

well because we don't have a copy of this file in our repository or in our

last commit git is going to remove this file from

the staging area and take it back to its previous state

which is a new on-track file let me show you

so git restore dash staged file2.js now let's run git status again

so file2 is a new untracked file because we have two question marks there are times that we have some code

in our working directory that we want to throw away

let's say we made some changes but we didn't like those changes so we want to

scratch everything and start over we can discard the local changes using

the restore command so here we have some local changes in

file1.js to undo these changes we type git

restore file1.js when we execute this command

git is going to take the version of this file in the next environment which is

our staging environment it's going to take that version and copy

into our working directory we can also use a period here and this

will undo all the local changes now let me show you something so the

command is executed now let's run another short status but

file two is still here why is that well this is a new on

tracked file so git hasn't been tracking this so when

we tell git to restore this file git doesn't know where to get a previous

version of this file it doesn't exist in our staging

environment or in our repository so to remove all these new untracked

files we have to type get clean now take a look

by default we get this fatal error saying require force defaults to true

and neither of these switches were given so basically git is telling us that hey

this is a dangerous operation if you accidentally remove these ontrack

files there is no way you can recover them

so let's run git clean dash for quick help

here we have this option dash f which forces git to remove this on track files

you also have d for removing whole directories

so quite often we type git clean dash fd now let's run short status again

file two is gone so this is how we undo local changes so now you know that once git tracks a

file it stores every version of that file in its database

and that means if you screw things we can always restore a file or a directory

to a previous version so in this demo i'm going to delete a file and then show

you how to restore it it's very easy so we're going to delete

file1.js now i told you that if we use the rm

command in linux or unix based systems this will only remove the file from the

working directory so then we'll have to stage the change or the deletion

a better way is to use the git rm command

this will remove the file from both the working directory as well as the staging

area okay now let's get a short status

so in the staging area we have a deleted file now

let's make a commit delete file1.js all right now let's say shoot we

shouldn't have deleted this file so what can we do here

well we have a few options we can undo or revert the last commit we're going to

talk about that later in the course but in this lesson i want to talk about

restoring a file to a previous version not on doing a commit so let's look at

our history all right so here's our history we want

to restore file one to the commit before the last commit

that is this comment over here so we type git restore now let's have a

quick look at the documentation the restore command

takes three types of arguments we can supply a bunch of options we can

still play a source we haven't done this so far so by

default git will restore that file from the next environment or the next

area so if the file you want to restore is in the working directory

git will restore it from the staging area and if the file is in the staging

area git will restore it from the last snapshot

or the last commit now in this case we want to change the default behavior

we want to restore a file from the commit before the last one

so we type git restore dash source we set it to head tilde 1

and then we specify the full path to the file in this case

file1.js now let's get a short status so we have a new untracked file so this

is how we can restore a file to a previous version hey guys bosh here as i said before this

video is the first hour of my complete git mastery course

the complete course is 5 hours long and covers intermediate to advanced

level concepts it comes with a certificate of completion

downloadable summary notes and a 30-day money-back guarantee

so if you're not happy you can ask for a refund you will learn all about browsing

history branching and merging collaborating with

others using git and github and rewriting history so by the end of

this course you would be able to use git like a pro

and work effectively with others in your team if you're interested click on the

link below this video to enroll