Getting started with Git

Table of Contents

This file is available online at: https://sed-bso.gitlabpages.inria.fr/formations/git-basics-Pau-02-05-2023/git-basics-Pau-02-05-2023.html

Git is a flexible and easy to use version control system (VCS).

1. Overview

1.1. What is a version control system (VCS) and why use it?

  • it is a software (that has to be installed on your computer)
  • it allows to record snapshots of your code and to navigate, explore and compare this snapshots
  • it is the very first step toward software reproductivity
  • other famous VCS: Subversion (svn), Mercurial, etc.
  • My personal opinion:
    • didactic tool with a very useful help messages
    • fast learning
    • small entrance ticket that worth to pay it
    • VCS should be integrated in your daily routine
    • to get used to it, commit your config scripts in a private repo ;-).

1.2. Git vs. GitHub/GitLab/Bitbucket…

1.2.1. GitHub, gitlab and others are are hosting platforms: they ensure data saving, allow to collaborate and provide set of services:

  • repository visualization
  • issues tracker
  • project management board
  • continuous integration delivery

See : https://gitlab.inria.fr/sed-bso/heat/ or https://github.com/MmgTools/mmg

1.2.2. gitlab.inria.fr: advantages and drawbacks

  • suitable for private or sensitive data: +
  • easy to get help from inria SDT and SEDs (CI/CD pipeline deployment): +
  • people have to be explicitely added to the repo to contribute or submit issues: - (not suitable for software community building)

1.3. interacting with Git

There are different ways to use git, pick your favorite one:

1.4. getting help in command line

Use the -h option.

git -h
git add -h

2. creating locally a new repository or cloning a remote one

2.1. for a brand new repo

git init
git add .	      # Add all the files under the current directory.
git commit -m "This is the first commit."

2.2. for an existing repo

git clone https://github.com/Algiane/mmg-MdB
cd mmg-MdB

What you obtain is a checkout.

3. history and commits

  • git log shows the history of changes to the repository
  • the history is a list of commits
  • a repository’s history is local, complete, and immutable
  • each commit has a unique 20-byte identifier (SHA1 hash), the commit ID. The commit ID can be shortened (e.g., take the seven first hexadecimal digits), as long as it’s unambiguous. If you “amend” a commit, you get a different commit ID, so effectively a different commit and a different history.
  • each commit has an author: name + email address
  • git show COMMIT-ID shows the changes introduced by the given commit (example: git show 15e0996)
  • git diff A..B shows the changes between commits A and B (example: git diff 15e0996 adf56)
  • Default diff tool is the diff command. You can choose your favorite diff tool using the git difftool -t <toolname HEAD> command. For example git difftool -t meld HEAD~.

4. references

  • HEAD is the tip of the current branch
  • foo is the tip of branch foo
  • master~ is the next-to-last commit of branch master
  • master~~~ is… guess what…
  • HEAD~~~, likewise but for the current branch
  • master~~~ can be shorten with master~3

5. The 3 trees (or spaces) of your local repo: working directory, index and. history

5.1. Commands

  • the files you edit are in the working directory
  • git add adds changes to the index, which is a staging area. Run git add -p to choose interactively and step by step changes to add or not.
  • git commit commits what the index contains to the history
  • git status reports on changes in the WD and in the index
  • git diff HEAD shows changes compared to the tip of the current branch

git_1.png

