Version control with git#

Git in a nutshell#

_images/Git-logo.png

Git is a version control system (VCS)

  • Keep history of modifications to files

  • Single-user or team software development

  • Created by Linus Torvalds in 2005 to support the linux kernel development

  • As of today, the most popular VCS out there

It is a command line tool. Check if you have it:

git --version
git version 2.34.1

Found it? Cool, then read on! If not: https://git-scm.com/downloads

What do I use it for?#

Over the past 10+ years:

  • code development

  • configuration files (my .bashrc, .emacs, etc.)

  • research papers - with geek colleagues only :-(

  • website, curriculum, tutorials, notebooks, …

All this can be done

  • as a single user or in collaboration with others

  • both offline on a machine (ex. my laptop) or…

  • … over a network (I currently use https://framagit.org/ as main server)

What will you use it for, today?#

  • Learn how to keep a text document under version control

  • Fine tune git configuration

  • Collaboratively edit a text document (ex. scientific article, documentation, …)

Quick start#

To keep track of the modification history of the files in a folder, turn that folder into a git repository.

Increments in the modification history appear as commits: each commit stores a set of modifications to the project, like adding, modifying or removing files.

Create a new folder, say project/, cd into it and initialize the repository

mkdir project
cd project
git init
Initialized empty Git repository in /home/coslo/teaching/tools/docs/project/.git/

Note

The history of your repository, along with its configuration, are stored in the .git/ folder. If you delete that folder, the git repository is gone!

Add a README file in the project folder

echo "Hello World!" > README.md
git status
On branch master

No commits yet

Untracked files:
..." to include in what will be committed)
    README.md

nothing added to commit but untracked files present (use "git add" to track)

Now add the file to the project and commit the change

git add .  # the dot will add all new files in the folder
git commit -m "Initial commit"
[master (root-commit) 87dfb76] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

More on commits#

As you can see, this is done in two steps:

  • add: include the new file into the list of modifications to record

  • commit: actually store the modifications in the repository

The -m flag allows you to leave a “commit message” to describe the change.

Modify the file and check the difference

echo "Hello World, again!" >> README.md
git diff
diff --git a/README.md b/README.md
index 980a0d5..5eb476f 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
 Hello World!
+Hello World, again!

Commit the change

git commit -am "Update README"
[master c8c02ae] Update README
 1 file changed, 1 insertion(+)

If we modify some files, we can “add” the change and commit in one shot with the -a flag.

Have a look at what we have done so far

git log
commit c8c02ae78ac2269ee3c477633bbdf809b4a3bc41
Author: Daniele Coslovich <92140-coslo@users.noreply.framagit.org>
Date:   Thu Apr 4 12:10:45 2024 +0200

    Update README

commit 87dfb767a1e466a3d4c4432719ab70db9b5a10e1
Author: Daniele Coslovich <92140-coslo@users.noreply.framagit.org>
Date:   Thu Apr 4 12:10:36 2024 +0200

    Initial commit

Finally, removing a file is similar to adding it

touch useless_file.txt
git add useless_file.txt
git commit -m "Add useless file"

git rm useless_file.txt
git commit -m "Remove useless file"
coslo@Latitude-7280:~/teaching/tools/docs/project$ [master 137a2b0] Add useless file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 useless_file.txt
coslo@Latitude-7280:~/teaching/tools/docs/project$ rm 'useless_file.txt'
[master db42cdc] Remove useless file
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 useless_file.txt

Bottom lines:

Useful commands to check the status of your repository are

  • git status

  • git diff

  • git log

Useful command to handle files

  • git add

  • git commit

  • git rm

Fine-tuning#

Personal information#

On the first commit, git might have asked you to provide your name and e-mail. This is not strictly necessary but you can do that with these commands

git config user.name <your_name>
git config user.email <your_email>

Add the --global flag to apply these settings globally for all your repositories

Warning

Privacy notes:

  • If you plan to share your project publicly, consider using a dummy (inexistent) email account

  • git commits may reveal a lot of information about a user’s habits…

Existing files#

What if the folder already contains files and/or sub-folders and we want to some (but not all) of them to the repository?

Option 1: add all the files then remove the ones you do not need

git add .
git rm <not_needed_file>
git commit -m "Add files"

Option 2: add selected files

git add <needed_file_1> <needed_file_2>
git commit -m "Add files"

You can use the star syntax (ex. \*.tex) to match multiple file

Ignoring files#

You may want to avoid storing certain files in your git repository, for instance

  • temporary or backup files (\*.~, \*.bak)

  • compilation artifacts and executables (\*.o, \*.so, \*.x)

Create a text file called .gitignore at the root of your repositoriy and fill it with patterns matching the files to ignore

cat > .gitignore <<EOF
*~
*.o
EOF

git add .gitignore
git commit -am "Add gitignore"

From now on, git status will ignore these files and they will not be considered for commit

FAQ#

How do I go back in time?#

First look for the hash of the commit you are interested in

git log --pretty=oneline
f23903dbaad95525b9f93a2e85bc2a0cbbe02563 Remove useless file
a595e3317b224aac0ef1752e2775c4d526859ca6 Add useless file
ddbfdfc0f64c5e8b8fa614d04b66b7345d989626 Update README
215049f1d757adcdf7a05ad3e5c253d4eb3b75f4 Initial commit

Check out a copy of the project as it was in that commit

git checkout a730cb4f

To get back to the current state of the project

git checkout master

How can I undo the last commit#

This is one of the most popular question about git on stackoverflow.

git commit -m "Something terribly misguided"
git reset HEAD~

Then edit the files as necessary and commit again.

Do I really need to write those commit messages?#

Writing commit messages may seem a burden (and actually, you can leave them blank) but it is important.

Tip: you may be able to write commit messages directly from your IDE and/or text editor.

_images/git_commit_2x.png

There are well-established guidelines to write good commit messages, so that they are informative and easy to read https://cbea.ms/posts/git-commit/

Structure

  • Separate subject from body with a blank line

  • Use the body to explain what and why vs. how

Style

  • Use the imperative mood in the subject line

  • Capitalize the subject line

  • Do not end the subject line with a period

  • Limit the subject line to 50 characters

  • Wrap the body at 72 characters

Hint

Write “Fix typo in tutorial”, not “fixed typo in tutorial.”

Branches#

Branches allow you to keep multiple versions of your project in parallel.

Repositories are created with a default branch, typically called master or main. That’s the branch to which we committed the modifications above.

Typical use case: develop a new feature in a separate feature branch, then merge it in the master branch.

_images/branch1.png

Glossary:

  • Fast-forward: no commits between the creation of the new branch and the merge

  • Conflict: concurrent modification to the same part of a file

Create a new branch and check it out

git checkout -b new_cool_feature
# commit commit commit ...
Switched to a new branch 'new_cool_feature'

Show available branches

git branch -va
  master           f23903d Remove useless file
* new_cool_feature f23903d Remove useless file

The prompt of your terminal should tell you which branch you are working on

coslo@local:~/teaching/tools/text/(new_cool_feature)$

If not, you may want to follow these instructions https://blog.sellorm.com/2020/01/13/add-the-current-git-branch-to-your-bash-prompt/

When the new feature is ready, get back to the master branch and merge the feature branch

git checkout master
git merge new_cool_feature
Switched to branch 'master'
Already up to date.

If conflicts occur, you will have to modify the files to remove them. git status will tell you how to proceed.

Warning

Beware! Conflict handling can be nasty…

Exercise: single-user workflow#

  • Make sure git is installed on your machine (if not, follow https://git-scm.com/downloads)

  • Download and extract the template project template-docs into docs/

git clone https://framagit.org/coslo/template-docs.git docs
  • Turn it into a new git repository: remove the .git/ folder, add all the relevant files and commit your changes

  • Edit README.md by adding your name to the “Authors” section and commit the change

Authors
-------
...
  • Familiarize yourself to the commands seen above, including those related to branching if you are already confident with the git basics