Skip to main content

Complete Git Tutorial – All You Need to Get Started

This Git tutorial will take you through everything you need to use Git like a pro.

Git is a Distributed Version Control System (DVCS) used to save different versions of a file (or set of files), wherein any version is retrievable at will.

Git makes it easy to record and compare different file versions. Consequently, details about what changed, who changed what, or who initiated an issue are reviewable anytime.

note

Git is not equivalent to GitHub.

Git is a version control system, while GitHub is a version control hosting service for hosting .git repositories.

You can learn more about the differences between the two technologies in the Git vs. GitHub article.

What Is a Version Control System?

A Version Control System (VCS) refers to the technique people use to save a file's versions for future reference.

Intuitively, many people already version control their projects by renaming different versions of the same file in various ways like blogScript.js, blogScript_v2.js, blogScript_v3.js, blogScript_final.js, blogScript_definite_final.js, and so on. However, this approach is error-prone and ineffective for team projects.

Moreover, tracking what changed, who changed it, and why it got changed is a tedious endeavor. Thus, the importance of a reliable and collaborative version control system like Git.

What Git Is Not

Git is not a Local Version Control System (LVCS) that saves file changes in a unique format on a local hard disk without collaborative support.

It is also not a Central Version Control System (CVCS) that centrally stores all its versioned files on a single server.

note

A Central Version Control System supports collaboration.

What Git Is

Git is a Distributed Version Control System (DVCS) that allows clients to clone an entire project's repository onto their disk.

In other words, Git enables storing and manipulating a file's versions on multiple servers (computers).

So, if a server dies, the project's repository is still retrievable from another server with a copy.

Additionally, many DVCS—including Git—have remote repositories (an online folder) that foster collaborative work on projects with anyone, anywhere, anytime.

But what exactly is the difference between remote repos and local repositories? Let's find out.

Remote vs. Local Repositories: What's the Difference?

Remote repositories are like any local directory—they are just folders.

The main difference between the two repositories is that only the person with the system can access a local repository.

However, a remote repository—located on an open platform like the internet—is accessible by anyone, anywhere, anytime.

As such, remote repositories facilitate dynamic collaboration on projects.

note
  • The term "remote" means "elsewhere"—not "online." Therefore, a .git directory duplicated to a location "elsewhere" on your local system is still a remote repository. Moreover, regardless of the type of remote repository, all the standard push, pull, and fetch operations are still applicable.
  • The Git local repository—automatically named .git—is a hidden folder where Git stores all recorded versions of your project's files.

Let's now discuss the three states of a Git file.

What Are the Three States of a File in Git?

The three primary states (conditions) of a file in the Git version control system are:

  • Modified
  • Staged
  • Committed

What is a modified file state in Git?

A file in the modified state is a revised—but uncommitted (unrecorded)—file.

In other words, files in the modified state are files you have modified but have not explicitly instructed Git to monitor.

What is a staged file state in Git?

A staged file is a modified file you have selected in its current state (version) in preparation for being saved (committed) into the .git repository during the next commit snapshot.

Once you stage a file, it implies that you have explicitly authorized Git to monitor that file's version.

What is a committed file state in Git?

Files in the committed state are files successfully stored in the .git repository.

In other words, a committed file is one in which you have recorded its staged version into the .git directory (folder).

note

The state of a file determines the location Git will store it.

Where Does Git Store Your Files?

The three key places versions of a file may reside while version controlling with Git are:

  • The working directory
  • The staging area
  • The .git directory.

What is a working directory?

The working directory is a local folder for a project's files.

In other words, any folder you create anywhere on a system is a working directory.

note
  • Files in the modified state reside in the working directory.
  • The working directory is different from the .git directory. You create a working directory, while Git creates a .git directory.
  • Learn more about the differences between a working directory and a Git directory in the Git vs. Working Directory article.

What is the staging area?

The staging area is a file Git uses to store details about files it is about to commit into the .git directory.

note
  • Files in the staged state reside in the staging area.
  • The staging area is technically called "index" in Git parlance.
  • The staging area is usually in the .git directory.

What is a Git directory?

The .git directory is the folder Git creates inside the working directory you have instructed it to track.

The .git folder is where Git stores the object databases and metadata of the file(s) you have instructed it to monitor.

note
  • The .git directory is the life of Git. It is the item copied when you clone a repository from another computer (or an online platform like GitHub).
  • Files in the committed state reside in the Git directory.

Let's now see what a basic Git workflow looks like.

The Basic Git Workflow

Working with the Git Version Control System looks something like this:

Git basic workflow
diagram

The basic workflow of files while version controlling with Git

Step 1

Modify files in the working directory.

note

Any file you alter becomes a file in the modified state.

Step 2

Selectively stage the files you want to commit to the .git directory.

note
  • Any file you stage (add) into the staging area becomes a file in the staged state.
  • Staged files are not yet in the .git database.
  • Staging puts information about the staged file in a file (called "index") located inside the .git repository.

Step 3

Commit the files you have staged into the .git directory.

