Working with branches and forks =============================== Where are the branches? ----------------------- We have split each of the Dalton and LSDalton repositories into two, a public repository and a private repository. So instead of two repositories we now have four: two public (containing the master and release branches), and two private repositories (containing all other branches):: https://gitlab.com/dalton/dalton/ https://gitlab.com/dalton/dalton-private/ https://gitlab.com/dalton/lsdalton/ https://gitlab.com/dalton/lsdalton-private/ The master branch ----------------- The ``master`` branches on the public repositories are the main development lines. Features should be developed on separate feature branches on the private repositories. The semantics of the ``master`` branch is that everything that is committed or merged to ``master`` is ready to be released in an upcoming release. Release branches ---------------- Release branches are located on the public repositories, and are labeled ``release/2013``, ``release/2015``, etc. They branch from ``master`` once at feature freeze. They collect patches. All commits to release branches can be merged to ``master`` in principle at any moment. We never merge branches to release branches (except when accepting merge requests). ``release/2013`` branch becomes frozen once Dalton 2015 is released. ``release/2015`` branch becomes frozen once Dalton 2016 is released. And so on. How to make changes to master or the release branches ----------------------------------------------------- Never push changes directly to https://gitlab.com/dalton/dalton/ or https://gitlab.com/dalton/lsdalton/. Instead do this: 1) Create a fork. 2) Clone the fork. 3) Create a feature branch. **Never commit any changes to master or a release branch**. 4) Commit to the feature branch. 5) Push the feature branch to the fork. 6) Submit a merge request. You can mark the feature branch to be automatically deleted once the merge request is accepted. make sure that you do not forget any of the following points: - Do not submit unfinished work. - Be aware that everything on ``master`` will be part of the next major release. - Describe your change in the CHANGELOG. - Commits should have the right size (not too small, not too large) - otherwise squash or split changes. - Commit messages should be clear. - Commits should be self contained - Test new code. - Comment new code. - Document new code. - When fixing an issue, autoclose the issue with the commit message. All commits to the master branch should be self-contained, eg. fix a bug or add a new feature, the commit message should clearly state what is achieved by the commit, and each commit should compile and run through the test suite. Long-term developments typically have several commits, many of which break compilation or test cases, and merging such developments directly will both make the git history ugly, and break functionality like ``git bisect''. Such developments should therefore be squashed into one or a few commits. Squashing --------- Assume you are working with two remote repositories "origin" and "upstream" (see how below). You have developed a new feature branch "my_messy_branch" on "origin" and incorporated the changes from "upstream" "master" into it, and would like to merge your changes back to "upstream" "master". First, make a local copy of your branch "my_messy_branch":: $ git branch -b my_clean_branch Second, rebase ``my_clean_branch'' with respect to "upstream" "master":: $ git rebase upstream master Third, make a ``soft'' ``reset'' $ git reset --soft upstream master This step removes all local commits, but leaves the code unchanged. This can be verified with a ``git status''. Fourth, make a commit of all the changes from "my_messy_branch" into one single commit on "my_clean_branch", by a regular ``git commit'', followed by a ``git push origin my_clean_branch'', and a subsequent merge request on gitlab. How to submit a merge request ----------------------------- https://docs.gitlab.com/ee/gitlab-basics/add-merge-request.html Where to keep feature branches ------------------------------ You can either develop them on one of the private repositories (discouraged), or on your fork (encouraged). The fork can be either private or public. How to update feature branches ------------------------------ You have probably cloned from your fork (good!) but from time to time you wish to update your feature branch(es) with changes on ``master``. First make sure that your clone is really cloned from your fork:: $ git remote -v The remote ``origin`` should now point to your fork - here is an example:: origin git@gitlab.com:user/dalton.git (fetch) origin git@gitlab.com:user/dalton.git (push) We encourage you to regard the ``master`` branch as read-only and discourage you from making any changes to the ``master`` branch directly. To update your forked ``master`` branch and your feature branches first add the central repository as an additional remote. You can call it for instance "upstream":: $ git remote add upstream git@gitlab.com:dalton/dalton.git Verify that it worked:: $ git remote -v origin git@gitlab.com:user/dalton.git (fetch) origin git@gitlab.com:user/dalton.git (push) upstream git@gitlab.com:dalton/dalton.git (fetch) upstream git@gitlab.com:dalton/dalton.git (push) Good! Now you can fetch changes from upstream and merge master to your feature branch:: $ git fetch upstream $ git checkout my-feature-branch $ git merge upstream/master $ git push origin my-feature-branch How to update your fork ----------------------- A fork is a clone. It will not update itself. To update your fork you need to pull changes from the upstream repository and push them to your fork. You can do this either by adding an alias to a remote:: $ git remote add upstream git@gitlab.com:dalton/dalton.git $ git fetch upstream $ git checkout master $ git merge upstream/master $ git push origin master Once you realize that "origin" and "upstream" are nothing more than aliases to web URIs you can fetch and push changes directly without defining new remotes:: $ git pull git@gitlab.com:dalton/dalton.git master $ git push git@gitlab.com:user/dalton.git master For other branches it works exactly the same way. For Git, all branches are equivalent. It is only convention to attach ``master`` a special meaning.