Skip to content

Git workflow

Stefania Pedrazzi edited this page Jun 27, 2022 · 24 revisions

Branching model

http://nvie.com/posts/a-successful-git-branching-model/

The git tagging system allows us to freeze efficiently instant where we need to create packages (and release candidate to test).

Every commit to the develop or master branch should be done through a moderated Pull Request.

Here is what can be committed to the different branches:

  • develop may receive new features, any change that breaks the binary compatibility and large code refactoring.
  • master may receive bug fixes, optimizations, clean-up that doesn't break the binary compatibility and documentation improvements that refer to the current release and which will be immediately published on Cyberbotics's web site as soon as they are merged.

Branch naming

New branches should be named according to the following syntax: <prefix>-<subject> where prefix should be one of the following:

hotfix: for a urgent enhancement/fix/doc/feature fix
fix: for a bug fix
doc: for a new documentation work
feature: for a new feature
enhancement: not a fix nor a feature (typically a code refactor)
update: for an update (cache files or release version for example)
cleanup: for removing unused files, comments, etc.

and subject should describe the issue explicitly, e.g., avoid subjects like "issue-89". It should be composed only of lowercase alphabetical characters, digits and dash signs (-) to separate worlds. The corresponding pull request should keep the same name as the branch. Examples of branch names:

hotfix-add-missing-texture-in-nao-appartment
fix-touch-sensors-without-physics-fail-with-ode-mt
doc-new-ros-tutorial
feature-procedural-protos

Regular workflow

while (workingOnWebots) {
  if (hotfix) {
    # Bug fixes, optimizations, clean-up
    # Enter in the master branch
    git checkout master
    # Update the master branch
    git fetch origin
    git merge origin/master
    git submodule update
  } else {
    # New features, changes breaking binary compatibility, code refactoring, etc.
    # Enter in the develop branch
    git checkout develop
    # Update the develop branch
    git fetch origin
    git merge origin/develop
    git submodule update
  }

  # Create a new feature branch
  git checkout -b <my-new-feature>
  # verify the branches list
  git branch

  # modify and commit files
  while (required) {
    while (required) {
      -> modify files
      git diff <modified-files>
      git status
    }

    # added files to the stage
    git add <modified-files>

    # monitor the already committed files
    if (required)
      git diff --staged <modified-files>

    # commit files
    # note: commits are local
    git commit [<modified-files>] -m "<My detailed comment>"

    # push the branch on the remote repository if required
    if (sometimes or lastCommit) {
      git push origin <my-new-feature>
      -> Check it was updated on GitHub
    }

    # Create the Pull Request (PR)
    # This is can be done at an early development stage to open the
    # discussion with the colleagues, share a todo list and/or a description
    # of the aims. In such a case, the PR should be opened as a draft PR.
    # From GitHub: find the "Compare and Pull Request" button
      -> if (hotfix)
           select base: master and compare: <my-new-feature>
         else
           select base: develop and compare: <my-new-feature>    

    if (lastCommit) {
      -> If the Github "Merge" button is unavailable because GitHub detected
         a merge conflict, the developer should fix it:
      if (mergeButtonDisabled)
        continue
      -> The developer should check by how many commits her branch is behind the
         develop (displayed as "behind" on the GitHub branches page) and evaluate
         the risk of bugs arising from possible logic conflicts (as opposed to merge
         conflicts which are well managed by GitHub ).
      if (developerUnsureAboutPossibleLogicConflict) {
        -> The developer should merge the current `develop` with her branch:
        git merge origin/develop
        git push origin <my-new-feature>
        -> and test her code again, if the test fails, she should fix the problems.
        if (testFail)
          continue
      }

      if (importantChanges) {
        launch a test suite test manually by adding the "test suite" tag to the PR
        other test tags are described in the "CI Test Labels" wiki page
      }

      -> The developer can mark the PR as ready for review (if the PR was a draft)
         and ask for a review (to a cyberbotics/development-team member, or a specific
         developer, or several specific developers) when the PR is completed and ready
         for review.
      -> The reviewer can post a review icon (":eyes:") when he starts the review
         (to avoid that multiple developers review at the same time) or simply assign himself as reviewer
         and start the review.
      -> If a PR is not any more ready for review (e.g., the developer is working on
         it following up a comment), it should be set back to a draft. Removing and
         re-adding the reviewer(s) should be avoided.
      -> When the PR is ready for review again, the developer must ensure this is clear
         for the reviewer: either a new review is explicitly requested or a message should
         be posted answering the comment and saying the PR is ready for review again.
      -> When a PR is approved, the author can merge it (if nobody else marked that he
         is reviewing the PR)
      -> If more than one review is required, a comment should be posted asking for a
         second (or third reviewer) once the first reviewer accepted the PR.
      if (the PR can be merged) {
        # The developer merges the PR from the GitHub GUI.
        # GitHub will automatically delete the corresponding branch.
        # The developer can delete her local branch if any.
        # Delete the local branch
          git checkout master
          git fetch
          git pull
          git branch -d <my-new-feature>
        }
        if (hotfix) {
          # update develop branch
          -> open a new PR from GitHub GUI (green button in 'Code' or
             'Pull Request' page) to merge origin/master into origin/develop
          -> set 'base' to 'develop' and 'compare' to 'master' before pressing
             the 'Create Pull Request' button
          if (mergeButtonDisabled) {
            -> The developer has to close or abort the creation of this second PR
            -> create a new branch <merge-master-into-develop> based on the
               'develop' branch
            -> merge with origin/develop and fix conflicts
            -> create a PR that merges into 'develop'
          }

          -> The developer has to ask for a review to a cyberbotics/development-team
             member, or a specific developer, or several specific developers.
          -> The reviewer has to submit a review.
          -> Once the PR is approved, the developer can merge it.
          -> if a branch was created, GitHub will automatically delete it.
        }
      }
      else { // not accepted
        The reviewer should explain what's wrong with the PR and use as much as
        possible 'change suggestions'.
      }
    }
  }
}

