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¶
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 branches are located on the public repositories, and are labeled
release/2015, etc. They branch from
master once at
feature freeze. They collect patches. All commits to release branches can be
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¶
- Create a fork.
- Clone the fork.
- Create a feature branch. Never commit any changes to master or a release branch.
- Commit to the feature branch.
- Push the feature branch to the fork.
- 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
masterwill 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.
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
$ 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¶
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
First make sure that your clone is really cloned from your fork:
$ git remote -v
origin should now point to your fork - here is an example:
origin firstname.lastname@example.org:user/dalton.git (fetch) origin email@example.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 firstname.lastname@example.org:dalton/dalton.git
Verify that it worked:
$ git remote -v origin email@example.com:user/dalton.git (fetch) origin firstname.lastname@example.org:user/dalton.git (push) upstream email@example.com:dalton/dalton.git (fetch) upstream firstname.lastname@example.org: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 email@example.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 firstname.lastname@example.org:dalton/dalton.git master $ git push email@example.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.