-
Notifications
You must be signed in to change notification settings - Fork 17
Git tutorial
This is a basic tutorial of git. A more advanced one can be found here. This tutorial is based on this Spanish version that I created many years ago.
Git is a version control software designed by Linus Torvalds, designed with the efficiency and reliability of maintaining application versions when there is a large number of source files. At first, Git was thought of as a low-level engine on which others could write the user interface or front end. However, Git has since become a fully functional version control system. There are some very relevant projects that already use Git, in particular, the Linux kernel.
The first step is to be able to download a repository, add files and send these files back to the repository.
- The first thing is to install a Git client. This is the instruction for Ubuntu, but you can install them in other operating systems.
$ sudo apt-get install git2.a. Next you will have to download the repository on which you are going to work. By default it downloads the last revision ("HEAD").
$ git clone https://github.com/miguelgfierro/codebase2.b. Alternatively, you can create a new repository.
cd /path/to/your/folder
$ git init- As you generate content, it is not "added" to the repository. When checking the status of git by typing:
$ git status
# On branch master <-- This is the branch you are currently in
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: README.md <-- This is the modified file
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# file.cpp <-- This is the new file created
#
no changes added to commit (use "git add" and/or "git commit -a")4.a. You can add a file:
$ git add file.cpp4.b. Or only the latest modifications to previously added files:
$ git add -u4.c. Or all files added and modified:
$ git add .- Looking at the status you will see that:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README.md
# new file: file.cpp- Now you have to upload everything to the local repository that is on the computer itself. This is an intermediate repository between your computer and the global repository.
$ git commit -m "I have improved my Git level!"Tips and tricks: You can do $ git commit -a -m = "I have improved my Git level!", this also uploads files marked as modified, without having to re-do git add.
- Finally you have to upload the changes to the global repository. In order to do this the administrator has to give you permission. You are going to push to branch
master, which is the initial branch available when the repo is created.
$ git push origin master- To download the latest version of the server:
$ git pull origin masterInitial settings to enter your name and email (git will advise if necessary). To configure your user in all PC repositories:
$ git config --global user.name "Bruce Wayne"
$ git config --global user.email iambatman@users.noreply.github.comTips and tricks: the alias your-github-username@users.noreply.github.com is a your default hidden email in Github.
To configure your user in a single repository:
$ git config user.name "Bruce Wayne"
$ git config user.email iambatman@users.noreply.github.comTo view the user and email configured in the repository:
$ git config user.name
$ git config user.emailThe branches are used to develop in parallel to the main repository. When you create a new functionality in the code, you should create a branch. Then you develop the functionality, test it and when it works perfectly is integrated into the main branch (which is usually the master branch).
Tips and tricks: In master there should always be working code, please don't be the guy who sends breaking code to master, karma will hunt you!
- View the state of the branches
$ git branch <-- This tells you the branches in your local repository
$ git branch -a <-- It tells you the branches in local and global repositories (listed as remotes/origin/...)
$ git fetch -p <-- Update the list of branches taking into account remote branches deleted by other people- Create and upload/download a branch
$ git branch testing <-- Create a new branch in the local repository called testing
$ git checkout testing <-- Change from the current branch to testing branch (can be done whenever you want to change branches)
$ git add new_file.cpp <-- We add a new file in the testing branch
$ git commit -m "added new_file.cpp to the testing branch" <-- commit local repository
$ git push origin testing <-- upload changes to the global repository (if you are prompted to do something else, do so)
$ git pull origin testing <-- you can download the latest changes from the global repository to your computer- If you want to merge a branch (eg testing) with the master branch
$ git checkout master <-- changes from the current branch to the master branch
$ git merge testing <-- merge the testing branch with the main- Delete a branch (eg testing, which would make sense after the merge) you have to do the next two steps
$ git branch -d testing <-- locally clears the testing branch
$ git push origin --delete testing <-- delete the testing branch in the global repository- Another good practice is to tag locate an important point of your code is to make a "tag". Tipically this is done when you want to make a release.
$ git tag <-- shows a list of all tags
$ git show v1.0 <-- shows detailed tag information called v1.0
$ git tag -a v1.0 -m "my tag v1.0" <-- creates a tag named v1.0 in the local repository
$ git push origin v1.0 <-- upload the tag to the remote server- In some situations there can be conflicts. A conflict occurs when two developers have modified the same file at the same time and then server doesn't know which is the final version of the file. The conflicts usually appear after pulling a branch and are visible when you see the status:
$ git status
# On branch master
# You have unmerged paths.
# (fix conflicts and run "git commit")
#
# Unmerged paths:
# (use "git add ..." to mark resolution)
#
# both modified: file.cppTo solve this you can open the file and manually fix the conflicts. Alternatively, you could choose to maintain the version of the global server
$ git checkout --theirs file.cppor you choose your local version
$ git checkout --ours file.cpp- A good way to avoid conflicts when developing in branches is to rebase. Put in simple words, when rebasing you are telling git to automatically solve the conflicts generated when two developers are modifying the same file locally, with a not up-to-date repo version. This behavior typically appears when you pull the last changes of a repo and another developer has modified a file at the same time. To avoid this conflict, you can rebase when pulling:
$ git pull --rebase origin masterIn git is easy to roll back to a previous version of your repo, for that we only need the identifier of the commit. First we need to find the commit we want to roll back:
$ git log
# commit 8af5d69e4bbc9aec8b5e268e2ba94c49fbffee37 <- this is the commit hash
# Author: Miguel Fierro <miguelgfierro@users.noreply.github.com>
# Date: Fri Jun 16 08:27:17 2017 +0100
#
# clean string js fix #76
# commit 8168c0c18c28488b0d1cf12c98f93ebc4f1e40e1
# Author: Miguel Fierro <miguelgfierro@users.noreply.github.com>
# Date: Fri Jun 16 08:21:20 2017 +0100
#To roll back to a specific commit:
git checkout 8af5d69e4bbc9aec8b5e268e2ba94c49fbffee37 In case you have a repo with submodules, which are different subrepos whithin the main repo (more info here), you need to update them:
git submodule update --recursiveNext a list of useful commands:
$ git diff <-- shows differences between a modified file and one that has been modified before but is stagged, i.e. it is in the local repository.
$ git diff --cached <-- differences between a modified file and the same file saved in the HEAD
$ git rm file.txt <-- delete a file
$ git mv file.txt new_file.txt <-- rename a file
$ git log <-- view commit history
$ git log --since = 2.weeks <-- view commit history from 2 weeks ago
$ git log --reverse <-- view the commit history in reverse order, starting with the first commit
$ git config --global alias.ci commit <-- alias for not having to type `git commit` and just do `git ci`
$ git config --global alias.st status <-- alias not to have to type `git status` and just do `git st`
$ git config --global core.excludesfile ~ / .gitignore <-- within `.gitignore` you list the files to be ignored
$ git config --global credential.helper cache <-- save your password in cache for 15 min, so you do not have to write it over and over again
$ git config --global credential.helper 'cache --timeout = 3600' <-- save your password for one hour
$ git rev-list HEAD --count <-- allows you to see the total number of commits
$ git shortlog -sne <-- allows to see the number of commits of each developer
$ git fetch origin <-- this command along with the one below removes all local changes and sets the server version.
$ git reset --hard origin/masterHappy gitting!