Release workflow

Current release → master

The master branch should always be ready to create a distribution of the current release. When all the issues referring to the revision milestone are closed (or moved to another milestone), a new PR should be open containing a tick-box list of all the tests needed before a release can be published, e.g, change log update, QA tests and test suite for all platforms. Once this PR is accepted and merged, the release can be published.

Major release → develop

The develop branch should always contain a stable version of the upcoming major release of Webots. When all the issues referring to a major release milestone are closed (or moved to another milestone), a new PR should be open to merge the develop branch into the master branch. The PR should contain a tick-box list for all the test needed before a release can be published, e.g, change log update, QA tests and test suite for all platforms. Once this PR is accepted, the release is published and the develop branch is merged in the master branch.

Useful git tricks

Branch with multiple developers

Get locally an existing remote branch:

git fetch origin
git branch <her-new-branch> origin/<his-new-branch>
git checkout <her-new-branch>
-> apply the regular workflow

Switch between branches

It is highly recommended to commit (even simply locally) the changes before switching branches. Otherwise, a conflict has to be managed (the conflict is simply that the uncommitted files are also present to the target branch)

# list the branches
git branch
# switch
git checkout <expected-branch>

More information here: http://www.gitguys.com/topics/switching-branches-without-committing/

Git ignore

Ignoring files is managed by adding .gitignore files.

# .gitignore file

# rule applied recursively
*.o

# rule applied locally
/*.class

# exception breaking the recursion
!foo.o

Complete documentation: http://git-scm.com/docs/gitignore

Revert a commit

# to get the commit id, either look at the PR commits or type
git log

git revert dd61ab32
# if the commit is on the remote, then the next push will revert it:
git push origin <my-feature>

Prune your local fork

When a branch is deleted in remote (typically after merging a PR or explicitly deleting a branch on GitHub), a stale branch can stay locally. This can be annoying when auto-completing, and using git branch -a. The following command allows you to clean your local directory.

git remote prune origin

Using regularly the -p argument when fetching the remote repository allows us to avoid this issue:

git fetch -p

To cleanup the local tags and synchronize with the remote repo you can type these commands. First delete all the local tags and the get the tags back from the remote server.

git tag -l | xargs git tag -d
git fetch --tags

Create a release tag

git tag -a vX.Y.Z -m "Webots X.Y.Z"
git push origin vX.Y.Z
Clone this wiki locally