Merging Component Changes

Bit extends Git’s workflow to merge component changes between different repositories, making it easier to sync your components between projects.

Syncing components between projects

Apart from installing components with package managers, Bit lets you import components into different projects and continue to develop them.

While this workflow is very useful for maintaining and updating your components, it also means that you can have the same components with different changes in different projects.

To manage and sync these changes, Bit enables you to track and merge changes to components by leveraging Git’s merge workflow.

How does it work?

Bit uses semantic versioning to manage different versions for components in your project.

When an updated version for a component is available in the remote Scope, Bit fetches these updates and allows you to update the components in your projects.

When an updated version is available for a component while the component has also been locally modified in your project, Bit enables you to accept and merge incoming changes to the component in your project.

In some cases, incoming changes can create a merge conflict. To resolve this conflict, Bit will use Git to try and automatically resolve it. When this is not possible, Bit will allow you to manually resolve the conflict in your code.

Component-level diff using your own diff tool

Prior to checking out the new version of a component, you can run bit diff on the imported component-version, and see how it differs from the locally modified component. The diff command triggers git diff, which in turn will trigger any other 3rd party diff tool you have configured on your machine.

How to merge component changes

The most common use case of merging component changes is when a local component has been modified, and at the same time bit import shows a newer version for the component in the remote Scope.

After you run the bit import command, Bit will notify you that a new version is available for a component.

$ bit import
successfully imported 2 components
- up to date bit.example/string/is-string
- updated bit.example/string/contains new versions: 1.0.1

If you run bit status you will see that you are not using the component’s latest version.

$ bit status
pending updates
(use "bit checkout [version] [component_id]" to merge changes)
(use "bit log [component_id]" to list all available versions)

    > bit.example/string/contains current: 1.0.0 latest: 1.0.1

modified components
(use "bit tag --all [version]" to lock a version with all your changes)

    > string/pad-left ... ok

You can now use the bit checkout command to update your component to it’s latest version.

$ bit checkout 1.0.1 string/pad-left
successfully switched bit.example/string/pad-left to version 1.0.1

updated src/pad-left/pad-left.spec.js
updated src/pad-left/index.js
auto-merged src/pad-left/pad-left.js

In this example, Bit was able to auto-merge the implementation of the modified files. If you run bit status you will see that the component is modified and contains the local modifications on top of the latest version from the remote Scope.

$ bit status
modified components
(use "bit tag --all [version]" to lock a version with all your changes)

    > string/pad-left ... ok

Next, let’s see what happens when Bit can’t auto-merge the component changes.

Updating a versioned component in your project

When you try to export a versioned component to a remote Scope which already contains the same or newer component version, your local version can’t override the remote version as other projects may depend on it.

In this case, you need to fetch the remote version using bit import, untag your local version and then merge the changes between the versions.

Once the changes have been merged, you can tag and export the component to the remote Scope to create a new version with the merged changes.

This example shows an imported component in my project tagged with version 1.0.5 which I want to export to a Scope that already contains the same version of the component.

Trying to import the remote version in order to merge the changes between them just won’t work. Bit cannot import a version which your local component is already tagged with.

$ bit import
error: merge conflict occurred while importing the component bit.example/string/pad-left. conflict version(s): 1.0.5
to resolve it and merge your local and remote changes, please do the following:
1) bit untag bit.example/string/pad-left 1.0.5
2) bit import
3) bit checkout 1.0.5 bit.example/string/pad-left

To allow Bit to import the component from the remote Scope, first untag the component’s local version.

$ bit untag bit.example/string/pad-left 1.0.5
1 component(s) were untagged:
bit.example/string/pad-left. version(s): 1.0.5

After you’ve untagged the component, you can import the remote version.

$ bit import
successfully imported one component
- updated bit.example/string/pad-left new versions: 1.0.5

Next, checkout the component’s latest version to the project’s workspace, merge the versions and tag a new version for the component.

$ bit checkout 1.0.5 string/pad-left
successfully switched bit.example/string/pad-left to version 1.0.5

updated src/pad-left/pad-left.spec.js
updated src/pad-left/index.js
auto-merged src/pad-left/pad-left.js
$ bit tag --all

Now that you have a new version with the merged changes, you can bit export it to the remote Scope.

Handling merge conflicts

Bit uses Git to automatically resolve merge conflicts between implementations of different component versions.

When Git can’t resolve a conflict, Bit will prompt you to decide how to resolve the conflict using one of three options:

  • --theirs - the remote version overrides the local modifications.
  • --ours - the local implementation overrides the remote changes.
  • --manual - resolve the conflict manually.

Using Your Own Merge Tool

One of Bit’s core concepts is to work alongside other developer tooling. For example, to resolve a 3 way merge, Bit will by default call Git’s 3-way-merge command. If you’ve configured your own 3rd party tool to resolve conflicts in Git, the same tool will be used to resolve conflicts in the component.

This prompt might appear when you bit checkout a component.

bit checkout 1.0.5 user.checkout/string/pad-left
automatic merge has failed for component user.checkout/string/pad-left.
please use "--manual" to manually merge changes or use "--theirs / --ours" to choose one of the conflicted versions

As the first two options are pretty straightforward, let’s look at the following example to see how to resolve the conflict manually by adding the --manual flag to the bit checkout command.

$ bit checkout 1.0.5 bit.example/string/pad-left --manual

successfully run npm install at /Users/user/Bit/test/src/pad-left

successfully switched bit.example/string/pad-left to version 1.0.5

updated src/pad-left/pad-left.spec.js
updated src/pad-left/index.js
CONFLICT src/pad-left/pad-left.js automatic merge failed. please fix conflicts manually and then tag the results.

Resolve the conflicts within the specified file, Bit will open your merge tool and present you with the conflicted files(s) so you can resolve the conflict. Once it’s resolved, run bit status and bit tag to see that the changes have been merged (component is modified).

$ bit status
modified components
(use "bit tag --all [version]" to lock a version with all your changes)

     > string/pad-left ... ok

Now you can simply bit tag the component with the new version, and if needed export it to the remote Scope.

$ bit tag --all