Figure 1: Illustration of the 3 trees of the local repo (source: http://www.marcelofossrj.com)

5.2. Exercise

  1. Modify multiple files or file area of your working dir
  2. Choose modifs that have to be indexed using git add -p
  3. Inspect your repo with git status
  4. Commit your index content with git commit -m "suitable commit message"
  5. Inspect your repo

6. discarding or stashing away local changes

  • git reset --hard to discard uncommitted changes
  • git stash to stash away uncommitted changes:
    • Run git stash -p to choose interactively and step by step changes to stash away.
  • Run git stash pop to reinstate those changes in the working tree, uncommitted.

7. branches

7.1. Introduction to branches

  • branches represent different lines of history, which can be merged:
    • Use git branch -l to list the local branches.
  • the “default” branch is called master or main
  • git branch <NAME> creates new branch <NAME> off the current branch
  • use git checkout <BRANCH> to switch the working tree to an existing branch named <BRANCH>
  • git checkout -b <NAME> create a new branch <NAME> off the current branch and automatically switch on it
  • git log --graph --abbrev-commit --decorate draws branches graph and commits in your terminal

7.2. branch merging vs rebasing

  • rebasing a branch <feature> into another (<master>) means that you will move the branch <feature> on the tip of <master> (git checkout <master> && git rebase <feature> ). For each commit of <feature> a new commit is created in <master>. The project history appears linear and it is easy to navigate the project (with git log and git bisect).
  • merging a branch <feature> into another (<master>) (git merge <master> && git rebase <feature> ) creates a new merge commit that ties history of both branches. It preserves the tree structure of the developments.

See the following ref for a description and comparison of both processes.

7.3. Navigates in history with merge commits

git show 4cfeba^1
git show 4cfeba^2

7.4. solving conflicts

Exercise:

  1. Create a new branch from the master one and switch to this branch (git checkout -b <branch_name>)
  2. Modify the first line of the README.md file
  3. Add and commit changes (git add -p, then git commit)
  4. Switch to the master branch and modify the same line of the README.md file (git checkout master)
  5. Add and commit changes
  6. Check that both branches have diverging commits
  7. Merge the new branch into the master one and solve conflicts (git merge <branch_name> then git mergetool -t meld)

8. Repository inspection

  • git ls-files allows to inspect list of commited files
  • git blame shows author and commits for each lines of code

9. Debugging

  • git bisect [start,good,bad,skip,reset] start a bissection between "good" and "bad" commits to help you to locate the commit that introduce a regression

10. remotes, push, pull

  • repositories can have associated remotes
    • a remote is a remote copy (clone) of the repository
    • a repository can have several remotes
  $ git remote -v
origin	git@github.com:Algiane/mmg-MdB.git (fetch)
origin	git@github.com:Algiane/mmg-MdB.git (push)
upstream	git@github.com:MmgTools/mmg.git (fetch)
upstream	git@github.com:MmgTools/mmg.git (push)
  • copies can be synchronized using git push and git pull
  • git branch -rl lists remote branches
  • each branch can specify which remote to push to/to pull from

11. Git configuration: .gitconfig file

  • you can configure git with git config command (use git config -h to get help).

For example to set your name and email address:

git config --global user.email
git config --global user.name
  • it modifies the .gitconfig file that can be manually edited too.
  • you can check the [user] section of this file.
  • the [alias] section allows to customize shortcuts.
[alias]
  ci = commit
  st = status
  unstage = reset HEAD --
  • Some useful aliases you can add:
    • for tree graph vizu:
lg1-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)'=
lg1 = !"git lg1-specific --all"
  • to find oldest ancestor of 2 branches:
oldest-ancestor = !zsh -c 'diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | head -1' -

12. Work organization

12.1. Workflows and branching strategies

Branching strategies will help you to understand your history and to limit conflict creation.

  • An easy to set-up strategy is the Feature Branch Workflow :
    1. you never work directly in master branch
    2. features are developped in dedicated feature/<my-feature-name> branches and merged into master when ended
    3. multiple features can lived at the same time
  • For projects with regular software releases, the Feature Workflow with Develop Branch variant can be used:
    1. you never work directly in master branch, it contains the production-ready state of the repository
    2. you have a unique develop branch deployed from the master in which you do not directly work either. The develop branch contains the latest developement changes for the next release and is merged into master when the realease is ready.
    3. features are deployed from the the develop branch in feature/<my-feature-name> branches and merged into the develop branch when ready.
    4. release fixes are deployed from the master branch into hotfix/<my-hotfix> one and merged when ready.

12.2. Dev rules

  • Keep comments in code, not in commit log
  • keep commits small and focused: you can stash away things not related to your commit
  • keep branch focused: creates new branches to separate tasks when a task leads to unexpected developments. You can use the git cherry-pick command to copy a given commit from one branch into another one (if needed) and limit conflicts.

13. Ressources

Date: 2 mai 2023

Author: Ludovic Courtez & Algiane Froehly

Created: 2023-05-02 Mar 17:46

Validate