The `531019e7119268c4dae5ac44ef5929165794f4b0` points to the tree object which points to the two committed files.

In git, there are 3 areas:
- The **working area** (everything in `alpha/` except the folder `.git`)
- The **staging area** (in the `.git` folder)
- The **repository** (also in the `.git` folder)

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 `data/number.txt`:
```sh
echo"2"> data/number.txt
git add data/number.txt
git commit -m"a2"
git st
git lo
```
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
git log
cat data/number.txt
git checkout 531019e
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 `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 log
```
The `git log` command doesn’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 log` command:
`(HEAD -> master)` became (HEAD).
This change means that you are in a **detached HEAD** state , the command `git st` also gives you this information.
```sh
git st
```
In git commit are chained one after another starting with the first commit.
Therefore, you can always go back to the commit history.
The repository is not only made of commits, but also of labels.
Labels point to a commit and can be the target of the `git co` command.
They are two types of labels:
- branches
- tags
If the first commit is the root of a growing tree of commits, branches are labels pointing to the leaves of the tree.
They change after each commit from pointing to the ancestor of the new commit, to pointing to the new commit.
The default branch in git is called `master`
Contrary to branches tags are anchored to a fixed commit.
**HEAD** is a special label that indicates your position in the tree of commits.
You can add a tag to your first commit with the command `git tag`
```sh
git tag -a v0.1 -m"my version 0.1"
git tag
git lo
```
You now have one tag in your repository.
The commit `c7a4cb9` is pointed by the tag `v0.1`.
```sh
git co master
git st
git lo
```
We are back at the leaf of the git repository.
## Growing the repository tree
We only have one branch, the `master` branch in our repository.
This means that we only have one timeline in our history.
In git, you can have as many branches as you want, to test out things, for example.
The following command creates the branch `dev` and move us (**HEAD**) to it.
```sh
git co -b dev
git st
git lo
```
```sh
echo ’3’ > data/number.txt
git add data/number.txt
git commit -m"a3"
git lo
```
If we have two branches `dev` and `master`, it’s hard to tell them apart (`master` is shorter).
```sh
git co master
echo'b'> data/letter.txt
git add data/letter.txt
git commit -m"b2"
git lo
```
Congratulations, you have a fork in your git repository !
Let’s make another one called `dev2` from the branch `master` where `data/letter.txt` contain the letter `c`.
Then create the corresponding commit `c2`
## Merging branches
When you are ready to incorporate your new code in your main branch you need to merge the branch containing the new code into your main branch.
You can merge branches with the command `git merge`.
This command is going to try to merge the targeted branch into the branch you are on (**HEAD**).
The command `git branch` shows you the available branches and the one you are on.
```sh
git branch
git merge master
```
Can we merge `master` into `dev2` ?
```sh
git co master
git branch
git merge dev2
```
There are three types of merge :
- Fast-forward
- Merge of two different lineages
- Merge of two different lineages with conflict
Here the branch `dev2` is a direct descendant of `master`.
`dev2` contain all the information contained in `master`.
For `master` to gain all the information contained in `dev2`, we just have to move the label `master` to the commit pointed by `dev2`
```sh
git lo
```
There is a fork between the branch `master` and `dev`, we have to merge two different lineages.
```sh
git branch
git merge dev
```
Here the command create a **merge commit**, a merge commit is a commit that has two direct ancestors.
A new commit means a new commit message to write.
```sh
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 `data/number.txt` file while in the `master` branch, we worked on the `data/letter.txt` file.
Let’s complicate things !
Create a new commit `e3` 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 branch `master`.
```sh
git lt
git branch
git merge dev
git st
```
The automatic merge failed due to a conflict in `data/letter.txt`.
You are now in a merging state.
You must solve the conflict by editing `data/letter.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 `data/letter.txt`, to set its content to `f`.
Then complete the merge:
```sh
git add data/letter.txt
git st
git commit
git st
git lt
```
You, now, know how to deal with the different kind of merge
`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.
> Note: repositories created on gitlab are _bare_ repository. There is no working
> or stash area on gitlab because nobody works on it.
At the end of the page [http://gitlab.biologie.ens-lyon.fr/<user_name>/git_basis](http://gitlab.biologie.ens-lyon.fr/<user_name>/git_basis) you have the following instruction to populate your remote repository
from an existing repository.
We can check the current remote addresses of our local git repository:
```sh
git remote -v
```
**origin** is set to `https://gitlab.biologie.ens-lyon.fr/LBMC/file_handle.git` for `fetch` and `push`
operation.
We want to add our repository to the remote addresses of our local git repository.
We are going to use `gitlab_lbmc` instead of `git@gitlab.biologie.ens-lyon.fr`
to match the ssh configuration file and use our ssh key in the connections to
Then we use the following commands to push our local copy to our remote repository:
```sh
git push -u perso --all
git push -u perso --tags# tags need to be pushed separatly
```
## merging branches
We want to merge our work with the **master** branch. What will the following
command do?
```sh
git merge master
```
Nothing. **master** points to an ancestor commit of the **tp1** branch.
However, the reverse operation is possible:
```sh
git checkout master
git branch -v
git merge tp1
git push perso
```
You can see the graph of our modifications at the following address [http://gitlab.biologie.ens-lyon.fr/<user_name>/git_basis/network/master](http://gitlab.biologie.ens-lyon.fr/<user_name>/git_basis/network/master)