Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Branches view confuses me -- how do I fix it?

ZeetixTom September 14, 2022

In the `Branches` view of my bitbucket repo, I have several branches (as expected). I want to make "master" have ALL the changes of `feature/public_20210922/byron`.

I'm lost in the user interface, and I've spent the day being "git-spanked".

When I look at the branch in question, I see what appears to be a split bar, with a light grey portion under the "Behind" tab and bright blue portion under the `Ahead` tab.

Each says "26". When I mouse over the bright blue bar, a tooltip says "26 commits ahead of master". When I mouse over the light grey bar, a tooltip says "26 commits behind master".

When I select the branch in question, I get a light blue bar that says "26 commits behind "master" and has a "Sync now" button.

When I click the "Sync now" button, I get an alert that says "Syncing this branch will result in merge conflicts".

I already knew that!

Here is a command-line session that seems to have the same unhappy result:

[tms@byron browser]$ git branch
* feature/public_20210922/byron
master
[tms@byron browser]$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
[tms@byron browser]$ git merge feature/public_20210922/byron
Auto-merging yarn.lock
CONFLICT (content): Merge conflict in yarn.lock
Removing src/components/scene/map_scene/RawMetadata.js
Auto-merging src/components/scene/map_scene/MapSceneView.js
CONFLICT (content): Merge conflict in src/components/scene/map_scene/MapSceneView.js
Auto-merging src/components/scene/map_scene/MapScene.js
CONFLICT (content): Merge conflict in src/components/scene/map_scene/MapScene.js
Auto-merging src/components/scene/map_scene/DataWindowContainer.js
Removing src/components/scene/map_scene/CovidMetadata.js
Auto-merging src/components/scene/SceneView.js
CONFLICT (content): Merge conflict in src/components/scene/SceneView.js
Auto-merging src/components/scene/Scene.js
CONFLICT (content): Merge conflict in src/components/scene/Scene.js
Auto-merging src/components/scale/SingleEndedScale.js
CONFLICT (content): Merge conflict in src/components/scale/SingleEndedScale.js
Auto-merging src/components/scale/BooleanScale.js
Auto-merging src/components/omnibox/scene_controller/map_scene_controller/MapSceneController.js
Auto-merging src/components/omnibox/scene_controller/map_scene_controller/DataNormalizationAndAdjustmentControl.js
Auto-merging src/components/omnibox/scene_controller/SceneController.js
CONFLICT (content): Merge conflict in src/components/omnibox/scene_controller/SceneController.js
Auto-merging src/components/omnibox/navigator/panes/ContactPane.js
CONFLICT (content): Merge conflict in src/components/omnibox/navigator/panes/ContactPane.js
Auto-merging src/components/omnibox/OmniboxView.js
CONFLICT (content): Merge conflict in src/components/omnibox/OmniboxView.js
Auto-merging src/components/omnibox/OmniboxContainer.js
CONFLICT (content): Merge conflict in src/components/omnibox/OmniboxContainer.js
Auto-merging src/components/legend/legend_view/BooleanLegendView.js
CONFLICT (content): Merge conflict in src/components/legend/legend_view/BooleanLegendView.js
Auto-merging src/components/legend/Legend.js
CONFLICT (content): Merge conflict in src/components/legend/Legend.js
Removing src/components/data_layer/value_renderer/RendererFactory.js
Removing src/components/data_layer/value_renderer/LogRenderer.js
Removing src/components/data_layer/styler/SingleEndedFeatureStyler.js
Removing src/components/data_layer/styler/DoubleEndedFeatureStyler.js
Removing src/components/data_layer/scale/legacy_legend.html
Removing src/components/data_layer/scale/legacy_index.js
Removing src/components/data_layer/scale/legacy_index.html
CONFLICT (modify/delete): src/components/data_layer/legend_view/SingleEndedLegendView.js deleted in feature/public_20210922/byron and modified in HEAD. Version HEAD of src/components/data_layer/legend_view/SingleEndedLegendView.js left in tree.
CONFLICT (modify/delete): src/components/data_layer/legend_view/DoubleEndedLegendView.js deleted in feature/public_20210922/byron and modified in HEAD. Version HEAD of src/components/data_layer/legend_view/DoubleEndedLegendView.js left in tree.
CONFLICT (modify/delete): src/components/NavigatorSpike.js deleted in feature/public_20210922/byron and modified in HEAD. Version HEAD of src/components/NavigatorSpike.js left in tree.
CONFLICT (modify/delete): src/components/LegendSpike.js deleted in feature/public_20210922/byron and modified in HEAD. Version HEAD of src/components/LegendSpike.js left in tree.
Removing src/components/DotEnvSpike.js
Auto-merging src/components/ContentContainer.js
CONFLICT (content): Merge conflict in src/components/ContentContainer.js
Removing src/components/AppContainerSpike.js
Removing src/components/App.test.js
Auto-merging package.json
Auto-merging README.md
Auto-merging .vscode/launch.json
CONFLICT (content): Merge conflict in .vscode/launch.json
Auto-merging .eslintcache
CONFLICT (content): Merge conflict in .eslintcache
Auto-merging .env
CONFLICT (content): Merge conflict in .env
Removing #.env#
Automatic merge failed; fix conflicts and then commit the result.