In other words, permanently store a snapshot of the staged files in the .git database.

note

Any file version you commit to the .git directory becomes a file in the committed state.

So, now that we know Git's basic workflow, we can discuss how to use it.

How to Use Git

Before you can use Git, you need to install it on your system—so let's start with the installation process.

How to Install Git

You can easily install Git from the Git download webpage.

A handy way to check the version installed on your system is to run the following:

>_ Terminal
git --version

After the installation, it is necessary to keep it up to date whenever there is a new version.

How to Update Git

If you are using a Windows system and your currently installed Git version is 2.16.1 or higher, freely get the latest Git version with this command:

>_ Terminal
git update-git-for-windows

Once you have the correct version installed on your system, you can proceed with the setup process by initializing Git in your project directory.

How to Initialize Git

Initialization is to make Git ready to start monitoring files in a specified directory.

To initialize Git in a directory currently not under version control, you must first go inside that directory from your terminal.

>_ Terminal
cd path/to/the/directory

Afterward, initialize Git in that project's directory by running the following:

>_ Terminal
git init

After running the command above, the computer will create a Git repository named .git in the project's folder.

note
  • Initializing Git in a project does not mean Git is tracking anything in that project directory. The git init command creates the .git repository, where almost everything that Git stores and manipulates lives.
  • If you are curious about the contents in the .git directory, check the Plumbing and Porcelain doc.

After the installation and initialization process, the next step is to configure Git. So, let's do that now.

tip

Configuring your username and email address is essential because Git permanently bakes these details into your commits to help team members identify each commit's creator.

How to Configure Your Project's Git Username and Email

Here's the command to configure your username:

>_ Terminal
git config --global user.name "Your Name"

And here is the command to setup your email:

>_ Terminal
git config --global user.email "your-email@address.com"
note

The --global option enables you to run the above commands only once. However, if you are okay with inputting your name and email for each project, you can omit the --global flag.

Suppose you want to change a specific project's configured name or email address. How can you do this? Let's find out.

How to Change a Project's Git Username

You can change a project's username configuration by using the terminal to navigate into that project's directory and run the following command:

>_ Terminal
git config user.name "The New Name"

How to Change a Project's Git Email

You can change a project's email configuration by using the terminal to navigate into that project's directory and run the following command:

>_ Terminal
git config user.email "the-new-email@address.com"

Let's now see how to confirm your Git configurations.

How to Check Your Project's Git Configurations

You can view all your project's Git configurations by running the following:

>_ Terminal
git config --list

Suppose you wish to confirm the value stored for a single configuration (for instance, your email). In such a case, use the git config <key> command like so:

>_ Terminal
git config user.email
How to Exit the Git Configuration Space

Press the Q key on your computer's keyboard to exit the Git configuration space.

So, now that you know how to configure your username and email, we can discuss using Git to track your files.

How to Track Your Files with Git

To begin tracking files in an initialized folder, go into that project directory from the terminal and run:

>_ Terminal
git add <fileOrFolderName>

After running the command above, Git will add the specified file (or folder) to the staging area.

Once Git adds a file (or folder) to its staging area, it means Git has started monitoring that file's version for further modifications that may occur on it.

note
  • Ensure the files you want to monitor are in the working directory where you initialized Git.
  • Replace <fileOrFolderName> with the file (or directory) pathname.
  • Suppose <fileOrFolderName> is the pathname of a directory. In that case, the git add command will automatically add all the files in that directory into the staging area recursively.

Git provides some options you can use with the git add command to help speed up the staging process—especially when you have multiple files to stage. Let's discuss these options now.

What Are the Git Options for Staging Files Quickly?

The options developers commonly use to quicken the process of adding multiple files to the staging area are:

  • -A flag
  • -u flag
  • The . (dot) option
  • The * (asterisk) option

What does the -A flag mean when staging files in Git?

The -A flag is for staging all modified and untracked files in a project's entire working directory—regardless of the current project directory in which you are.

>_ Terminal
git add -A
note

The -A flag is the shorthand notation for the --all option. You can use any of the two flags to add all modified files to the staging area.

What does the -u flag mean when staging files in Git?

The -u flag is for staging only the modified files you previously committed.

>_ Terminal
git add -u
note
  • The -u flag will stage all modified files—currently being tracked—in the project's entire working directory. This staging will occur regardless of the project folder you are in presently.
  • -u flag will not add any new file (previously uncommitted files) to the staging area.
  • The -u flag is the shorthand notation for the --update option. You can use any of the two flags to update all modified files under version control.

What does the . (dot) option mean when staging files in Git?

The . (dot) option is for staging all modified and untracked files located only in the current project's directory in which you are.

>_ Terminal
git add .
note
  • The dot is essential in the add command above.
  • A dot symbol means current directory. So, the above command will only stage all modified and untracked files of that project directory wherein you invoked the command.
  • There must be a space between the add command and the dot (.) mark.

What does the * (asterisk) option mean when staging files in Git?

