*********** How To: Git *********** Main concept ============ We assume, that you know what ``git`` is and how it is basically used. Otherwise, there are plenty tutorials. This paragraph is more about the branching and release / testing strategy. Concerning the branching, it is mainly based on the following articles: `A successful branching model `__ by Vincent Driessen and `Gitflow workflow `__ by Atlassian. Both references might give you a deeper understanding. There will be the following main branches: #. **develop**: this will be the main development branch, where new features will be merged in and new releases are branched off #. **feature/***: these are multiple feature branches like ``feature/count_to_infinity`` and ``feature/charge_faster``. So when starting a new feature, branch off the develop branch using ``git checkout -b feature/new_stuff develop`` and start working. Depending on the complexity of the feature, a feature branch might live for a long time and consist of a lot of commits or it might be a small one with only one commit. It is advised to keep it as short as possible, so it can be tested inside the develop branch. TOWRITE: * single commits should be stable if fast-forward commit should be done * public/private * when to rebase #. **release candidate / bugfix**: * for every release candidate a new branch like ``rc/0.1`` will be branched off from development. No new features should merged in, only bugfixes, that might come up during testing. When testing is finished, the release candidate will be branched of to a release branch, that gets tagged. * simple bugfix branches like ``bugfix/div_by_zero`` will be used for fixing bugs TOWRITE: * release strategy * how to test release candidates * versioning * back-merging of bugfixes inside the release candidate branches #. **release**: Once a release candidate has succeeded in all testing, the release branch like ``release/0.1`` will be created and should be assumed as stable. Furthermore this branch will be used to keep track of shipped releases. So once a bug will be reported in production, that needs to be fixed also in the production version. That bugfix should be done on the release branch by branching off a hotfix. #. **hotfix / maintencance**: These branches like ``hotfix/forgot_to_unplug`` will be used as bugfix branches which will act directly on the release branch, so they can be send back to production immediately. After finishing the fix, it gets merged back to its corresponding release branch and a new minor version will be tagged. Furthermore it will be merged or cherry-picked to the current release candidate branch or development branch (the decision, which branch to take might be different for each scenario). #. **master**: This branch will point always to the latest release. The idea behind this branch is, that it tracks the latest stable version. In contrast, the develop branch should track the latest unstable version and the release candidate branch tracks the latest testing version. A visualization of the branching structure and the corresponding git commands can be found in the section :ref:`workhorse-example`. It might be a good idea to read through the shell script. You can also execute it, it should create a folder called ``rnd_git_dir``, and play around. Best practices ============== Despite all the best practices you might find online, here are some more: * Always try to create branches for seperate work units If different units of work are intermixed inside one branch, it is harder to seperate commits belonging to different units of works. Also tracking down a specific bug to a single commit gets harder. * If possible, rebase your feature branch against its parent frequently Doing that, merging back frequently rebased branch to its parent becomes much easier and you also keep track of ongoing and related changes that might affect your work. But keep in mind, that you should not rebase public branches, that are used by others - only if you set up a conspiracy * Never rebase public branches Rebasing will rewrite the history and therefor will affect all users, that already checked our the branch. Just don't do it! Tips'n'Tricks for git ===================== * rebase (interactive), self-rebasing * stash * cherry-picking * merge conflicts Using private repositories -------------------------- If you create a local feature branch or some work in progress, and you don't want to put these things into the main repository, but still want to have it backup'd somewhere. You can push this branch to a private repository. Let's say for example, the main repository is located at ``https://github.com/SomeProject/SomeRepo`` and you have a private repository at ``https://github.com/PrivateUser/PrivateRepo``. Furthermore the main repository is checked out in ``/main_repo``, then you can do the following: .. code:: bash /main_repo$ git checkout -b wip/new_stuff develop /main_repo$ # do some work, add and commit /main_repo$ # add private repo as additional remote, called 'private' /main_repo$ git remote add private https://github.com/PrivateUser/PrivateRepo /main_repo$ git push private Now, the branch ``wip/new_stuff`` will be pushed to your private repository. Locally, you can work with that branch like with any other and some day you might merge or push it to the main repository, whose remote name is usually origin. .. _workhorse-example: Workflow example ================= Visualization of the branching structure ---------------------------------------- .. image:: git-workflow.svg Corresponding git commands -------------------------- .. literalinclude:: do_git.sh :language: bash