3

I am working on a site with other three developers.

We are all working on different features for the same site.

We are having conflicts with project config files, since we are merging our changes into the main branch at different "random" times, and this makes our project config folder have added and deleted files each time another member does a push or fetch to/from main.

How do you recommend organizing the team workflow so that we don't run into this problem while having multiple people which are working on multiple branches?

I have been trying to understand where the conflict comes from, so:

  • Person A creates a new field or changes a setting, it gets reflected into the database and into the project yaml files.
  • Person A commits and pushes changes into main.
  • Person B fetches the changes while still working on two different branches locally.
  • Craft asks for a project config update but then a bunch of project config files get deleted, and others added.
  • And what's even worse, if person A did a pull request to main but wants to work on a different branch before that pull request gets merged, changing to another branch will also result in "pending changes"

This is very confusing, and a minor error can lead to total disaster, having to redo all the lost fields and settings.

1 Answer 1

7

Your trouble comes from working in the main branch directly, don't do that. Instead, follow a feature branch workflow where every feature is developed in a dedicated branch. This way, every developer can work in their own branch without other people interfering. You can even configure branch protection rules in Github (if you're using Github) to prevent everyone from pushing to the main branch directly. Instead, merging finished features is done through pull requests. You can allow developers to merge pull requests as soon as they're opened up, though I highly recommend requiring at least one approving review from another developer. This has the added benefit of having at least two pairs of eyes on every feature that gets introduced to the project, which allows you to catch bugs early and increase everyone's knowledge of the entire codebase.

If you're working in your own branch, other developers merging something into the main branch on the remote won't interfere with your work and you can update your local main branch whenever you want without conflicts. You still might have to fix conflicts between your changes and the changes introduced, but you can do so at your leisure and only need to do so when your feature is done.

With this workflow, the regular process looks a little like this:

  1. Developer A(lice) and B(ob) both start work on a feature. Both create a local branch (feature-a and feature-b, respectively) based on the main branch at this point in time.
  2. While Bob is still working, Alice is done. She pushes her branch to Github and opens a pull request. Charlie reviews the request and approves it, Alice merges it into main (and deletes branch-a on Github). Now Alice can checkout the main branch locally, pull the merged changes from Github and delete her feature-a branch. Now she can create a new branch for the next feature she is going to work on based on the current main.
  3. Now Bob is finished with his feature. Once all his changes are committed in feature-b, Bob checks out the main branch and pulls the latest changes. Then he checks out feature-b again. Now he can either merge main into his branch (git merge main) or rebase his branch on main (git rebase main). Both of those operations will perform a three-way merge by default and report any conflicts. Oftentimes, there won't be any conflicts, in this case Bob can continue to open a pull request.
  4. Let's assume there are conflicts. Now is the time to resolve them, the same way you would resolve other conflicts in git. Once all conflicts are resolved, Bob has a branch that's either rebased on main or has the latest changes from main merged into it, so it includes both the first feature Alice worked on and the feature Bob worked on. Now Bob can open a pull request that won't result in any conflicts.

The key to not get other people's config changes as uncommitted changes in your working directory is to apply the config every time you change branches. That means:

composer install
php craft project-config/apply
php craft migrate/all

By the way, you can usually skip step 3 with no problems. If you open a pull request without having pulled the latest changes from main, Github will tell you if you can merge the PR without causing any conflicts. If Github reports no conflicts, you can just merge the PR which performs a three-way merge directly on the remote. If you do get conflicts, you can proceed to do step 3 (pull changes from main and merge/rebase).

And what's even worse, if person A did a pull request to main but wants to work on a different branch before that pull request gets merged, changing to another branch will also result in "pending changes"

You just need to use php craft project-config/apply after switching branches, to make sure your development environment matches the state of the branch you're working on now.

4
  • 1
    Vielen Dank Moritz! This is clearly an amazinlgy clear answer! Really helps. How would you go about this case: Bob works on feature-a and edits a field which causes an edit to a specific project file (let's call it specific-file.yaml). Then Bob does a pull request on feature-a. Then Bob wants to work on feature-b before feature-a gets approved. When Bob checks out feature-b, it will appear that specific-file.yaml has been edited (since it now contains different content). Then Alice approves the pending Pull Request but Bob has now a wrong content for specific-file.yaml which will cause issues. Mar 1 at 11:17
  • 1
    @ÁlvaroFranz Always use project-config/apply after switching branches. After opening the PR, if Bob wants to work on a new feature, he first checks out main and uses project-config/apply. Now the changes in the feature-a branch are gone from his working dir and his local installation and he can work on feature-b without problems. If feature-a is merged while Bob works on feature-b, he can do the rebase/merge (step 3 & 4) once he' finished, which usually won't result in any conflicts.
    – MoritzLost
    Mar 1 at 11:30
  • 1
    @ÁlvaroFranz A special case is if feature-b depends on feature-a. In this case, Bob can base the feature-b branch on feature-a, which means he can continue to work on a feature that require the changes from feature-a even while feature-a is in review. Once feature-a is merged, it's again time to rebase feature-b on main. It's also important that every developer has a good understanding of Git, in particular the branching model, to be able to use this workflow effectively.
    – MoritzLost
    Mar 1 at 11:32
  • 1
    Thanks again! ✌️ Mar 1 at 11:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.