Working with Git and GitHub is often an essential part of your daily programming tasks. In many cases,
you'll want both a local Git repository and a remote GitHub repository for a project.
- With the local repository, you work on your own copy of the project.
- You make and test changes independently before pushing those changes to the remote repository for
others to review and merge.
-
You use the remote repository for offsite storage and to share the project with others.
What Do Git, GitHub, and Repository Mean?
A repository, or "repo" for short, stores and tracks the versions of your project files. As you
make changes to those files, you commit (or copy) those files into the repository for safekeeping. The
repository keeps a list of all your committed changes, called a commit history.
Git is a popular and widely used version control system for creating and working with
repositories. It runs locally on your computer. You can download, install, and use Git on any platform
without any cost or fees. With Git, you create a local repository in your project's working folder and
Git stores the commit history for the files in that folder.
Git Installation
For Git installation on Linux, macOS, and Windows, please follow the platform-specific instructions
below:
Linux:
Install Git on Debian-based systems like Ubuntu:
$ sudo apt-get update
$ sudo apt-get install git
macOS:
Install Git using Homebrew:
$ brew install git
Windows:
Download and install Git from git-scm.com.
After installation, verify with:
$ git --version
Git Configuration
If you're new to Git, configuring your identity is an essential step. This helps Git attribute your
commits correctly. Follow these steps:
- Open a terminal or command prompt.
- Set your name using the following command:
$ git config --global user.name "Your Name"
- Set your email address using the following command:
$ git config --global user.email "youremail@example.com"
These configurations are global, applying to all your Git projects. You can also set project-specific
configurations by omitting the "--global" flag.
Git Init
If you have a directory (folder) and you want to use git with it. Follow these steps:
- Navigate to your directory.
- Open the terminal.
- Run
git init and that's it.
Now, if you look back at the directory and enable hidden files to become visible (ctrl + h on linux),
you'll see a folder called .git which means that this folder is now a git repository and
you're ready to go!
You don't have to worry about that hidden folder. Basically, Git will use it to store information about
your repo but you don't need to touch it.
If you remove it, the folder is no longer a git repo and all commits will be removed.
Git Clone
If you're new to Git and want to start working on an existing project hosted on a remote repository
(e.g., GitHub), you'll need to use the "Git Clone" command. This command allows you to make a local copy
of the entire project on your computer. Here's how to do it:
- Open a terminal or command prompt.
- Decide where you want to store the local copy of the project on your computer. Navigate to the
directory where you want the project to be saved using the terminal. For example:
$ cd /path/to/your/preferred/directory
- Now, you're ready to clone the project. You need to know the URL of the remote repository. If you're
using GitHub, you can find it on the repository's page. Run the following command, replacing
"repository-url" with the actual URL:
$ git clone repository-url
Here's what each step does:
- The "Git Clone" command tells Git to create a local copy of the remote repository.
- You navigate to the directory where you want the project to be saved to ensure that the clone is
placed in the right location on your computer.
- By providing the repository's URL, you specify which project you want to clone. Git will download
all the project files, history, and branches to your computer.
Once the cloning process is complete, you'll have a local copy of the project on your computer, and you
can start working on it. You can make changes, create branches, and later use "Git Push" to send your
changes back to the remote repository for collaboration with others.
Remember that "Git Clone" is typically used when you want to start working on a project that already
exists. It's a great way to get involved in open-source projects, collaborate with a team, or simply
work on your own projects.
Git Add
git add is one of the most important commands. Let's understand how it works.
First, let's create a new Git repo using git init command.
I'll create a new git repo called example in desktop (I'm using Linux, but Git commands
should be the same on any OS):
$ mkdir example
$ cd example
$ git init
Now, Run:
$ git status
You should get an output similar to this:
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)
Let's create a new file called file1.txt:
$ touch file1.txt
Run in your terminal:
$ git status
You should get something like that:
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
file1.txt
nothing added to commit but untracked files present (use "git add" to track)
As you can see, we now have untracked files (well, it's actually just one
file) and Git is telling us
to use git add command to include an untracked file (or files)
and track it.
So, let's do that:
$ git add file1.txt
Run:
$ git status
Output:
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: file1.txt
As you can see, Git is telling us to commit changes now. But
hey what did the command
git add do?
Well basically, it adds the file(s) you pass to it to the
Staging Area. So our
file1.txt is now in the Staging Area (well
actually it's a copy of the
file). But what's the
Staging Area?
Git uses two important areas to function:
- Working Directory (Also known as
Working Tree).
- Staging Area (Also known as Index).
Working Directory is the directory your currently working on
(in our case, it is example).
Easy, right?
Now, let's talk about the Staging Area. You can think of it
as a box.
We know that a box contains some random things like books.
In Git, the box contains
files. So, our box was empty. When we did:
$ git add file1.txt
We added a copy of
file1.txt to the box (Staging Area). Ok got
it Staging
Area is a box that contains copies of files that exist
in our Working Directory but what's the point of
it?
Why do we store things in a box? So, we can use
them later if we need to!
The same thing applies to Git! We can recover the
content (or just some content) of a box and change our
Working Directory when needed (For example, when we make
a mistake).
We can add as many files as we want like this:
$ git add file1.txt file2.html ...
Or add them all at once:
$ git add .
Now all we need to do is to
commit the box and we're done!
Read the next section to
learn how to do so.
Git Commit
Let's continue our Git journey using the example folder we created in Git
Add section 🤠!
As we saw in Git Add section, the command git add is used to add copies of files in
the Staging Area (Or a box if that makes sense to you).
Imagine that you have some books that you want to store in boxes. You have
books about science, physics, math, history....
How would you store them? Well obviously, store each book according to its kind (science, math...) in a
specific box
But what if we just store books randomly without organizing them and after, say, one year I want to read
a
specific book? Oh no, there are many boxes and you will take so long to find just that one book.
However, if
we, for example, put a ticket on each box and say this box is for science and this one is for math... it
will be easy to find our target!
That's exactly what commmits are! Basically, tickets that hold messages so we can find
our copies of files easily if we need to!
Remember that we still have a copy of file1.txt in the Staging Area that we added using
git add file1.txt.
Now to finish our current box that contains this copy, we need to commit it using
git commit command like so:
$ git commit -m "Create a new file"
You can replace the message "Create a new file" with any one you wish like "First
commit"
but it's best to choose a name depending on the changes you've made (in this case, creating a new
file).
It's a convention to use a verb in the present simple as the first word like I did.
-m is called a flag. If you don't specify it, Git will open an editor
and
you'll
be able to
choose the message there as well as an optional explanation to why you did these changes.
There are many flags you can use with different Git commands but for now, let's not worry about
them.
Now we have a new box (More correctly, a commit) in our Git
History
(just like your browser's history).
Run in your terminal:
$ git log
You should get an output similar to this:
commit edee7b7362e47751f6ace4507cd2fc1686f57966 (HEAD -> main)
Author: <username> <somegithub@gmail.com>
Date: Thu Oct 5 22:00:16 2023 +0100
Add a new file
As you can see, this is our new created box. Date is the creation date.
Author
is the username and github email of the creator (I used fake ones here) that were set using
git config command. Also the text
edee7b7362e47751f6ace4507cd2fc16 is
called a hash. It's actually what we'll be using and not the message when
we want to go
back to some
specific commit (or a box).
NOTE: Every commit has a unique hash and that's how Git
exactly
differentiate between them.
Ok, Let's practice more:
- Write any text inside
file1.txt.
git add it.
git commit it with a message of "Write some text" or anything.
- Now create two new files
file2.txt and file3.txt.
git add them.
git commit with a message of "Create two new files" or whatever using
git add file2.txt file3.txt or both at once: git add ..
- Now
git log Git History.
As you can see, Git organizes our work and remembers changes we've made over time so we
don't get lost
and we can add features safely in our apps without worrying about losing current progress
since we can
just recover data from old commits.
Git Reset
Let's recap what we have learnt so far:
git add is used to add copies of files that were recently created or edited from
Working
Directory to the Staging Area.
git commit is used to commit (In other words, add to Git History) these changes that
were added to the Staging Area.
- Remember: first
git add and then git commit.
git log lets us check Git History.
Ok. Now, let's learn a new command: git reset!
Let's create a new Git repository called foo:
$ git init foo
$ cd foo
Next, create a new file called hello.txt:
$ touch hello.txt
Write in the new file (We'll make typos on purpose and let's assume we did not notice it):
Hello World! I'm a nw prgramer!
Let's add the file to the Index (Staging Area) and commit:
$ git add .
$ git commit -m "Create hello.txt and write some text in it"
Now let's create a new file called bye.txt, add it, and commit the changes:
$ touch bye.txt
$ git add .
$ git commit -m "Create bye.txt"
So now your Git History should look like this:
commit 45cdf54583460c091faa106e201e2bc6a1ef99a6 (HEAD -> main)
Author: <username> <somegithub@gmail.com>
Date: Fri Oct 6 10:36:29 2023 +0100
Create bye.txt
commit ffe5e5ebf54223dcea4dbe661b0256f912bd9350
Author: <username> <somegithub@gmail.com>
Date: Fri Oct 6 10:31:43 2023 +0100
Create a file and write some text in it
Only at this point, we've realized that we made wrong changes in the first
commit!
we realized that our hello.txt's text is not what was supposed to
be!
Thankfully, Git offers commands to fix this issue. We can, for example, just
edit the file and then use
git add and git commit with a message of "Fix a typo"
or whatever. This is the
safe (and recommended) way since it doesn't delete current commits
Or we can go the unsafe way using something like
git reset.
This command basically deletes as much commmits as we want! Let's try it:
- Run in your terminal:
$ git log
- Now, look for the commit that holds our changes which is the first one
in our case:
commit ffe5e5ebf54223dcea4dbe661b0256f912bd9350
Author: <username> <somegithub@gmail.com>
Date: Fri Oct 6 10:31:43 2023 +0100
Create a file and write some text in it
- Copy that commit's hash. Mine is:
ffe5e5ebf54223dcea4dbe661b0256f912bd9350
- Run (replace my hash with yours):
$ git reset ffe5e5ebf54223dcea4dbe661b0256f912bd9350
Running this command will delete every commit
after this one (In our case, just
"Create bye.txt" commit).
Now if you run git log, you can see "Create bye.txt" commit has
been deleted and our old
commit is the new HEAD (Don't worry about the HEAD for
now, we'll cover it in
upcoming lessons).
You may have noticed that our Working Directory hasn't changed. That's because
we didn't add
--hard option, which tells Git to undo the changes we've made after
our target commit as if
we never made them in the first place. So, in this case, our command is:
$ git reset ffe5e5ebf54223dcea4dbe661b0256f912bd9350 --hard
NOTE: This command won't delete untracked files (an
untracked file is a file that
was never before added to the Staging Area) because Git doesn't know they exist
until you
git add them at least one time.
If we don't specify any option, the default is --mixed, which
tells Git to keep changes
but clear the Index (Staging Area). That means any file we
git added will
be removed from Index.
There's also --soft option, which is like --mixed
but doesn't clear the Index.
Usually, you would use --hard option more frequently than the
other two.
Another way to use git reset is:
$ git reset HEAD~<number_of_commits_to_remove>
So, in our example, we could do:
$ git reset HEAD~1 --hard
Which does the same thing.
Another use for git reset is to remove files from the Index like:
$ git reset file1.txt file2.txt ...
Or using the "all" syntax:
$ git reset .
Remember:
--hard deletes all changes and clear the Index.
--mixed keeps changes and clear the Index.
--soft keeps changes and the Index as they are.
BIG WARNING: Never ever git reset
commits made by other developers
unless you let them know you want to do so. That's
because, it will cause complex
merging
conflicts that can be hard to solve and
developers will have hard times looking at
Git History since this command deletes commits and that's why
it's unsafe. Instead, prefer
to use git revert <hash> which is a safe
way to undo changes. It achieves
that by undoing them and adding a new commit without affecting any
existing commits. If the commits are
made by you, then
it's perfectly fine to use git reset.
Git Push
After making changes to your local repository and committing them, you'll want to push those changes to a
remote repository (e.g., on GitHub). This ensures that your changes are available to others. Follow
these steps:
- Open a terminal or command prompt.
- Navigate to your local repository directory using the terminal.
- Run the following command to push your changes to the remote repository:
$ git push origin branch-name
If you're not sure which branch to push, the default branch is usually named "main." You can omit the
branch name, and Git will use "main" by default. This command will upload your changes to the remote
repository, making them accessible to your collaborators.
Git Pull
If you're collaborating with others and they have made changes to the remote repository, you'll want to
update your local repository to include those changes. Use the following steps:
- Open a terminal or command prompt.
- Navigate to your local repository directory using the terminal.
- Run the following command to pull changes from the remote repository:
$ git pull origin branch-name
If you're not sure which branch to pull, the default branch is usually named "main." You can omit the
branch name, and Git will use "main" by default. This command will fetch the latest changes from the
remote repository and merge them into your local branch, ensuring your repository is up to date with the
latest changes.
Here are some useful references: