Skip to content

10. Version Control

We strongly recommend to at least read Chapter 1 and 2 of the official Git book and maybe the seven rules of a great Git commit message.

Setup for the First Time

$ git config --global user.name lyrahgames
$ git config --global user.email lyrahgames@mailbox.org
$ git config --global core.editor nano

New Project

$ pwd
/home/lyrahgames/projects/cpp-course
$ ls
01-hello     02-input  03-fibonacci  04-files  05-rational
06-graphics  07-build
$ mkdir 08-git
$ ls
01-hello     02-input  03-fibonacci  04-files  05-rational
06-graphics  07-build  08-git
$ cd 08-git
$ pwd
/home/lyrahgames/projects/cpp-course/08-git

Git Initialization

$ git init
Initialized empty Git repository in /home/lyrahgames/projects/cpp-course/08-git/.git/

Git created a new folder .git inside the current directory. Because of the preceding dot, this folder is typically hidden. To print it to the screen, we use an additional flag for ls.

$ ls -a
.git/

For now, the content of this folder is not interesting for us.

Status

$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

Untracked Files

$ touch main.cpp
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    main.cpp

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

Preparing for Commit

$ git add main.cpp
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
    new file:   main.cpp

Commit

$ git commit -m "Initial commit"
[master (root-commit) 63588d9] Initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 main.cpp

Clean Repository and History

$ git status
On branch master
nothing to commit, working tree clean

$ git log
commit 63588d9bb330ba9edb2d6f7bf664a445ec53a457 (HEAD -> master)
Author: lyrahgames <lyrahgames@mailbox.org>
Date:   Tue Oct 20 20:11:10 2020 +0200

    Initial commit

Modified and Modified after Stage

// main.cpp
#include <iostream>
int main(){
  std::cout << "Hello, World!\n";
}
$ g++ -o hello main.cpp
$ ./hello
Hello, World!
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   main.cpp

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    hello

no changes added to commit (use "git add" and/or "git commit -a")
$ git add main.cpp
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   main.cpp

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    hello

Change main.cpp again before committing.

// main.cpp
#include <iostream>
int main(){
  using namespace std;
  cout << "Hello, World!\n";
}
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   main.cpp

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   main.cpp

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    hello

git add adds a snapshot of the file at the time the command was called. If the file has changed after git add, it has to be added again.

$ git add main.cpp
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   main.cpp

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    hello

Now let us do another commit.

$ git commit

This one opens the nano editor. Type in your commit message.

Printing the Log

$ git log
commit 37123eab509e177d2f7d7449b2dfde686bb8393a (HEAD -> master)
Author: lyrahgames <lyrahgames@mailbox.org>
Date:   Tue Oct 20 20:35:27 2020 +0200

    Add hello-world program

commit 63588d9bb330ba9edb2d6f7bf664a445ec53a457
Author: lyrahgames <lyrahgames@mailbox.org>
Date:   Tue Oct 20 20:11:10 2020 +0200

    Initial commit

Checkout Other Commits

$ git checkout 63588d

Return to the last commit.

$ git checkout master

Ignoring Specific Files: Black and White Listing

Let us now add a typical template buildfile from the last project to be able to automatically compile the program by using build2.

$ touch buildfile
cxx.std = latest

using cxx

hxx{*}: extension = hpp
cxx{*}: extension = cpp

exe{hello}: {hxx cxx}{*}

cxx.poptions =+ "-I$src_base"

Test the compilation.

$ b
c++ cxx{main}
ld exe{hello}
$ ./hello
Hello, World!
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    buildfile
    hello
    hello.d
    main.o
    main.o.d

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

From these given files, only buildfile should be tracked by Git. To not always manually decide which files to add to the commit or the history, we will use a .gitignore file.

$ touch .gitignore

Black listing approach: List every file or file pattern you do not want to track.

# .gitignore
hello
hello.d
main.o
main.o.d

with patterns:

# .gitignore
hello
*.d
*.o

Both of these files gives us the following output when git status is called.

$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    .gitignore
    buildfile

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

Black listing, in my opinion is not ideal. Therefore we will use white listing. We will first ignore every possible file by using * and invert ignoring files by using !.

#.gitignore

# Ignore everything.
*

# Allow any subfolder.
!*/

# Allow C++ header and source files.
!*.hpp
!*.cpp

# Allow build2 buildfiles.
!buildfile

# Allow .gitignore file.
!.gitignore

Now make the commit by adding everything that is not ignored.

$ git add .
$ git commit

References


Last update: October 22, 2020