Although you can use the git add * command to stage multiple files. However, to prevent unexpected results, it is best to avoid using it.

Important Stuff to Know about Staging Files in Git

Here are two essential facts to remember whenever you stage files in Git.

1. Staging does not save your files

Whenever you stage your files, it does not imply saving them in the Git directory.

Staging implies that you have added details about your staged files into an "index" file in the Git directory.

2. Git commits only the files you've staged

Only the file versions in the staging area get committed to subsequent historic snapshots—not the working directory's versions.

In other words, whenever you run the commit command, Git will only save the file versions presently in the staging area—not the ones in your working directory.

Let's now discuss how to commit files to Git.

How to Commit Files to Git

Committing files to Git means storing the staged version of your working directory's files in the .git repository.

To commit a file that is currently in the staging area, run the following:

>_ Terminal
git commit -m "Write a message about the file(s) you are committing"

The -m flag allows you to write your message in-line with the commit command. If you omit it, Git will launch your text editor with comments prompting you to enter your commit message.

You can delete the editor's comments and type in your commit message. Or you can leave the comments and add your commit message.

Once you've finished writing your commit message inside the text editor, exit it so that Git can create the commit.

Writing commit messages with a text editor allows you to write long notes—even with multiple paragraphs. However, for short commit messages, the in-line method is sufficient.

Let's now discuss the three main parts of a Git commit message.

What Are the Three Main Parts of a Git Commit Message?

The Git commit message developers write in their text editor typically follow the same basic structure:

  1. Summary: Short description of the commit
  2. Body: Additional contextual description of the commit
  3. Footer: Metadata details about the commit, such as external links and issue reference
note
  • We use a blank line to separate one section from the other.
  • Suppose you omit the body. In that case, your footer can come immediately after the summary.

Syntax of a Git commit message

<summary>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

Example of a Git commit message

Use 50 characters or less to summarize the changes

Provide extra information about the changes you are committing. And you
should wrap this addon text at around 72 characters because Git does not
wrap text automatically. Although, some text editors, like VSCode, help
with text wrapping.

Remember that it is essential to use a blank line to separate each section
of your commit message (the summary, body, and footer).

It is okay to have multiple paragraphs in the body section. You can also
use bullet points. However, note the following:

- Precede each bullet point with a space

- Separate each bullet point with a blank line

- People typically use a hyphen or asterisk to indicate bullet points

The footer is the last part of a long commit message. Use it for issue
references, external links, and other metadata details like so:

Resolves: #35

Note the following:

  • We typically write the footer in a <word-token>: <string> format.
  • The <word-token> typically uses hyphens (-) instead of whitespace characters to separate words—except while indicating BREAKING CHANGE. This convention helps to differentiate the footer section from the body of a commit message.
  • You can use whitespace and newline characters in your footer's <string>.
  • You can use the BREAKING CHANGE text as your footer's <word-token>.

Important stuff to know about Git commit messages

Here are six essential facts to remember when writing your commit messages.

1. Standardize your commit message by specifying its type

The Conventional Commits specification recommends prefixing the summary section of your commit message with a type.

Here's the syntax:

>_ Terminal
<type>: <summary>

Here's an example:

>_ Terminal
fix: Use 50 characters or less to summarize the changes
note
  • <type> is a noun, such as fix, feat, and chore, that specifies the type of changes you are committing.
  • Always use a terminal colon (:) and a space after your commit message's type.
  • You can add a scope to the commit type to indicate the package or file where the change happened. Ensure you enclose the scope in parentheses—for instance, fix(readme): Correct typo in the title.
  • Developers sometimes reference the type, scope, and summary as the commit message's header.

2. There are 11 <type>s developers often use

The eleven <type>s developers typically use to categorize their commits are:

  1. build: for commits that impact your app's build step or external dependencies—for instance, an update to your NPM package.
  2. chore: for commits that implemented maintenance-related updates, such as updating your .gitignore file, or an existing API key.
  3. ci: for commits that modify your CI (continuous integration) configurations.
  4. docs: for commits that modify your project's documentation.
  5. feat: for commits that add a new feature to your codebase. This commit type is synonymous with a MINOR release in Semantic Versioning (SemVer).
  6. fix: for commits that add bug fixes to your codebase. This commit type is synonymous with a PATCH release in Semantic Versioning (SemVer).
  7. perf: for commits that improve your app's performance.
  8. refactor: for commits that refactor specific parts of your codebase—for instance, renaming a function.
  9. revert: for commits that revert your codebase to a previous commit history. You may also add the commit SHAs you are reverting to the footer as references—for instance, Refs: 7b804hrw, b394c306.
  10. style: for commits that modify your code's style, such as adding semi-colon, white-space, or indentation.
  11. test: for commits that modify your app's test code.

3. How to indicate breaking changes in a commit message

Suppose a specific commit includes breaking changes. In that case, you can indicate it through one (or both) of the following ways:

  • Append the commit type with an exclamation mark—for instance, fix!
  • Add a BREAKING CHANGE: text to the beginning of your commit message's body or footer section.

