· 5 min read Posted by Kevin Galligan
Part 5: Pulling Changes
GitPortal for KMP - Bidirectional
As app developers make changes to each of the apps, the KMP changes eventually need to be merged between them. GitPortal provides a few commands to accomplish this:
- bidir.push
- bidir.compare
- bidir.pullmerge
- bidir.pullmergeresolve
Push
The bidir.push
command will grab all commits from the app’s history that impact your KMP module, in our template example that is the library
folder, and “recreate” them in the KMP repo.
You’ve already used this command indirectly. The CI process runs this when you have KMP changes in the app repo. We’re explaining it here, but you should never need to run it directly.
The changes are not pushed directly to the tracking branch. Instead, they are pushed to a parallel branch specific to the app they were pushed from. In our case, gitportal/bidir/main-android
for Android and gitportal/bidir/main-ios
for iOS.
As you merge and push changes to main in your app’s repos, you’ll see changes to the KMP code being pushed into those branches automatically by CI.
If you made the DatabaseHelper
change from the previous post in the series, you should see a commit with that change in gitportal/bidir/main-android
.
Compare
As changes are pushed from the apps, they are added to the parallel branches listed above. When it’s time to pull changes into the “other” app, you can get a list of the changes to be pulled. This is what bidir.compare
does.
For example, to see the DatabaseHelper
, open a terminal in the iOS app folder and run the following:
gitportal bidir.compare -c android
You should see that commit listed. The -c android
argument tells GitPortal what app we want to compare to. Since we’re in iOS currently, we want to see available commits from Android.
Pull Merge
The bidir.pullmerge
grabs the outstanding changes and pulls them into the local app repo. For example, to pull changes into the iOS app, run:
gitportal bidir.pullmerge -c android
Assuming there are no conflicts, you will see a success message. If you run git log
, you’ll see a single commit with any changes pulled from Android.
Running bidir.compare
again will tell you that there are no outstanding changes.
What actually happens?
In the KMP repo, GitPortal maintains the parallel branches mentioned above. When bidir.pullmerge
runs, GitPortal actually runs a git merge operation. Say we’re running from the iOS app, GitPortal will create a merge from gitportal/bidir/main-android
into gitportal/bidir/main-ios
. In the local app repo, those updates are pulled and commited.
Technically, the changes are not yet merged into gitportal/bidir/main-ios
. A merge commit is created, but gitportal/bidir/main-ios
is not updated until those changes are commited to iOS main
, pushed, and GitPortal’s CI is run again. At this point, it’ll finalize updating gitportal/bidir/main-ios
.
Implement and Test
Once KMP changes are pulled, you’ll need to implement and test the app-specific parts of those changes. In our case, there’s not much you need to do (we only added a comment). In a more complex example, iOS screens may need to be created, iOS-specific changes applied, as well as testing on iOS to ensure the KMP changes work as expected.
Once that iOS-side work is done, you commit, push, and PR just like any other iOS change. When those changes are merged, GitPortal’s CI process will finalize the KMP library’s updates.
Pull Merge Conflicts
Because changes are happening in both repos independently, conflicts can occur. When you run bidir.pullmerge
, if the git merge operation fails because of a conflict, you need to do what you’d normally do: resolve the merge conflicts.
GitPortal actually creates a git worktree in which it runs bidir.pullmerge
. If the merge fails, you’ll be directed to that worktree folder to resolve the merge conflicts.
The merge worktree folder is just a regular git branch. You can use whatever method or tools you normally would to resolve the merge conflicts. Once resolved, commit them locally (don’t try to push. You won’t break anything, but you’ll have extra branches in your KMP repo).
Personally, I use Intellij to resolve merge conflicts in my day-to-day code editing. To do that, you can simply open the worktree folder with Intellij.
Local Config
The GitPortal CLI tool supports adding a default tool to open when there are merge conflicts.
There are two “officially” supported options, Intellij IDEA and Android Studio, but you can supply your own command if you’d like to use something else.
To have Intellij IDEA open automatically for merge conflicts, run:
gitportal localconfig -proc idea
Most tools will just take the worktree path as an argument, but some tools have their own command line param format. To use an arbitrary command, run the following:
gitportal localconfig -cmd 'sometool {dir}'
The {dir}
will be replaced with the path to the worktree. Some tools are picky about paths, so you may need to tweak arbitrary command strings (a “test” of this command setting is on the roadmap).
Pull Merge Resolve
When the merge conflicts are resolved, add and commit them to the worktree branch.
Now, you’ll need to run bidir.pullmergeresolve
. This will “complete” the pull merge step.
When a pull merge has no conflicts, the complete step is performed automatically. When there are conflicts, you need to run the complete step manually after resolving conflicts.
Make sure to open a terminal in the main repo directory. Not in the worktree folder. Then run:
gitportal bidir.pullmergeresolve
Assuming success, you’re done!
Well, sort of. Again, you need to go through your normal PR and merge process for the app, as with the no-conflict bidir.pullmerge
example above.
If successful, the bidir.pullmergeresolve
command will delete the worktree folder. It’s best to make sure you’ve closed whatever window or terminal was accessing that folder.