We are going to write some basic configuration files to be able to the [gitlab server of the LBMC](http://gitlab.biologie.ens-lyon.fr).
If you are not using your own laptop, remember to delete your `~/.ssh` folder at the end of the TP.
Otherwise, somebody else could use your ssh key if you don't protect them with a password.
But don't stress to much about it, you can always remove the key later from your [gitlab configuration](http://gitlab.biologie.ens-lyon.fr/profile/keys).
Throughout this practical, every string between chevrons `<like this one>` must be replaced with the adequate value.
## Git configuration
Git can be configured with the `git config` command or directly by editing the
`~/.gitconfig` file. Here is a config example to start:
Git can be configured with the `git config` command or directly by editing the `~/.gitconfig` file. Here is a config example to start:
```sh
# This is Git's per-user configuration file.
...
...
@@ -43,7 +43,7 @@ editor = vim
co = checkout
ci = commit
st = status
lo = log --graph--decorate--date-order--all"
lo = log --graph--decorate--date-order--all
lg ="log --pretty=format:\"%h - %an : %s\""
lt = log --graph--oneline--all
unstage ="reset HEAD"
...
...
@@ -52,13 +52,13 @@ unstage = "reset HEAD"
You can replace `vim` by any other editor of your choice, like `nano` (easier to learn) or `gedit` (graphical).
The **alias** section of the configuration is for shortcuts of git commands.
`git checkout` is now equivalent to `git co` to minimize the number of key
pressed.
`git checkout` is now equivalent to `git co` to minimize the number of key pressed.
## Gitlab connection
There are many ways to connect to a gitlab server. Git relies on other
system protocols to handle authentication and rights. Here we are going to use two different method depending if you are using your laptop or a PSMN computer.
There are many ways to connect to a gitlab server.
Git relies on other system protocols to handle authentication and rights.
Here we are going to use two different method depending if you are using your laptop or a PSMN computer.
For this method to work, you need to setup a password in you gitlab profile.
Go to [https://gitlab.biologie.ens-lyon.fr/profile/password/edit](https://gitlab.biologie.ens-lyon.fr/profile/password/edit) and set your password.
### `~/.ssh/config` file method (not for PSMN computers)
### `~/.ssh/config` file method (for your personal computers)
To connect to the gitlab server via ssh, you first need to generate a ssh key:
...
...
@@ -106,25 +105,26 @@ To test your connection run:
ssh -Tv gitlab_lbmc
```
With this second method, you will have to replace every `https://gitlab.biologie.ens-lyon.fr/` url in the sequel with `gitlab_lbmc:`.
With this second method, you will have to replace every `https://gitlab.biologie.ens-lyon.fr/` url in the sequel with `gitlab_lbmc:`, the shortcut you defined in your `~/.ssh/config` file.
# Part 1: Git alone
Git is a powerful tool to keep track of changes in your project and to manage your modifications history.
In this first part of the TP you will practice different git commands to keep track of your work and modifications with Git.
## Your first git repository
> A Git repository is an informatic project (folder) where changes are recorded using Git.
### Creation of a git repository
## Creation of a git repository
Start by creating a folder `alpha` in which you are going to write your project:
Start by creating a folder `alpha` in which you are going to write your project
```sh
mkdir alpha
cd alpha
```
Once in the alpha folder, you can initialize a git repository.
A git repository is a project tracked and indexed by git.
Once in the alpha folder, you can initialize a Git repository.
A Git repository is a project tracked and indexed by git.
```sh
git init
...
...
@@ -133,11 +133,11 @@ ls -la
The `git init` command create an hidden `.git` folder at the root of your project.
You should not temper with the content of the `.git` folder.
Everythings in the `.git` folder belong to git the rest of the `alpha` folder belong to you.
Everythings in the `.git` folder belong to Git the rest of the `alpha` folder belong to you.
When you issue `git` command the content of the `.git` folder is accessed or modified by git.
### Using git to track changes
## Using git to track changes
There is nothing in our repository:
...
...
@@ -151,9 +151,9 @@ We defined `st` as an alias of `status` in the `~/.gitconfig` file, so the two c
Our first code:
```sh
mkdir src
mkdir data
git st
echo 'a' > src/dict.txt
echo 'a' > data/letter.txt
git st
```
...
...
@@ -164,31 +164,67 @@ There are *untracked files*.
To start tracking file we use the command `git add` :
```sh
git add src/dict.txt
git add data/letter.txt
ls -R .git/objects/
git st
```
There are now changes to be committed, this means that git is now following the state of the `src/dict.txt` file.
The current state of `src/dict.txt` is recorded.
> `git add` greate *git blob*:
>
> - contains the compressed content of a file
> - The name of the blob is the [SHA1](https://en.wikipedia.org/wiki/SHA-1) of the file.
> - The first two characters of the [SHA1](https://en.wikipedia.org/wiki/SHA-1) are used as the name of a directory inside the objects folder
> - The rest of the hash is used as the name of the blob file
There are now changes to be committed, this means that git is now following the state of the `data/letter.txt` file.
The current state of `data/letter.txt` is recorded.
{height=150px}
```sh
echo 'b' > src/dict.txt
echo 'b' > data/letter.txt
ls -R .git/objects/
git st
```
We changed the state of `src/dict.txt`, but those changes are not staged for commit.
The previous states of `src/dict.txt` is still recorded *somewhere* even if it differs from its current state.
We changed the state of `data/letter.txt`, but those changes are not staged for commit.
The previous states of `data/letter.txt` is still recorded *somewhere* even if it differs from its current state.
This *somewhere* is called the staging area (where you stage changes).
{height=150px}
```sh
git ls-files --stage
printf '1234' > data/number.txt
git add data/number.txt
git ls-files --stage
printf '1' > data/number.txt
git add data/number.txt
git ls-files --stage
```
{height=150px}
You can save the state of the staging area definitively with the command `git commit`
```sh
git commit -m "a: my first commit"
git commit -m "a1"
git st
```
You cleared the change to be committed and wrote them in a commit.
Here "a1" is the message associated with the commit.
)](img/git_commit_xkcd.png){height=250px}
The repository is a chain of commit beginning with your first commit.
### Navigating a git repository
Let's create a new commit with the changes made to `src/dict.txt`:
Let's create a new commit with the changes made to `data/number.txt`:
```sh
git add src/dict.txt
git commit -m "b: my second commit"
echo "2" > data/number.txt
git add data/number.txt
git commit -m "a2"
git st
git lo
```
...
...
@@ -224,23 +275,25 @@ You have a second point in your commit history.
You can navigate to a given point of the repository with the command `git checkout`:
```sh
cat src/dict.txt
git checkout c7a4cb9
cat src/dict.txt
git log
cat data/number.txt
git checkout 8afd9d3
cat data/number.txt
```
You don't have to give the complete commit identifier for the command `git checkout`, only an unique subset of it.
The state, of the file `src/dict.txt` is back to the one at the time of the first commit.
> You don't have to give the complete commit identifier for the command `git checkout`, only an unique subset of it.
The state, of the file `data/number.txt` is back to the one at the time of the first commit.
The `git checkout` or `git co` command rewrite your whole working area to match the state of the targeted commit.
```sh
git lo
git log
```
The `git lo` command don't display your second commit anymore.
The `git log` command don't display your second commit anymore.
Git commits only know of their direct ancestor(s).
The other change is in the first line of the `git lo` command:
The other change is in the first line of the `git log` command:
`(HEAD -> master)` became (HEAD).
This change mean that you are in a *detached HEAD* state , the command `git st` also gives you this information.
...
...
@@ -297,8 +350,8 @@ git lo
```
```sh
echo '1' > src/num.txt
git add src/num.txt
echo '1' > data/number.txt
git add data/number.txt
git commit -m "1: first commit in dev"
git lo
```
...
...
@@ -307,15 +360,15 @@ If we have two branches `dev` and `master`, it's hard to tell them apart (`maste
```sh
git co master
echo 'c' > src/dict.txt
git add src/dict.txt
echo 'c' > data/letter.txt
git add data/letter.txt
git commit -m "c: third commit in master"
git lo
```
Congratulation you have a fork in your git repository !
Lets make another one called `dict` from the branch `master` where `src/dict.txt` contain the letter `d`.
Lets make another one called `dict` from the branch `master` where `data/letter.txt` contain the letter `d`.
### Merging branches
...
...
@@ -366,11 +419,11 @@ git lo
```
The new commit is a `Merge` commit with the identifiers of its two ancestors.
Here, we didn't have any conflict: in the `dev` branch, we worked on the `src/number.txt` file while in the `master` branch, we worked on the `src/dict.txt` file.
Here, we didn't have any conflict: in the `dev` branch, we worked on the `data/numberber.txt` file while in the `master` branch, we worked on the `data/letter.txt` file.
Let's complicate things !
Create a new commit in the `master` branch where the content of `src/dict.txt` is set to `e`.
Then create a new commit in the `dev` branch where the content of `src/dict.txt` is set to `f` and go back the the branch `master`.
Create a new commit in the `master` branch where the content of `data/letter.txt` is set to `e`.
Then create a new commit in the `dev` branch where the content of `data/letter.txt` is set to `f` and go back the the branch `master`.
```sh
git branch
...
...
@@ -378,35 +431,36 @@ git merge dev
git st
```
The automatic merge fail due to a conflict in `src/dict.txt`.
The automatic merge fail due to a conflict in `data/letter.txt`.
You are now in a merging state.
You must solve the conflict by editing `src/dict.txt`.
You must solve the conflict by editing `data/letter.txt`.
You can see three things in the `src/dict.txt`:
You can see three things in the `data/letter.txt`:
- The state of the file in your current branch (*HEAD*)
- The state of the file in the last common ancestor of the two branches
- The state of the file in the merged branch (*dev*)
Edit `src/dict.txt`, to set its content to `f`.
Edit `data/letter.txt`, to set its content to `f`.
Then complete the merge:
```sh
git add src/dict.txt
git add data/letter.txt
git st
git commit
git st
```
You now, know how to deal with the different kind of merge.
You now, know how to deal with the different kind of merge
## Cloning a git repository
## Part 2: Git togetherdata
We start by cloning an existing repository.
`file_handle.py` is a small python script to handle the dating and the access to dated files in a format compatible with the [guide of good practices at the LBMC](http://www.ens-lyon.fr/LBMC/intranet/fichiers/bioinfo/good-practices.pdf).
The `git clone <url>` command retrieves the whole history of a project and setup a working area based on the last point in this history.