Here's an example:

feat!: Use 50 characters or less to summarize the changes

BREAKING CHANGE: Provide extra information about the changes you are
committing. And you should wrap this addon text at around 72 characters
because Git does not wrap text automatically. Although some text
editors, like VSCode, help with text wrapping.

Resolves: #71
Refs: codesweetly.com/how-to-use-git, codesweetly.com/git-cheat-sheet
note
  • Any commit type can include a breaking change.
  • A BREAKING CHANGE commit—regardless of its type—is synonymous with a MAJOR release in Semantic Versioning (SemVer).

4. How to write long commit messages in the terminal

Below is the command line syntax for writing your commit message's summary, body, and footer.

>_ Terminal
git commit -m "Write your summary" -m "Write your body" -m "Write your footer"
tip

Each -m flag tells git to begin a new paragraph.

5. How to view the changes you are about to commit

Suppose you use the text editor to input your commit message. In that case, add the -v flag to the git commit command like so:

>_ Terminal
git commit -v

By doing so, Git will include the diff of your changes in the editor so you can see the exact changes you are about to commit.

In other words, use the -v flag to include—at the bottom of the text editor's commit message template—the differences between what you are currently committing and your previous commit.

note

Git will not include the diff (at the bottom of your text editor's commit message template) in your final commit message.

The diff is only present to help you remember the changes you are about to commit, making crafting a good commit message easier.

6. It pays to draft a good commit message

Crafting a good commit message will help your collaborators (and yourself—after some time) understand why you committed a specific version of your project's files.

It will also help clarify differences between the file versions committed.

Suppose you wish to commit your changes without staging them first. In such a case, you can skip the staging area. Let's find out how.

How to Commit Files without Staging Them

You can skip the staging area while committing your files (that is, omit running the git add command) by adding an -a flag to your git commit command like so:

>_ Terminal
git commit -a

By so doing, Git will automatically stage all the files it is already tracking. After the automatic staging, it will then commit the files.

Suppose you do not want Git to monitor nor commit specific files or folders. How can you do this? Let's find out.

How to Tell Git to Ignore Specific Items

We use a .gitignore file to tell Git the files or folders it should ignore—including not listing them as untracked.

note

A common practice is to create the .gitignore file in a project's root directory.

Developers use the term "root directory" to reference the folder containing all other files and sub-folders of a specific project. In other words, a root repository is a working directory that houses everything concerning a particular project. As such, its content will also include the .git folder.

How to create a .gitignore file

To create a .gitignore file, go into the root directory where the files you want to ignore are. Then, run the command below in your terminal:

>_ Terminal
touch .gitignore

Let's now see how to specify the items you want Git to ignore.

How to specify the items you want Git to ignore

Open your project's .gitignore file and write the filenames, folders, or file types you want Git to ignore.

Here is an example:

.gitignore
# In a ".gitignore" file, an asterisk (*) is a wildcard symbol that
# means zero or more characters—but not a slash (/)—can replace
# the asterisk.

# The command below will ignore any document starting with "abc"
# located anywhere in this project:
abc*

# The command below will ignore all ".txt" filetypes located anywhere
# in this project:
*.txt

# In a ".gitignore" file, an exclamation mark (!) means "important."

# The command below will track "readme.txt" filetypes, even though
# you've instructed Git—through the asterisk command above—to
# ignore all ".txt" files:
!readme.txt

# The command below will ignore any "package-lock.json" file located
# anywhere in this project:
package-lock.json

# The command below will ignore only the "passwords.text" file
# located in the specified directory:
directory/of/passwords.text

# This command below will only ignore the "NOTE" file in the current
# directory—not in any other folder—of this project:
/NOTE

# The following command will ignore all the content inside any folder
# named "modules":
modules/

# This command below will ignore all ".txt" files directly inside the
# folder named "mix":
mix/*.txt

# Note that the command above will still track all ".txt" files that
# are in the subdirectories of the "mix" folder. For instance, it
# will ignore "mix/test.txt" but will track "mix/real/test.txt".

# In a ".gitignore" file, double asterisks (**) mark—followed by a
# slash (e.g., **/)—is a wildcard symbol that means zero or more
# directories' names can replace the double asterisks.

# The command below will ignore all ".pdf" files inside both the
# folder named "doc" and in any of its subdirectories:
doc/**/*.pdf

# The question mark (?) in the command below means any single
# character—except a slash—can replace the question mark:
sea?.txt

# As such, the command above will ignore files like "seas.txt" or
# "seat.txt". However, it will not ignore files like "seats.txt".

# In a ".gitignore" file, a pair of square brackets "[...]" specifies
# the range of characters acceptable for a single character position.
# Below are some examples.

# The command below means the character after character "n" can
# either be character "s" or character "t":
plan[st].js

# Therefore, the command above will match files like "plans.js" or
# "plant.js". But it will not match "plane.js" nor "plants".

# The command below means the character after character "n" can be
# any character between numbers "3 to 9" inclusive:
plan[3-9].js

