# Collaboration [TOC] ## Introduction Effective collaboration and branch management are fundamental aspects of any successful software development project. **Key points:** 1. Identifying your collaboration needs: Understand the specific requirements of your project that necessitate collaboration. 2. Setting up a contribution workflow: Establish clear guidelines for how contributors can participate in your project. 3. Documenting the workflow: Ensure that your collaborative workflow is well-documented. ## Branches In (collaborative) software development, branch management is useful when using versioning control and GitHub. Creating a new branch offers an isolated workspace for any task, whether it's adding a new feature or addressing a bug, regardless of its scale. The core advantage of branching is that it provides separate, dedicated environments for code development to both individuals and teams, independent of the main codebase. This approach enables parallel development streams, allowing for experimentation and modification without impacting the stable main version of the project. This approach is also valuable for projects with just one developer! Adopting a branching strategy is about establishing a set of practices that govern code writing, merging, and release processes within a version control environment. It provides a structured framework, ensuring smooth collaboration and efficient management of the shared codebase. :::success :bulb: **Consideration** For open source projects, details about the branching strategy, how to collaborate and contribute can be communicated in the repository's **contributing guidelines** in the file `CONTRIBUTING.md`. - eScience Center - [Example project contributing guidelines](https://github.com/eWaterCycle/ewatercycle/blob/main/CONTRIBUTING.md) - GitHub - [Documentation contribution guidelines](https://github.com/github/docs/blob/3ef0cdb56f166d9da2cb03229af48df34096fa97/.github/CONTRIBUTING.md) ::: ### Branch models There are various branch management workflows developed, but a recommendation for research software would be to use GitHub Flow or Gitflow. [GitHub Flow](https://docs.github.com/en/get-started/using-github/github-flow) is a simplified and straightforward workflow, relying on a single `main` branch. Developers create feature branches off of the master branch, work on their changes, and then merge them back into the master branch via pull requests. The process is built around the principle of continuous collaboration, and it is particularly useful for projects where regular updates and deployments are common. [Gitflow](https://nvie.com/posts/a-successful-git-branching-model/) involves two main branches: `main` and `develop`. Developers create feature branches off of the develop branch. Once a feature is complete, it's merged back into the develop branch. In short, GitHub Flow is simpler and more suitable for projects that prioritize continuous integration and deployment, while Gitflow offers a more structured approach for managing larger projects with distinct release cycles and versioning requirements. For research software, both approaches can be used, depending on the projects needs. :::info :book: **Further reading** - [GitHub Flow getting started](https://docs.github.com/get-started/quickstart/github-flow) - [Introduction GitHub Flow](https://education.github.com/experiences/series_intro_github_flow) ::: ### Branch management in action #### Personal projects and small teams GitHub Flow model: - Typically start with just the `main` branch. - Use branches for unfinished/untested ideas. - Use branches when you are not sure about a change. - Add [**tags**](https://git-scm.com/book/en/v2/Git-Basics-Tagging) to mark important milestones. ```mermaid %%{init: {'theme': 'base', 'gitGraph': {'showCommitLabel': false}}}%% gitGraph LR: commit commit branch "feature A" checkout "feature A" commit commit type:REVERSE checkout main commit branch "feature B" checkout "feature B" commit commit commit checkout main merge "feature B" commit tag:"Paper submission" ``` When applying this workflow for projects with a few persons, *you accept things breaking sometimes*. For projects with a few persons, where more control is required, follow: - The `main` branch is write protected. - You create new feature branches for changes. - Changes are reviewed before they are merged to the `main` branch. - Only merges to main branch through pull requests (and optionally code reviews). ::::spoiler :question: What is the difference between `master` and `main` branches? :::info GitHub decided to rename the default branch from `master` to `main` for new repositories after October 2020. This change was part of a broader industry move to replace terms that may be considered insensitive or non-inclusive. It's important to note that while the terms `main` and `master` refer to the default branch in a repository, they are functionally the same. Be aware that repositories created before October 2020 may still use `master` instead of `main`. ::: :::: #### Distributing releases When you need to distribute releases, your `main` branch will serve as the latest stable version. To avoid - Gitflow model - The `main` branch is protected and read-only. - You set up a `develop` branch for active development. - Create feature branches of the `develop` branch. - Merge feature branches (through Pull Requests) back to `develop`. - Only merge `develop` into `main` when releasing a new stable (and tested) version. ```mermaid %%{init: {'theme': 'base', 'gitGraph': {'showCommitLabel': false}}}%% gitGraph commit tag:"v0.1.0" branch develop commit checkout develop commit commit checkout main merge develop tag:"v0.2.0" checkout develop commit commit checkout main merge develop tag:"v0.3.0" checkout develop commit commit ``` #### Add additional supporting branches When a critical bug in a production version must be resolved immediately, a `hotfix` branch may be branched off from the corresponding tag on the `main` branch that marks the production version. After fixing, `hotfix` is then merged with both `main` and `develop`. ```mermaid %%{init: {'theme': 'base', 'gitGraph': {'showCommitLabel': false}}}%% gitGraph commit tag:"v0.2.0" branch develop commit commit commit commit checkout main branch hotfix commit commit checkout develop merge hotfix checkout main merge hotfix tag:"v0.2.1" checkout develop commit commit checkout main merge develop tag:"v0.3.0" ``` :::spoiler :eyes: The complete Gitflow model in action. ![Full Gitflow model](https://nvie.com/img/git-model@2x.png) ::: :::info :book: **Further reading** - Code Refinery - [Branching models](https://coderefinery.github.io/git-branch-design/05-branching-models/) - GitHub - [Branch protection rules](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule) - [Tag names following semantic versioning](https://semver.org/) - [GitHub tags and releases](https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases) ::: ## Collaborative workflow Following the GitHub Flow model, everything starts from the `main` branch. Developers can create feature branches from the main branch to isolate their work. Once ready, changes are merged back to `main`. A common workflow in a collaborative development project. 1. **Create a feature branch:** Start by creating a new branch off the main project (usually called main or master). This branch should have a descriptive name to give an idea of the work that will be done, such as a new feature or a bug fix. This separation allows you to work independently without affecting the main codebase. 2. **Make changes and commit:** Work on your branch, making the necessary changes to the code. Commit these changes with clear, descriptive messages. 3. **Open a pull request:** Once you have made your changes, open a pull request (PR). During this step your changes are reviewed before they are merged into the main branch. PRs allow for discussion, review, and additional changes if necessary. 4. **Review and deploy:** Before merging, your changes might go through a review process where other team members can give feedback. Some projects may require a review before merging is allowed. After review, you might deploy your changes to a staging or testing environment to ensure everything works as expected. 5. **Merge:** Finally, once your changes are reviewed and tested, you can merge the pull request into the main branch. This incorporates your contributions into the project, making them part of the official codebase. 6. **Delete feature branch:** Feature branches should be short-lived, thus avoiding potential conflicts due to the divergence of the code. :::spoiler Sequence diagram of workflow ```mermaid sequenceDiagram participant A as Author participant R as Reviewer A->>A: Write some code in (forked) branch A->>R: Open a pull request R->>R: Add comments to a review R->>A: Submit a review loop Until approved A->>R: Address or respond to review comments R->>A: Clarify or resolve comments end R->>A: Approve pull request A->>A: Merge pull request A->>A: Delete branch ``` ::: #### Forking External collaborators who do not have the same administrative rights to the repository can fork the project. They make their changes on their forked repository in a new feature branch. Steps 3-5 remain the same. :::success :bulb: **Tip!** You can create "Draft" Pull Requests. With Draft PR's you - want to signal that a pull request is just the start of the conversation and your code isn’t in any state to be judged. - have no intention of ever merging it, but you’d still like people to check it out locally and give you feedback. - opened a pull request without any code at all in order to get the discussion started. For more information, check out [Introducing Draft Pull Requests](https://github.blog/2019-02-14-introducing-draft-pull-requests/). ::: ### Conflict resolution Effective conflict resolution ensures that changes can be integrated smoothly and that the project remains on track. Conflicts occur when two or more changes compete with each other, typically during a merge or rebase operation in Git. By utilizing pull requests code review and testing yoiu can catch potential conflicts before they are merged into the main codebase. Conflicts usually come up and are resolved during a pull request: 1. **Review Conflicts:** When a conflict is detected in a pull request, GitHub will alert you. Start by reviewing the conflicting files to understand the nature of the conflict. 2. **Pull and Merge Locally:** Fetch the latest changes from the `main` branch and attempt to merge them into your `feature/develop` branch locally. This will allow you to resolve conflicts on your local machine. Check status with `git status` and `git diff`. 3. **Resolve Conflicts:** This might involve choosing one change over another or merging the changes manually. 4. **Test Changes:** After resolving conflicts, thoroughly test your changes to ensure that the merged code works as expected. 5. **Commit and Push:** Once conflicts are resolved and changes are tested, commit the resolved conflicts and push your changes back to the `feature/develop` branch on GitHub. 6. **Complete the Pull Request:** After resolving conflicts and pushing your changes, review the pull request again to ensure everything is in order. If all checks pass and your team approves the changes, you can complete the merge into the main branch. Essentially, the key to conflict resolution is avoiding them, and clear communication and adherence to established practices is the way to go. :::info :book: **Further reading** - GitHub - [Resolving a merge conflict](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github) - Code Refinery - [Lesson on conflict resolution](https://coderefinery.github.io/git-intro/conflicts/) :::