Version control with Git
Git is an open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. This tutorial shows how to install and use Git in a local computer and connect to a remote repository on GitHub or GitLab. The following are great sources to learn more about Git:
Installation
Depends on the operating system, it might be needed to install Git first. Computers with Windows operating systems do not automatically have a Unix Shell installed. So for Windows users, it would be better to install Git for Windows, which gives you access to both Bash Shell and Git simultaneously.
When we use Git for the first time, its better to configure user name and email by:
$ git config --global user.name "your name"
$ git config --global user.email "your@email"
This will set your name and email address to all activities
associated with Git. We can find the list of adjusted configurations
by git config --list
and to see more helps by
git config --help
.
Git commands
As a prerequisite, first learn about the Unix Shell and basic Bash commands.
Let’s start working with Git on your local computer with an example. First, we will make a directory and then initiate a Git repository in the directory, and then start to add a text file and edit the file.
Open a terminal prompt and run the following commands one by one, read the comments after hash to see what they do.
cd ~ # change directory to home/
mkdir first_repo # create a new directory called "first_repo"
cd first_repo # change directory to home/first_repo
git init # create an empty Git repository (after that Git could track all changes in this directory)
git status # show the working tree status which tells "nothing to commit"
nano file.txt # nano text editor will create "file.txt" and open the file. Let's add the following:
>Hi! this is the first line in my new repository. # press ctrl+o to save and ctrl+x to exit
git status # say "nothing to commit but untracked files present"
To record all changes by Git, we need to:
- Add file contents to the index by
git add
- Record changes to the repository by
git commit
Use the following commands for the above steps:
git add file.text # add file contents to the index
git status # show changes to be committed
git commit -m "Add file.txt and write the first line" # record changes to the repository, -m option add message
git show file.txt # show the most recent commit of "file.txt"
git log # show the commit logs
Let’s make some changes in the first_repo
directory to
see how Git records changes:
nano file.txt # nano will open "file.txt"
>Hi! this is the first line in my new repository.
>Changes in this file will record by Git. # press ctrl+o to save and ctrl+x to exit
git status # show changes not staged for commit
git diff file.txt # show changes between most recent commit and the current "file.txt"
Use the following to record above changes by Git:
git add file.txt
git commit -m "Add the second line"
git show file.txt # show the most recent commit of "file.txt"
git show HEAD~1 file.txt # show the previous commit of "file.txt"
Also, we can compare changes between the current version and
previous versions. Let’s make some more changes on the
file.txt
to see how we can compare all versions:
nano file.txt # nano will open "file.txt"
>Hi! this is the first line in my new repository.
>Changes in this file will record by Git.
>This changes are new. # press ctrl+o to save and ctrl+x to exit
git diff file.txt # show changes between the most recent commit and the current "file.txt"
git diff HEAD~1 file.txt # show changes between the previous commit and the current "file.txt"
Record new changes by:
git add file.txt
git commit -m "Add the third line"
git show file.txt # show the most recent commit of "file.txt"
git show HEAD~1 file.txt # show the previous commit of "file.txt"
git show HEAD~2 file.txt # show the previous previous commit of "file.txt"
We always can restore previous versions of our work. Let assume
that we want to restore the previous version of
file.txt
:
cat file.txt # show the content of the file
git show HEAD~1 file.txt # show the previous commit (we want to restore this version)
git checkout HEAD~1 file.txt # restore the previous version
cat file.txt # show the content of the file
Again record new changes by:
git add file.txt
git commit -m "restore the previous version"
Also, we can unstage an added file by using reset
command:
git add file.txt
git reset file.txt # unstage added file
Note: reset
, checkout
and revert
all let us undo changes in a repository. Learn
more about them in here.
Your local computer might be one side of your mechanism to control
and store your file versions. GitHub
and GitLab are providing an
infrastructure to keep track of our files in somewhere outside the
local computers. Let’s connect to GitHub through SSH and add
first_repo
repository to it.
To connect your GitHub (or GitLab) account through SSH, you should
generate a public SSH key on your local computer and add it to your
GitHub account at Settings > SSH Keys
. To do that open
a terminal prompt in your computer and issue:
cd ~
ssh-keygen
Make sure to create a strong passphrase and remember it for latter. To show the public key, use the following in the terminal prompt:
cat .ssh/id_rsa.pub
Copy the the public ssh-key and add it to
Settings > SSH Keys
on your GitHub account.
Now, click on “+” next to your avatar on GitHub to generate a new
repository, name it first_repo
and do not initialize it.
For next steps, copy the SSH address of your remote repository from
GitHub that should be like
git@github.com:user/first_repo.git
- later you may find
the address under “Clone or download” tab on your repository.
To add the remote repository, open a terminal prompt on your computer and issue:
cd ~/first_repo
git remote add origin git@github.com:user/first_repo.git # add the remote repo
git remote -v # show the remote repository
Finally, to upload your local repository to GitHub use:
git push -u origin master
You can always generate and initialize a new repository on your
remote i.e. GitHub and clone to your local computer. Click on “+” next
to your avatar on GitHub to generate a new repository, call it
second_repo
and make sure to be initialized. To clone the
remote repository on your local system with SSH, click on “Clone or
download” and copy the SSH address. Open a terminal prompt on your
local computer and issue:
cd ~
mkdir second_repo
cd second_repo
git clone git@github.com:YourUserName/second_repo.git
Any changes in the second_repo
directory will record
by Git and you can use git push origin
to update the
remote.
Another important asset of Git is collaboration with others at the
same time. One of the most effective way to collaborate without
conflict, is making new branches in addition to the
master
branch. Use the following Git commands to make a
new branch and switch between branches :
git branch # show all branches
git branch my_work # create my_work branch
git checkout my_work # switch to my_work branch
Now if we keep working on the directory, all changes will be stored
at my_work
branch instead of master
branch.
That will prevent the conflict between your work and others. When you
finish your tasks you can merge my_work
branch to the
master
by:
git merge my_work
Also, we can add multiple remote to a repository. To add another
remote (called public
) to the current remote
(origin
) we can use:
git remote add public SSH_adress
Where the SSH address
is address of the new remote
(for example another empty repo. in GitHub) - try
git remote -v
to see name and address of remotes.
To push the repositort to public
remote use:
git push public master
Above commad will create a new branch called master
in
public
remote and push entire repo to the new location.
Note that now we have two remotes for the repo.
Summary
The following Git commands are used in this article:
man git <command> # show the manual of the command
git init # create an empty Git repository or reinitialize an existing one
git config -l # list config file
git config -e # edit config file
git status # show the working tree status
git add # add file contents to the index
git mv # move or rename a file, a directory
git rm # remove files from the working tree (local) and from the index (remote)
git rm --cached # unstage and remove paths only from the index (remote)
git log # show commit logs
git log <file_name> # show commit logs for the file
git log --patch <file_name> # combine both `git log` and `git diff` comments
git diff # show changes between commits, commit and working tree, etc
git diff --staged # show changes between commit and working tree after add
git diff HEAD # show changes between working tree and the most recent commit
git diff HEAD~n # show changes between working tree and the nth most recent commit
git diff HEAD <file_name> # show changes between the current file and the most recent commit
git show HEAD <file_name> # show the most recent commit of a file
git show HEAD~n <file_name> # show the nth most recent commit of a file
git checkout # restore working tree files or switch branches
git checkout HEAD <file_name> # recover the version of the file recorded in HEAD
git reset <file_name> # reset (unstage/uncommit) current HEAD to the specified state
git reset --hard HEAD~1 # reset commited state to last HEAD
git revert <commit ID> # revert some existing commits
git revert --no-commit HEAD # revert to last commit (no asking to commit at the moment)
git revert --abort # abort the revert (return to before revert)
git remote # show the remote repository (use -v floag for a verbose details)
git remote add origin <SSH_add> # add remote repository to the local repo
git remote remove <remote_name> # remove a remote repository
git remote rename <remote_name> <new_name> # rename a remote repository
git remote set-url origin <url> # set/change remote origin
git clone # clone a repository into a new directory
git fetch # download all history from the remote tracking branches
git merge # join two or more development histories together
git pull <origin> <branch> # a combination of fetch and merge
git push <origin> <branch> # update remote refs along with associated objects
git commit # record changes to the repository
git commit --amend # edit the commit comment before push (i to insert and esc- :wq to exit)
git branch # list branches
git branch <new branch name> # create a new branch
git branch -d <branch name> # delete a branch