ℹ️ Cette présentation est aussi disponible en français !
👩💻 Autonomous version (for solo reading)
A distributed Version Control System (VCS)
= system allowing to manage different versions of a set of files
(Many intermediate versions between two releases!)
Often used to allow several people work the same on code... among other reasons!
Git ≠ GitHub, GitLab, Gitea, etc.
Git = software tool (command line)
GitHub and GitLab = Git repository hosting services
Linux ≠ OVH, for example
Benefits on several levels:
It's worth the trouble!
Let's start with a parenthesis on the word “distributed”.
You may have heard that Git is a distributed version control system .
What does that mean??
❗️ I promise, nothing complicated! (there will be plenty of images)
Git is based on a graph.
A commit is identified in an unique way by its hash.
All the information in a commit, including the contents of the files, are passed to a hashing function to obtain its hash.
Principle of a hash function: data (a sequence of bytes) is passed to it, it returns a number (“hash”); two identical entries ⇔ two identical hashes.
(More info for the curious on Wikipedia)The hash of a commit is a very large number, presented in hexadecimal: 6828f7bf493cd4c9c332ea769e6e38fbbe258821.
Hashes are often shortened (by default to 7 characters): 6828f7b, this is what we will use throughout this course.
It's not just commits that point to commits.
There are also branches, tags, and some other things. (We'll talk about their differences later)
To create a commit...
... we simply add it to the graph.
There is no trick here, (almost) all operations only ever add commits to the graph.
Though, let's talk about what happens when we do.
HEAD
HEAD
refers to the commit that is currently checked out.
That is, it is the commit whose contents (files) are currently present in the directory.
The commit pointed to by HEAD
can be thought of as “where we are right now”.
HEAD
And when creating a new commit?
HEAD
follows the new commit (it is automatically checked out).
And when creating a new commit?
A branch follows the commit if and only if it is checked out.
A tag is immovable and cannot be checked out, so it never follows a new commit.
(To “move” a tag, it must be deleted and re-created elsewhere.)
➔ A branch is used to follow something (development of a feature...); a tag is used to mark a particular commit (version...)
Try to avoid graphic interfaces if possible.
(At least at the beginning.)
For example, their handling of errors is often problematic...
$ git init
Creates a new repository in the current directory.
Answer: the .git
directory1.
1 In some cases it's a file.
Apparently there was an error?
Let's create a few files.
I promise this is the last thing
Git lets you choose which modifications will be recorded in the next commit.
This is done via the git add
command suggested by the earlier hint text.
We just witnessed git commit
opening a text editor.
Text editor for use by Git commands. The value is meant to be interpreted by the shell when it is used. Examples:~/bin/vi
,$SOME_ENVIRONMENT_VARIABLE
,"C:\Program Files\Vim\gvim.exe" --nofork
. The order of preference is the$GIT_EDITOR
environment variable, thencore.editor
configuration, then$VISUAL
, then$EDITOR
, and then the default chosen at compile time, which is usuallyvi
.
GIT_EDITOR
documentation in git-var
.
The editor used by default is vi
, which has a... peculiar ergonomy.
To change that to nano
(for example):
$ git config --global core.editor "nano"
EDITOR
in your .bashrc
/.zshrc
also works.
# ...
export EDITOR=nano
# ...
Yes, that's an option!
It is however crucial to ensure that the command only returns when the file is closed:
$ git config --global core.editor "subl -w"
$ git config --global core.editor "code -w"
Git on your machine = backup tool (and more)
Git on many machines = 🤯
Each machine contains a Git repository. .git
directory, etc.
Modifications can be “pushed” to another machine, and “pulled” from it as well.
git clone
git pull
git push
Git models remote machines using “remotes”.
A remote = a certain repo on a certain machine (more or less).
Remotes are managed via git remote
!
git fetch
Git does not make network requests for each command.
To remain up to date: git fetch <remote>
.
(git pull
implicitly calls git fetch
.)
...Git has our backs.
issotm@sheik-kitty /tmp/test% git push
To example.com:path/to/repo.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'example.com:path/to/repo.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
... “non-fast-forward”?
“Fast-forwarding” a branch means “moving it only towards children commits”:
“Fast-forwarding” because it's only ever going “forward” in time.
Fast-forward = always safe (can't “lose” any commits).
...what about non-fast-forward cases?
git merge
git rebase
Advantages:
Downsides:
git merge <commit>...
Creates a new commit on the current branch that “gathers” the current branch and all <commit>
s.
We will explain the “gather”ing together with rebase
.
Example: git merge master
git rebase <new-base> [<branch>]
If <branch>
is omitted, the current branch is modified.
Example: git rebase master
(or git rebase master add-dark-mode
)
git init
⚠️ Creates a repo in the current directory!
git clone <URL>
git status
issotm@sheik-kitty /tmp/rgbds% git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
git status
issotm@sheik-kitty /tmp/rgbds% git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: .editorconfig
deleted: .checkpatch.conf
no changes added to commit (use "git add" and/or "git commit -a")
git add
issotm@sheik-kitty /tmp/rgbds% git add .editorconfig
issotm@sheik-kitty /tmp/rgbds% git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: .editorconfig
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: .checkpatch.conf
A neater visualiser for git diff
and git blame
: delta
The Git status can be shown in the shell prompt (for example via powerlevel10k)
A good graphical interface (though freeware): Sublime Merge (I recommend because it shows the commands it executes)
If you use an IDE, it may have a Git integration (sometimes via extensions), read the docs
The slides are available online: https://eldred.fr/slides/git!