DEV Community

Cover image for The Different Types of Collaboration Workflows in Git
Mustafa Hashmani
Mustafa Hashmani

Posted on • Originally published at mustafahashmani.hashnode.dev

The Different Types of Collaboration Workflows in Git

Centralized Workflow

  • AKA Everyone Works On Master/Main
  • AKA The Most Basic Workflow Possible
  • The simplest collaborative workflow is to have everyone work on the master branch (or main, or any other SINGLE branch).
  • It's straightforward and can work for tiny teams, but it has quite a few shortcomings!
  • Pamela, Forrest and David clone the repo
  • Forrest gets to work on a new feature and pushes his work to Github
  • At the same time, Pamela also worked on a new feature. She tries to push her new work up to Github, but she runs into trouble as the current branch is behind its remote counterpart. So she pulls to get the changes from origin master, merges them and then pushes them
  • David is working on a new feature, but is having some doubts. He'd like to share his commits with the rest of the team to start a discussion but before he can commit he has to pull from Github and merge them into master Now he can finally push his work up to Github. His teammates can pull to get his new commits.

    The Problem

    While it's nice and easy to only work on the master branch,
    this leads to some serious issues on teams :

    • Lots of time is spent resolving conflicts and merging code, especially as team size scales up.
    • No one can work on anything without disturbing the main codebase. How do you try adding something radically different in? How do you experiment?
    • The only way to collaborate on a feature together with another teammate is to push incomplete code to master. Other teammates now have broken code...

Feature Branches

  • Rather than working directly on master/main, all new development should be done on separate branches!
    • Treat master/main branch as the official project history
    • Multiple teammates can collaborate on a single feature and share code back and forth without polluting the master/main branch
    • Master/main branch won't contain broken code (or at least, it won't unless someone messes up)
  • Pamela, Forrest and David clone the repo
  • David starts work on a new feature. He does all this work on a separate branch!
  • David wants Pamela to take a look at his new feature. Instead of merging it into master, he just pushes his feature branch up to Github!
  • Pamela is hard at work on her own new feature. Just like everyone else, she's working on a separate feature branch rather than master.
  • Pamela hears from David that he wants her to take a look at his new work. She pulls down his feature branch from Github.
  • Pamela takes a look at the code and makes a couple of improvements of her own. She adds/commits on the same feature branch.
  • Pamela pushes up her new work on the add-dark-theme feature branch so that David can pull them down.
  • David fetches from Github and sees that there is new work on the add dark theme branch. He pulls the changes down and continues work.
  • David decides he is happy with the new feature, so he merges it into master!
  • David pushes up the updated master branch to Github. The others can now pull down the changes.

    Feature Branch Naming

  • There are many different approaches for naming feature branches. Often you'll see branch names that include slashes like bug/fix-scroll or feature/login-form or feat/button/enable-pointer-events

  • Specific teams and projects usually have their own branch naming conventions.

    Merging In Feature Branches

    • At some point, the new work on feature branches will need to be merged into the master branch! There are a couple of options for how to do this :
      • Merge at will, without any sort of discussion with teammates. JUST DO IT WHENEVER YOU WANT.
      • Send an email or chat message or something to your team to discuss if the changes should be merged in.
      • Pull Requests!

Pull Requests

  • Pull Requests are a feature built into products like Github and Bitbucket. They are not native to Git itself.
  • They allow developers to alert team-members to new work that needs to be reviewed. They provide a mechanism to approve or reject the work on a given branch. They also help facilitate discussion and feedback on the specified commits.
  • "I have this new stuff I want to merge into the master branch...what do you all think about it?"

    The Workflow

1. Do some work locally on a feature branch
2. Push up the feature branch to Github
3. Open a pull request using the feature branch just pushed up to Github
4. Wait for the PR to be approved and merged. Start a discussion on the PR. This part depends on the team structure.

### Merging Pull Requests with Conflicts

- Just like any other merge, sometimes there are conflicts that need to be resolved when merging a pull request.
- You can perform the merge and fix the conflicts on the command line like normal, or you can use Github's interactive editor.
Enter fullscreen mode Exit fullscreen mode

Image