# Therefore, the command above will match files like "plan3.js" or
# "plan5.js". But it will not match "plan10.txt" nor "plan1".

# The following command means the character after character "n" can
# be any character between letters "f to z" inclusive:
plan[f-z].js

# As such, the command above will match files like "plank.js" or
# "plany.js". But it will not match "plan2.txt" nor "plane".

# An exclamation mark within a square bracket "[!]" means "negate".

# The command below means the character after character "n" cannot be
# character "s" nor character "t":
plan[!st].js

# Therefore, the command above will match files like "plane.js" or
# "plan2.js". But it will not match "plans.js" nor "plant".
note
  • Git regards any line beginning with a hash symbol (#) as a comment.
  • A .gitignore file serves to ensure files that are currently untracked remain untracked. In other words, Git will not ignore any file it is already tracking—even if specified in a .gitignore file—unless you delete it from the staging area.

Viewing a project's commit history is a common practice while developing an app. So, let's discuss how developers do this.

How to View a Project's Commit History

You can view your project's commit history by running the following:

>_ Terminal
git log

After running the command above, if you get stuck on the Git console, just hit your keyboard's Q key to exit.

note

The project's directory—whose commit history you want to check—must be the current directory.

Below are some options you can use with the git log command.

FlagDescriptionExample
-3Limit the number of commit histories displayed to the last three entries.git log -3
-p (Short for --patch)

Display the diff (differences) introduced in each commit.

Note: The git log command displays only basic commit history details—such as the author, date, and commit message. So, adding the -p flag allows you to include the differences introduced in each commit.

git log -p
--color-words

Make the git log -p's output less cumbersome by only displaying each chunk's modified words and their context—not each modified line and its context.

git log -p --color-words
--abbrev-commitDisplay an abbreviated version of the commit hash instead of all 40 characters.git log --abbrev-commit
--prettyDisplay the default version of the commit history.git log --pretty
--pretty=shortDisplay the shorter version of the commit history.git log --pretty=short
--pretty=fullDisplay the full version of the commit history.git log --pretty=full
--pretty=fullerDisplay the fuller version of the commit history.git log --pretty=fuller
--pretty=onelineDisplay the one-line version of the commit history.git log --pretty=oneline
--pretty=oneline --abbrev-commitDisplay the one-line version of the commit history while also abbreviating the commit hash.git log --pretty=oneline --abbrev-commit
--onelineA shorthand version of --pretty=oneline --abbrev-commitgit log --oneline
--name-only

Display the names of the modified files.

Note: The git log command displays only basic commit history details—such as the author, date, and commit message. So, adding the --name-only flag allows you to include the names of the files you modified in each commit.

git log --name-only
--name-statusDisplay the names of modified files and their modification status (added, modified, or deleted).git log --name-status
--relative-dateDisplay the relative date format instead of the full date—for instance, 2 days ago.git log --relative-date
--statDisplay the statistic of the changes that occurred in each commit.git log --stat
--shortstatDisplay a brief statistic of the changes that occurred in each commit.git log --shortstat
--graphDisplay the "branch and merge" history's ASCII graph alongside the commit history.git log --graph

Let's now see how to compare a project's commit history.

CodeSweetly ads

Design in Figma, launch in Webflow

Bring your static designs to life with IX2, wire up content using our powerful CMS, and one-click publish onto the fastest hosting infrastructure.
Find out more

How to Compare the Commit History of Two Git Branches

You can compare the commit history of one Git branch with another like so:

>_ Terminal
git log first-branch-name..second-branch-name

The code above tells Git to compare the commit history of first-branch-name with second-branch-name.

Therefore, Git will log out the commits present in second-branch-name but not in first-branch-name.

Other Git Commands You Will Find Useful

Below are other handy Git commands.

How to check the status of your files

>_ Terminal
git status

How to check where Git got installed on your system

>_ Terminal
which git

How to compare the file version in the staging area with the most recent version committed into the Git directory

>_ Terminal
git diff --staged

The command above will show the difference between the file versions in the staging area and those most recently committed to the Git directory.

How to compare the version of files in the working directory with those you added to the staging area

>_ Terminal
git diff
note
  • The git diff command shows the changes in a working directory's files you've not yet staged.
  • By default, git diff will compare a working directory's file version with those in the staging area. However, for any file currently not in the staging area, git diff will compare the working directory's version with the one you last committed.
  • Suppose nothing shows after running the diff command above. In that case, it implies the same file version exists in the working directory and the staging area.
  • The git diff command does not show the entire content of a file. Instead, it displays only chunks.
  • To make the chunk less cumbersome, add the --color-words flag to the git diff command (that is, git diff --color-words). Thus, each chunk will include just the modified words (not lines) and their context.

How to confirm if a specific item is in the .git directory

>_ Terminal
git ls-files | grep <fileOrFolderName>
note
  • Replace <fileOrFolderName> in the command above with the name of the file (or directory) you want to check.
  • If nothing shows after running the command above, the specified file (or folder) is not in the .git directory.
  • The grep command is a helpful utility for searching for a specified pattern or characters and printing lines that match that pattern. For instance, git ls-files | grep test.js will look for and print lines that match test.js.
  • Check Git's grep documentation for additional options for the grep command.

How to open gitignore's manual page

>_ Terminal
git help gitignore
note

The gitignore manual will open in your default browser.

How to remove files from Git version control and the working directory

Use the following code to delete a file from your system and to stop Git from tracking the file.

>_ Terminal
git rm fileToDelete
tip
  • Add the -f flag to forcefully remove modified files (or files previously added to the staging area). For instance, git rm -f fileToDelete.
  • Add the -r flag to remove a folder—for instance, git rm -r folderToDelete.
note

Suppose you only run rm fileToDelete (excluding the git command). In such a case, the specified file will only get deleted from the working directory. Therefore, Git will still track it as an unstaged change.

However, running git rm fileToDelete will delete the specified file from the working directory and automatically stage the removal. As such, during the next commit, Git will delete the file from the .git directory.

How to remove files from Git version control only

Use the following code to stop Git from tracking a staged file.

>_ Terminal
git rm --cached fileToDelete
note

The command above will remove the specified file from the .git directory only. It will not delete the file from your working directory.

tip

Add the -r flag to stop tracking a staged folder—for instance, git rm --cached -r folderToDelete.

How to rename a file

Here's how to rename a file:

>_ Terminal
git mv currentFileName newFileName

How to skip writing a commit message

Suppose you made only minor modifications to your file and prefer not to write a commit message. In such a case, you can skip writing the commit text by adding the --no-edit option to your git commit command like so:

>_ Terminal
git commit --amend --no-edit

How to stage and commit at once

Here's how you can stage and commit your file at once:

>_ Terminal
git add <fileOrFolderName> && git commit -m "A message about your commit"

How to undo a commit

Suppose you wish to undo a specific commit. In such a case, run:

>_ Terminal
git revert <commit-to-undo>

The snippet above tells Git to create a new commit that reverts the changes introduced in <commit-to-undo>.

note
  • The git revert command does not delete any data. Instead, it creates a new commit that reverses the changes added to the specified commit.
  • After committing the reverted changes, the HEAD pointer will move to the new commit.
  • In the snippet above, replace <commit-to-undo> with the commit you wish to undo—for instance, git revert b91ey04.
  • Use a --no-commit (or -n) flag to stop Git's default behavior of automatically committing the reverted changes. The --no-commit flag will put the reverted changes in your working directory for you to edit further and commit manually.
  • Suppose you wish to use git revert's default commit message. In that case, add the --no-edit flag to the command—for instance, git revert b91ey04 --no-edit. By so doing, Git will not prompt you to provide a commit message for the reverted commit.

How to undo the pushing of a commit upstream

You can undo a commit you've recently pushed to a remote repository by running:

>_ Terminal
git revert HEAD
git push origin main

The snippet above tells Git to do the following:

  1. Create a new commit that reverts the changes made in the HEAD commit. (Note: The HEAD commit means your recent commit.)
  2. Push the local branch (named main) to the remote branch (origin).

How to undo the staging of a specific file in the staging area

Here's how to remove a specific file from your project's staging area:

>_ Terminal
git reset HEAD fileToUnstage

The command above can be dangerous if you add a --hard flag.

However, using git reset without the --hard flag makes it a non-destructive tool that would not change any file in your working directory.

Alternatively, you can also use:

>_ Terminal
git restore --staged fileToUnstage

How to undo the staging of all files in the staging area

Here's how to undo the staging of all the files in the staging area:

>_ Terminal
git reset

How to view all the files currently in the staging area and the .git repository

>_ Terminal
git ls-files
note

Git's ls-files doc contains additional options for the ls-files command.

How to write text into a file via the terminal

>_ Terminal
echo textToWrite >> fileToWriteInto
note
  • >> will append your text to the end of the file's content.
  • > will overwrite any existing content of the specified file.
  • Suppose you wish to use symbols, such as an exclamation mark (!). In that case, prepend each with a backslash (\) mark. In doing so, Git will analyze the character as a text—not a command.

Here's an example:

Write "Hello!!!" into a file via the command line:

>_ Terminal
echo Hello\!\!\! >> fileToWriteInto

Dangerous Git Commands

Commands that permit you to undo changes are generally dangerous because they can permanently delete your work—if you do it wrongly!

Therefore, be super careful with these commands!

How to amend your last commit

Suppose you forgot to include something in your last commit—for instance, a file. In that case, do the following:

  1. Use the git add <fileName> command to stage the missing content.
  2. Run the following code:
>_ Terminal
git commit --amend

After you've invoked the snippet above, a COMMIT_EDITMSG file will open, prompting you to update your previous commit message.

You can choose to update the previous commit message or retain it.

Once you've decided on the message to use, exit the COMMIT_EDITMSG file so that Git can create the commit.

Afterward, Git will automatically replace your last commit with this updated version.

warning

Use the --amend command cautiously—as amending a commit changes the commit's SHA-1. --amend replaces an old commit with a new one.

Therefore, to avoid confusing other collaborators, you shouldn't amend any commit you have pushed (shared)!

In other words, amend only the commits that no one has pushed anywhere. Otherwise, you may destroy a commit on which other developers rely.

How to forcefully push to a remote repository

You can forcefully overwrite a remote repository with your local .git repo by running the following:

>_ Terminal
git push --force

By so doing, Git won't ask you to update your local branch before pushing to the remote repo.

In other words, Git's default setting compels you to update your local branch with the latest commits of the remote repository to which you wish to push.

However, the --force flag allows you to override Git's default configuration.

Keep in mind that git push --force is a dangerous command because:

  • It makes it easy to erase commits your collaborators recently pushed to the remote repo.
  • The local repo you are moving upstream will replace any old commit on which your colleagues' new work still relies.
note
  • Consider using --force-with-lease instead of the --force flag. --force-with-lease will alert you if someone has updated the remote repository since you last fetched.
  • Using git revert is a safer way to undo a commit you've pushed to a remote repository. It is a non-destructive command that does not rewrite commit histories.

How to rebase Git commits

Git rebasing is a technique used to change the base of a specific commit from one branch to another.

In other words, Git rebase allows you to cut off one branch's commit and reapply it to another.

The three main things people do with the git rebase command are:

  • Modify a previous commit message
  • Merge multiple commits
  • Delete redundant commits
warning

Use the rebase command cautiously—as amending a commit changes the commit's SHA-1.

rebase replaces an old commit with a new one. Therefore, to avoid confusing other collaborators, it's best not to rebase any commit you have pushed (shared)!

In other words, rebase only the commits that no one has pushed anywhere. Otherwise, you may destroy a commit on which other developers rely.

Let's discuss some helpful ways to use the rebase command.

How to modify a previous commit message

Suppose you wish to amend a previous commit message. In that case, use the rebase command like so:

>_ Terminal
git rebase -i HEAD~2

The snippet above tells Git to begin an interactive rebasing session from the two previous commits.

note
  • The -i flag is the shorthand notation for the --interactive flag. You can use any of the two flags to begin an interactive rebasing session.
  • The interactive tool allows you to stop after each commit in the specified series (the previous two in the case of our snippet above). You can add files at each stop, change the commit's message, or do whatever else you wish to do.
  • HEAD~2 tells Git to rebase onto the parent of the last two commits. In other words, we instructed Git to rewrite commits as far back as the previous two.
  • HEAD~2 is equivalent to HEAD~1^. You can use any of the two arguments to rebase onto the parent of the last two commits.
How to edit any commit message from the first one

You can start your interactive rebasing session from the first commit like so:

>_ Terminal
git rebase -i --root

Once you've invoked the interactive rebasing command, a git-rebase-todo file will open in your text editor. The file will look like this:

git-rebase-todo
pick 324c9db Create index.html file
pick 1d0923a Create Addition component

# Rebase 5b8c120..1d0923a onto 5b8c120
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
# commit's log message, unless -C is used, in which case
# keep only this commit's message; -c is same as -C but
# opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified); use -c <commit> to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
note
  • Interactive rebase lists commit from the oldest to the newest—rather than git log's way of listing from the most recent to the oldest.
  • To delete a commit, delete it from the list of commits in the git-rebase-todo file.
  • To reorder your commits, swap their positions in the git-rebase-todo file.

The opened file allows you to specify the commits where the script should stop so that you can edit the previous commit message.

For instance, suppose you only need to modify 324c9db commit's message. In that case, you would change 324c9db's pick command to edit like so:

git-rebase-todo
edit 324c9db Create index.html file
pick 1d0923a Create Addition component

Then, you would save and close the git-rebase-todo file.

Afterward, Git will go back to the 324c9db commit and drop you a piece of information on the command line that looks like this:

>_ Terminal
$ git rebase -i HEAD~2
Stopped at 324c9db... Create index.html file
You can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue

In other words, run git commit --amend to modify 324c9db commit's message. Then use git rebase --continue to finish the rebase process.

How to squash commits

The interactive rebase tool lets you squash (merge) two or more commits together.

For instance, suppose you began an interactive rebasing session from your project's root commit like so:

>_ Terminal
git rebase -i --root

Let's now assume that after running the snippet above, a git-rebase-todo file opened with four commit histories similar to this:

git-rebase-todo
pick 7e8525d Create project directory
pick 5b8c120 Initialize NPM
pick 324c9db Create index.html file
pick 1d0923a Create Addition component

You can merge the two most recent commits with the third one by changing the word pick to squash like so:

git-rebase-todo
pick 7e8525d Create project directory
pick 5b8c120 Initialize NPM
squash 324c9db Create index.html file
squash 1d0923a Create Addition component

Once you save and close the git-rebase-todo file, a COMMIT_EDITMSG file will open, prompting you to merge your previous commit messages.

In other words, your COMMIT_EDITMSG file would look like this:

COMMIT_EDITMSG
# The first commit's message is:
Initialize NPM

# This is the 2nd commit message:
Create index.html file

# This is the 3rd commit message:
Create Addition component

You need to merge the three commit messages.

Here's an example:

COMMIT_EDITMSG
# This is a combination of 3 commits.
Create package.json, index.html, and Addition.js files

Afterward, save and close the COMMIT_EDITMSG file so that Git can finish the squashing process.

How to split a previous commit

The interactive rebase tool allows you to split a previous commit into multiple commits.

For instance, suppose you began the interactive rebasing session from your project's root commit like so:

>_ Terminal
git rebase -i --root

Let's now assume that after running the snippet above, a git-rebase-todo file opened with three commit histories like this:

git-rebase-todo
pick 5b8c120 Initialize NPM
pick 324c9db Create index.html and style.css files
pick 1d0923a Create Addition component

You can split the middle commit (324c9db) into two different commits.

In other words, you can split Create index.html and style.css files into two commits: the first will use "Create index.html file" as its commit message, and the second will use "Create style.css file".

Here are the steps required to split your previous commit:

1. Change pick to edit

Change the pick command to edit for the commit you wish to split.

Here's an example:

git-rebase-todo
pick 5b8c120 Initialize NPM
edit 324c9db Create index.html and style.css files
pick 1d0923a Create Addition component

Save, and close the git-rebase-todo file once you've changed the command.

Afterward, Git will go back to the 324c9db commit and drop you a piece of information on the command line that looks like this:

>_ Terminal
$ git rebase -i --root
Stopped at 324c9db... Create index.html and style.css files
You can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue
2. Reset the commit

At this stage, reset the commit to the one before the HEAD pointer like so:

>_ Terminal
git reset HEAD^

The snippet above will move the HEAD pointer to the commit before the one you wish to split.

In other words, the git reset command will update your project's staging area with the content of the commit right before the one you want to split.

Therefore, you can now create and commit new files individually.

note
  • Suppose you do not want git reset to update your staging area. In that case, add a --soft flag to the command—for instance, git reset --soft HEAD^. By so doing, Git will only move the HEAD pointer to the previous commit while leaving the staging area untouched.
  • Suppose you want git reset to move the HEAD pointer, update your staging area, and update your working directory. In that case, add a --hard flag to the reset command—for instance, git reset --hard HEAD^.
  • A hard reset operation is a destructive command that will overwrite your working directory's files. Therefore, use it cautiously.
3. Stage and commit files

Once you've reset your HEAD pointer, you can begin to stage and commit files.

For instance, you can split "Create index.html and style.css files" into two commits by staging and committing them like so:

>_ Terminal
git add index.html
git commit -m "Create index.html file"
git add style.css
git commit -m "Create style.css file"
4. Finish the rebase process

When you've finished splitting your previous commit, end the rebase process by running the following:

>_ Terminal
git rebase --continue
note

Git changes the SHA-1s of all the commits following a rebase change. Therefore, ensure you've not pushed any of those commits to a shared repository.

How to replace a working directory's file with the last committed or staged version

>_ Terminal
git checkout -- localFileToDeleteAndReplace

Alternatively, you can also use:

>_ Terminal
git restore localFileToDeleteAndReplace
warning

The two commands above are dangerous commands that will permanently delete all the changes in the local version of the specified file.

In other words, Git will replace your local file with the last committed or staged version.

How to Share a Git Repository

Sharing a Git repository online makes it easy for collaborators to collaborate on a project from anywhere, at any time.

Moreover, GitHub—a popular online platform used for sharing .git repositories—takes Git collaboration to a whole new height.

To share your Git repository (your project's committed file versions) on GitHub, follow this How to Host a Git Repository on GitHub guide.

How to Clone a Git Repository

Git Cloning is mainly about getting (downloading) a copy of a .git repository.

For instance, you may need a copy of a project you intend to modify. In such a case, getting a clone of the project's .git directory puts in your possession all the file versions the project's contributors have committed to the .git repository.

To clone a repository, run the following:

>_ Terminal
git clone <theGitRepoURL> <state the place to put the cloned git folder>

By so doing, Git will download a copy of the specified .git repository into the place you've identified.

note
  • Replace <theGitRepoURL> with the URL of the .git directory you want to clone.
  • Substitute <state the place to put the cloned git folder> with your system's location, wherein you want the cloned .git repository to reside. (If omitted, Git will use your current directory as the default clone location.)
  • Whenever you clone any remote repo, Git automatically names that repo's URL "origin". However, you can specify a different name with the git clone -o yourPreferredName command.

Overview

This article discussed all you need to get started with Git.

Useful Resources

Below are links to other valuable content on how to use Git.

FREE Git Cheat Sheet!

Get the CodeSweetly free Git PDF cheat sheet.

Use it to easily remember the Git commands you need for your projects.

Download Now

Your support matters: Buy me a coffee to support CodeSweetly's mission of simplifying coding concepts.

Join CodeSweetly Newsletter