.. _git_introduction: Git Introduction ================ This section will give you a brief introduction to `Git `_ and `Gitlab `_ and how we use them. .. contents:: Table of contents :local: :backlinks: none Git and Gitlab -------------- **Git** is a version control system for tracking changes in the source code of software projects during development. **Gitlab** is a web application for version control based on git. Among other things, it provides a wiki, an issue tracking system, and a CI/CD pipeline system. CI/CD stands for continuous integration and continuous deployment and roughly means that new code runs through a "pipeline" of automated tests before it is integrated into the project. This way, errors and inconsistencies can be detected quickly. **Installation** To install git, follow the instructions of the git book in the chapter "`Installing Git `_". **Introduction** If you have never worked with git before, check out this webpage of the entire `Pro Git Book `_ for an introduction. Especially take a look at the pages "`What is Git? `_", "`Branches in a Nutshell `_", and "`Basic Branching and Merging `_", to make yourself familiar with the basic concepts. **Git Repository** A repository is a directory which stores all the files and data as well as metadata of a project. A git repository is a repository that is controlled by git. A git repository includes a complete version history of every file. The idea of git is that every project member has a copy of the entire repository on their **local** computer. In order to contribute to a software project that uses git for version control, you need to **clone the repository**. That means, it is copied to your local computer from the **remote** server, where it is stored. The git repository of our project is called "pyddg". The cloning of pyddg happens when installing pyddg according to the installation guide (see the `online docs `_), when using the "git clone" command. Branching --------- After having checked out the website "`Branches in a Nutshell `_", you now know what branches are. To summarize it again: A big software project with many people working on it can easily become chaotic. The idea is that you don't want to mess up the main line of development by all the small or specific changes. Instead, you want to contribute your work to the main line of development when you have completed a task. This is what branching is for. In our case, **develop** is the name of the branch on which the latest stable version of pyddg should always be found. **Issue Tracking** The work on the library is managed by issue tracking. **Every task/bug/problem is formulated as an issue** in gitlab which is assigned to somebody. When there does not exist an issue for a task, it probably should be created. Every project member has the permission to do so. **Related Branch** Every issue (concerning the repository) has a **related branch**. All the changes in the repository corresponding to an issue will take place on its branch. When you are assigned to an issue that does not have a related branch yet, **create one** by clicking on the little arrow next to "create merge request" and selecting "create branch". The default **source branch** for every new branch is develop. That means the new branch is a copy of develop in its current state. You can also use other branches as a source. Committing ---------- When using the **git commit** command, a snapshot of the repository in its current state on your branch is taken and stored. That makes it possible to recover this version of the repository afterwards. Commits should be based on **logical units**, as for example completed subtasks. It is important to commit your work early and often to get a clear version history of your code. When committing, you must specify which of your changed files are affected. **git add** If you want to add a file to the commit, use git add to add a file to the so called **staging area**. That means the files are gathered and wait to be committed together. .. code-block:: bash git add **git checkout** If you want to discard the changes in a file, use **git checkout**. These files will be restored according to their previous version. .. code-block:: bash git checkout After specifying which changed files in your repository are taken into account, you can commit your work with the **git commit** command (see below). **Commit Messages** Each commit requires a commit message, which summarizes the changes that happened in this commit. You can add the commit message to the commit command by using the option '-m' with the message as a string. .. code-block:: bash git commit -m 'commit message' **Vim** If no commit message is specified in the commit command, the editor **vim** will launch and ask you to write one. If you don't know how to use vim, you may panic because you won't be able to write anything or get out. Luckily, you just need to know few commands to add your commit message and leave. 1. Switch to insert mode by typing **i** 2. Now you can write your commit message 3. Get out with first pressing **escape**, then typing **:wq!** for 'write & quit!' and **enter**. Your commit is completed! **Commit Message Conventions** For a better overview, all commit messages should follow our conventions. See the docs :ref: `commit-conventions`. Switching to another Branch ~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is best, to switch to another branch when your working area is clean and you committed or checked out all changed files. Then you can easily use the git checkout command to switch to a branch: .. code-block:: bash git checkout name-of-branch If you don't want to clean up the mess before you check out, check out this `page of the git book `_. Transferring Data between Local & Remote Repository --------------------------------------------------- You have already learned that the git repository is stored on each developer's local server as well as on a remote server. As a consequence, it will happen that one version of the branch is ahead of the other. The **git pull** and **git push** commands are for transferring data between these two versions and updating the one who is behind. To find out about the status of your local branch with respect to its remote version, you need the **git fetch** and **git status** commands. **git fetch** That's the first thing you do when you want to check repository. This command downloads the data of the remote repository - without changing your local one. That means your local repository now knows the current state of the remote one. .. code-block:: bash git fetch **git status** The second thing you do is use the git status command. It tells you which branch you are on, as well as whether your branch is ahead of, behind of, or up to date with its remote version. .. code-block:: bash git status **git push** When working on a branch and committing every now and then, your local branch will be ahead of its remote version. The git push command transfers the commits of your local branch to the remote server. When pushing, the code runs through the pipeline mentioned earlier. In the pipeline the changes in code are checked through automatic tests before the remote version of the branch is updated. If the tests fail, the developers will be notified. If the tests pass, the changes will be accepted. It is important to push to the server often, so your code is stored in a safe place. Also, the latest version of your branch is made accessible to other developers. They could be interested in the latest version of your work, since they may want to use part of it. Note, that you can't push to develop. This is our protected stable branch we use for deployment of pyddg. Only maintainers can operate on that branch. .. code-block:: bash git push **git pull** There is always a lot going on on the branches of pyddg's repository. Busy developers will push their work frequently and supply new features. That's why you should regularly use fetch and status to check whether you are behind. If you are, you can use the git pull command. It downloads the remote version of your current branch and updates your local branch with the changes of the new version. .. code-block:: bash git pull Merging Branches ---------------- If you are working on branch1 and want to use new features of branch2, you need to merge branch2 into branch1. This can happen, if for example, you took a long time working on an issue and the usage of functionalities you are using has changed. In this case, you may need to merge develop into your branch. You can do so, by switching to the branch you are working on and merging the other branch: .. code-block:: bash git checkout branch1 git merge branch2 Take a look at the page of the git book about `basic branching and merging `_. Here, it is explained very well! Note, that you can merge develop into your branch but you can't merge into develop, since only maintainers have the permission to do so. When you have finished your work, you have to create a **merge request** (as explained in :ref:`workflow`). **Merge Conflicts** If the same part of the same file in two branches is changed differently, git can not decide which of the parts is the right one to keep. In that case, the merge can't happen automatically and has to be done manually. Use **git status** to check, which files are unmerged. In these files, you will now find both versions of the code. The version of your current branch is marked as "HEAD". For each conflicting part, **choose one version or combine both**. When all conflicts are resolved, use **git commit** to complete the merge. Useful Git Commands ------------------- A collection of some useful git commands. Reverting changes ~~~~~~~~~~~~~~~~~ - revert all **uncommitted changes** on current branch .. code-block:: bash git reset --hard HEAD - set branch to exactly **match the remote develop branch** .. code-block:: bash git fetch origin git reset --hard origin/develop - revert **last merge commit** on develop .. code-block:: bash git revert develop -m The ```` is the index of the hash behind ``Merge: ...`` in the log obtained by .. code-block:: bash git log -n 1 Git Overview ------------ Further, the following webpages can be helpful: - https://git-scm.com/book/en/v2 - https://www.atlassian.com/git/tutorials/learn-git-with-bitbucket-cloud