Fork and Clone

  • The "fork and clone" workflow is different from anything we've seen so far. Instead of just one centralized Github repository, every developer has their own Github repository in addition to the "main" repo.
  • Developers make changes and push to their own forks before making pull requests.
  • It's very commonly used on large open-source projects where there may be thousands of contributors with only a couple of maintainers.
  • It allows a project maintainer to accept contributions from developers all around the world without having to add them as actual owners of the main project repository or worry about giving them permissions to push to the repo

    Forking

    • Github (and similar tools) allow us to create personal copies of other people’s repositories. We call those copies a "fork" of the original.
    • When we fork a repo, we're basically asking Github "Make me my own copy of this repo please"
    • As with pull requests, forking is not a Git feature. The ability to fork is implemented by Github.
    • When you click on the fork button on that repository, it will create a copy on your account
    • Now that I've forked, I have my very own copy of the repo where I can do whatever I want!
    • I can clone my fork and make changes, add features, and break things without fear of disturbing the original repository.
    • If I do want to share my work, I can make a pull request from my fork to the original repo.

    Workflow

    • When we clone a repo, Git automatically adds a remote called origin that points to our forked repo on Github.
    • Next, I add a remote pointing to the original project repo
      (NOT the fork). This remote can be named anything, but
      you'll often see "upstream" or "original" used.

      git remote add upstream <url>
      
    • I do some new work locally. To share my changes with others, I cannot push to upstream. I don't have permission! But I can push to origin (my Github fork)

    • Next, I can make a pull request from my fork on Github to the original project repository. Now I wait to hear from the project maintainers! Do they want me to make further changes? It turns out they accept and merge my pull request!

    • The next day, I get back to work. The official project repo now contains work done by other collaborators. I don't have their new work on my machine! I'm behind!

    • All I need to do is pull from upstream (the original repo) to get the latest changes in my local repo.

    • Now I have the latest changes from the upstream repo! I can work on some new features locally without working about being out of date.

Image

### Summary
Enter fullscreen mode Exit fullscreen mode
  1. I fork the original project repo on Github
  2. I clone my fork to my local machine
  3. I add a remote pointing to the original project repo. This remote is often named upstream.
  4. I make changes and add/commit on a feature branch on my local machine
  5. I push up my new feature branch to my forked repo(usually called origin)
  6. I open a pull request to the original project repo containing the new work on my forked repo
  7. Hopefully, the pull request is accepted and my changes are merged in!

Top comments (9)

Collapse
 
dasheck0 profile image
Stefan Neidig

Bigger teams often rely on git flow, which is a popular branching model. It comes with feature branches, as you mentioned, but also has hotfix and release branches to cover most of the production related needs.

Collapse
 
tandrieu profile image
Thibaut Andrieu

Gitflow has a little success back in the 2015’s, especially with the git-flow CLI tool. It is today more and more criticized for its complexity and the latency it introduced in integration.

Personally, I prefer Trunk Based Development. Small feature branch with very short lifetime, and commit directly to master for very small modifications. I've applied this branching model in projects from 2 to 20 developers. It works well as long as everyone assume their responsibility.

Collapse
 
dasheck0 profile image
Stefan Neidig

Wasn't aware of that. Thanks for shedding some light on it. We use it on our projects and it works quite well.

Collapse
 
mustafahashmani profile image
Mustafa Hashmani

Exactly! It is also easy for beginners to understand and get used to

Thread Thread
 
tandrieu profile image
Thibaut Andrieu

To go further, I did a comparison of some git branching model here:
kissyagni.com/2022/03/14/an-overvi...

Thread Thread
 
dasheck0 profile image
Stefan Neidig

Was wondering how you would realize production hot fixes with trunk based branching model. Let's say we have a production version denoted by commit abc. We then release this to the app store (or deploy it on production server) and continue development. So a new feature and some improvements are integrated making xyz the new head on master. We now find a bug, that needs to be fixed asap but we do not want to ship any new features. How would I do this? Would I checkout abc again and branch from there or would I "hide" the new features when starting from xyz?

Thread Thread
 
tandrieu profile image
Thibaut Andrieu

You create a branch when you release a version.
Let say, I have the master, where all the work is done. My product follow a quaterly based release cycle. So I would create branch "2023.1" for january release, "2023.2" in april, etc... I can also put a tag "2023.1.0".

If I need a hotfix on 2023.1, I can add it to 2023.1 branch and then put a tag "2023.1.1". Tags ensure to keep track of what has been delivered. Branches are there to handle hotfixes. That's why you need both.

The point is to not merge or rebase the "release" branches. They are just there to handle hotfix. If everything goes well, these branches don't even contains any specific commit (or maybe just the commit that update version, changelog, etc...).

Thread Thread
 
dasheck0 profile image
Stefan Neidig

I see makes sense. So in a way this is git flow lite. Thanks for clarifying

Collapse
 
mustafahashmani profile image
Mustafa Hashmani

Thankyou for Sharing this. Never knew about git flow but will research about it