Select and document clean git workflow
We need a well-defined git workflow that is not to complicated for contributors to follow. This has been commented on in several merge requests, let's concentrate the discussion into this issue.
Possible workflows
GitFlow
One of the most popular workflows with git is the gitflow workflow, popularized by github. See also the article on a success git branching model for other documentation on GitFlow.
Gitlab low
Gitlab uses the gitlab flow, which seems to be more similar to an SVN based workflow.
CORSIKA 8 considerations
Assuming that CORSIKA 8 will follow a similar release pattern as CORSIKA 7, it would seem that GitFlow would be a good and simple choice. Maintenance on released versions will be minimal, probably only fixing serious bugs. Once a new release is out, development and maintenance of older releases ceases. This means that there is no need for maintenance branches for individual release series.
Other links about git workflows
Feature branch maintenance
Only feature branches can have their history manipulated. The master
branch (and possibly a develop
branch) should not have their history manipulated. In gitlab, they should be protected branches.
Avoid conflicts and overlapping changes: Try to perform only changes corresponding to the topic of the issue or merge request. Do not scratch an itch and change something, just because it is irritating or plain wrong. Also, try to keep commits clean and understandable. Failing to do so can lead to merge problems and makes reviewing a merge request harder.
merge vs rebase
In case of divergences, git has the the possibility to either merge
the branches, with a special merge commit, or rebase one branch onto another. This includes the possibility to rebase a local branch onto the upstream branch in the main repository.
Merges are used to bring the development from a feature branch back into the default (master
or develop
) branch. Merges should be avoided along feature branches.
Pulling: consider rebase
Merge commits created git pull
ing the branch from the main repo can cause conflicts later. This happens if development happened on the local checkout that is not in sync with the repository. This can be avoided by requesting git to rebase instead of merging when pulling. You can either
- Set one of the options
pull.rebase
,branch.<name>.rebase
totrue
, or setbranch.autoSetupRebase
to eitherremote
orall
. More information is in the man-pagegit-config(1)
. - Provide the option
--rebase
togit pull
.
Either option will rebase local changes onto the branch fetched from the repo.
Long lived feature branches
If the development of a feature takes more time, you have to make sure the branch remains mergeable. This could mean that changes from the default branch might need to be incorporated. This should be done rebasing the feature branch, not merging the default branch into the feature branch.
Rewrite history and fine control of commits
Git has several tools for rewriting the history of a branch. This means changing the order and contents of commits. This is typically done to make the history more descriptive and to group changes that logically belong together and so split changes that accidentally ended up on the same branch or even in the same commit.
Selective adding of hunks
If you have accumulated changes in your source directory, you might want to commit them in more than one commit on the branch. In the simplest case, all you have to do is to git add
only some files before committing. If things get messier, you might want to commit only some changes inside a file, line-by-line or hunk-by-hunk. On the command line, you can git add -p
or using the patch menu in git add -i
. This quickly gets tedious, a gui tool like https://www.gitkraken.com/, https://www.syntevo.com/smartgit/, or https://www.sourcetreeapp.com/ (last Mac and Windows only) helps.
--amend
Commit option If you forgot a change, you can do it after committing and then update using git commit --amend
. For more complicated cases, you might have to use the more powerful interactive rebase.
Interactive rebase
More complicated re-writes of the history can be done by the interactive rebase: git rebase -i
. This allows to reorder, merge, split, remove, and edit commits. For example, a change that should have been part of a commit three commits down the branch. You can move it and squash or merge. Or you can use it to separate (and accumulate) cosmetic changes from algorithmic code changes.
Squashing commits
It is possible to squash commits as part of the merge process. This can help if the history is messy, chronological. A cleaner way to get an informative history is to use an interactive rebase before merging. This can result into squashing all commits in the case of simple changes, but keeps the option to group changes logically into more than one commit. In the end, this provides a more informative history.
History rewriting by Developers
Only users with Maintainer or Owner privileges can force update a branch to commit a re-written history. A regular Developer can work around this by first forking the project and requesting a merge from a development branch in their fork.