Is there some straightforward way to tell git/bucket to make the `master` branch be the same as `feature/public_20210922/byron`?

I know that I can slog through dozens of files one by one with my IDE and fix them -- but that is exactly WHY I put all these changes into this feature branch!

What am I missing here?

Following are three screenshots showing the above:

1_browser_branches.png2_browser_branches.png3_browser_branches.png

2 answers

1 accepted

0 votes
Answer accepted
ZeetixTom September 16, 2022

I know that the community is not going like what I'm about to write, and I'm going to accept it anyway as an answer.

All of this complexity about merge conflicts and such was exactly WHY I started using the "feature branch" workflow two years ago. This is not a huge project with many developers. This is JUST ME -- trying to keep different layers of my technology in some meaningful way.

The specific use case is that I have a complex app that works (I invite you to drive it at `https://covid.zeetix.com`). It has a database backend, middleware in nodejs, and a frontend built from React using the Material UI library. The last is key -- the working front end, as of about a year ago, was written in v4 of the Material UI library.

I learned, about that time, the MaterialUI v4 was being replaced by v5 -- and the changes are pervasive (at least in my front-end). I needed a place to keep those changes, and so I created a feature branch for them -- `feature/muiv5`

I did ALL of my muiv5 development in that feature branch, and started working on the migration.

The motivation for changing the front end was the need to add user authentication. I chose `auth0` to minimize the amount of code I had to write on my own. Still, it meant writing several new React components to present the various screens to the user. Since I didn't want to add more technical debt, I decided to add the user authentication behavior in the `feature/muiv5` branch.

The new screens are independent enough that I just added them, knowing that I still had work to do to port the rest of the UI from muiv4 to muiv5. The new screens use muiv5 components, and so far all was fine. All this was in the `feature/muiv5` branch.

Then the world changed -- my (small) team decided that we really needed to make some immediate changes in the appearance of the front end (rendering a map with different colors, for example). That couldn't wait for the muiv5 project. I did those in a different feature branch called `features/public_20210922` -- it was branched from the public server on 22-Sep-2021 (almost a year ago). Note the misspelling of the branch name -- it should be `feature/public-20210922`, but that's a different story.

I chose these two branches in hopes of keeping these changes separate from each other.

As I wrapped up the rendering changes in early 2022 (funny how a "1-2 week" project always turns into "2-3 month"), we determined that it was important to add completely new and very challenging behavior to the system. I did frontend pieces of that work in the `features/public_20210922` branch, again in the hopes of keeping them separated from the delayed user authentication and MUI migration that were in the `feature/muiv5` branch.

A few weeks ago, the changes in `features/public_20210922` were finished, everything worked, and everything was deployed. All was fine.

  1. It was then time to pickup the work on migration and authentication. By this time, I wanted to merge the features/public_20210922 changes back to the master, add some testing, and migrate the changes from the `feature/muiv5` branch one at a time.

It was the first attempted merge -- from features/public_20210922 to `master` -- that derailed me. Somehow (I have no idea how) the `feature/muiv5` changes were already in the `master`.

I thus got a long list of merge conflicts. That's when I dove into the `branches` screen to try and sort things out. What it did was confuse me even more.

I spent about 2 days laboriously plodding through dozens of merge conflicts, making what appeared to be the obvious choices. After each pass, when I tried to run the app, more problems were revealed. I gave up after about a half-dozen restarts.

Here is what ultimately worked for me:

  1. I used the recipe from Atlassian/bitbucket to clone the entire repo so that I did not make the existing repo any worse.
  2. I used `git clone` to clone the new repository to a new directory.
  3. I made sure I was on the `master` branch of the new repo (I'll change this to `main` later).
  4. In a shell, I did a plain `cp -rf ...` from the working features/public_20210922 directory to the base directory of the new repo.
  5. I did the usual `git add .`, `git commit -m ...`, `git push`

I now have what I wanted in my new repo. I have all the branches that were in the original repo, and my `master` is in a known-good state.

This is very close to what I would have done had I not had any version control at all.

I am the only developer committing to this repo. In a particular working directory, I do a "git add .", "git commit -m ..." and "git push" at least once a day. At least I can still reconstruct the daily changes I've made over the past two+ years.

Nevertheless, this particular "Branches" screen and -- so far as I can tell -- the entire "feature branch" workflow is a disaster.

At least for the foreseeable future -- certainly until a second developer joins the team -- I intend to use `master` for ALL my changes. The happy talk about branches, workflows, and so on strikes me as marketing material intended to sell products rather than actual robust and working practices that reasonably competent developer can do on a daily basis.

1 vote
Erez Maadani
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 14, 2022

Basically, the UI tries to tell you couple of things:

  1. You branched out `master` 26 commits ago - which means, your `master` branch includes 26 new commits since you created `feature/public_20210922/byron`.
  2. Your added 26 new commits to `feature/public_20210922/byron` since you branched out of `master`

So now you have code changes in both your `master` & `feature/public_20210922/byron` branch, and you need to ask yourself which of the changes you need to keep.

This article gives a good explanation about git merge strategies and and I recommend you choose one which suites you best from there. 

Going forward, to avoid such issues, I highly recommend to limit the feature branches lifetime, preferably, till nearest weekend. Small changes are easier to merge, easier to review, easier to test and statistically, include less bug :)

Ulrich Kuhnhardt _IzymesCo_
Marketplace Partner
Marketplace Partners provide apps and integrations available on the Atlassian Marketplace that extend the power of Atlassian products.
September 14, 2022

Great comment @Erez Maadani ! This kind of out-of-sync scenario happens quite often in larger teams as 'master' or 'main' evolve quickly. I found this strategy the easiest:

  1. While on feature branch: $ git fetch origin master 
    This will update the local representation of master (FETCH_HEAD), but not mess up your files on the feature branch.
  2. Then run: $ git merge FETCH_HEAD
    This may create merge conflicts, and you need to resolve them here. There's no way around it unfortunately.
  3. Once the files with merge conflicts have been resolved, add them to the git staging area with: $ git add <my-conflicted.file> <other-conflicted.file>
  4. Then you're ready to roll: $ git commit
    This will finish the sync merge and create new commit on your feature branch. Congratulations, you can now create a pull request in Bitbucket to merge your feature into master. There will be no more merge conflicts.

Going forward as @Erez Maadani suggested, perform steps 1 - 4 regularly, perhaps even first thing in the morning (after coffee of course, in case there are merge conflicts to go through)

Best, Ulrich

// Izymes (We build apps that turbo-charge team velocity through contextual automation.)

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
PERMISSIONS LEVEL
Site Admin
TAGS
AUG Leaders

Atlassian Community Events