GitPortal - Git Repo Source-Linking Tool
GitPortal is a command-line tool that syncs source code across git repos. It is designed to specifically support sharing code with Kotlin Multiplatform.
GitPortal is Experimental
GitPortal is undergoing heavy development. The unidirectional flow is complete, but arguments and options may change with future versions. Bidirectional flow support is in private testing.
What does GitPortal do?
GitPortal can pull a remote repo’s content into a folder in your local repo. Its design is based on git subrepo, with changes and extensions to support necessary features.
GitPortal uses standard git operations to store, track, and push changes made in your local folder to the remote repo. It is conceptually similar to git submodules, but avoids the complexity of submodules, while supporting additional features needed for our source-sharing goals.
Background
Most teams introducing KMP start by publishing pre-built binaries. AAR files for Android and XCFrameworks for Xcode. While this is simple and low-friction, there are several negatives to this approach. The most critical are the following:
- iOS developers cannot see or browse Kotlin code
- iOS developers cannot debug Kotlin code
GitPortal’s current design is focused on implementing a Unidirectional code-flow model with repo-linking.
In “non-jargon” terms, it’s like publishing binaries, but with source code instead of binaries. While that means iOS developers using the KMP code will need a JVM installed, it’s a small bit of “friction” for the benefits that source code visibility provides.
Installation
MacOS
On MacOS, you can install GitPortal through Homebrew.
brew tap touchlab/homebrew-gitportal
brew install gitportal
Other Platforms
For other platforms, GitPortal can be run from a jar file. See GitPortal Releases and download the attached *.jar
file for the latest release. All commands and options are identical to those of the native executable builds.
Operation
Before installing and using GitPortal, make sure to read GitPortal for KMP Tutorial to understand why GitPortal works the way it does.
The initial implementation of GitPortal implements a unidirectional code-sharing flow. A KMP git repo is pulled into the Android and iOS app repos, based on tags in the KMP repo.
The KMP code is managed in the KMP repo. Versions are marked with git tags. Each app repo can pull in the KMP by tag.
Setup
You’ll need a git repo with KMP code, and at least one version tag. GitPortal pulls that code into your app repos.
From a terminal, cd to the local git clone of your Android or iOS repo. Run the GitPortal setup command.
gitportal setup [library folder] -r [remote KMP repo url] -t [tag from the KMP repo]
That will create a folder in your app repo, with the contents of the KMP matching the tag provided. To create a folder called kmpcode
from a KMP repo https://github.com/touchlab/MyKMPCode.git
at version tag 1.3.2
, the command would be the following:
gitportal setup kmpcode -r https://github.com/touchlab/MyKMPCode.git -t 1.3.2
A folder called kmpcode
will be created and the source from the KMP repo will be added there. GitPortal creates a commit after the files are added, and a metadata file at kmpcode/.gitportal
. Do not edit this file. It is used for future updates.
Once your linked folder is set up, you can edit your app repo’s files as you normally would. Make changes, push them to the app repo.
Dev Process
Developers can edit the app code as they normally would without interacting with GitPortal. You only need to use GitPortal when updating the KMP code with new version tags.
With a unidirectional model, the only restriction is that changes to the KMP files from the app’s repo should not be committed. You can edit them locally, but these changes should be reverted before committing. Updates to the KMP files and repo have a separate process.
This restriction is in place to implement the one-way unidirectional flow of code changes, similar to publishing binary dependencies. GitPortal has a check
operation that verifies that the KMP code has no changes, and provides a command you can run to revert inadvertent changes if they are made. The check
command is also available as a GitHub Actions workflow that you can run in your repos to enforce the unidirectional model.
In summary, a mobile dev interacts with the native app code and repos the same way they would without KMP. They can locally edit the KMP, but those edits shouldn’t be committed. GitPortal provides easy tools to highlight changes and revert them if necessary.
KMP Code Version Update
To update the KMP code in the app repo, get the version tag from the KMP repo, and run the following:
gitportal pull kmpcode -t 1.3.3
If the tag you are pulling doesn’t contain the commit from the tag you’re currently on, GitPortal will exit with an error. You can force-pull. This will only apply the changes necessary, and we may change GitPortal to default to “force” in future versions. It’s not a big deal, but be aware of it.
KMP Code Changes
The unidirectional flow prevents commiting KMP changes directly to the app’s repo, but you can push them from the app’s repo to the KMP repo.
Make a local branch
To make the process easier, it is suggested to create a local branch first before pushing changes from the local app repo to the KMP repo. You can stay in the same branch, but you’ll have extra GitPortal “paperwork” commits in your history.
Make KMP code edits, commit, then run:
gitportal push kmpcode -b my_kmp_feature_branch
GitPortal will extract local changes to the KMP code and push them to a branch my_kmp_feature_branch
in the KMP repo. If the branch does not exist, it will be created.
From there, you can review and merge the KMP changes in the KMP repo. When you want a new version, add a version tag to the KMP repo.
For our sample, we’ll assume you create the tag 1.3.4
in the KMP repo.
At this point, from GitPortal’s perspective, your linked KMP folder in the local app repo is in an “editing” status. The check
operation won’t run because you’re no longer attached to a tagged version. To get that linked folder back into the proper unidirectional mode, you need to use GitPortal to “pull” with a tag.
If you created a new branch for the KMP changes, checkout whatever branch you were on, or main
(or whatever your branch process is). Then run:
gitportal pull kmpcode -t 1.3.4
If you’re not in a separate branch, you’ll probably need to add -f
to the pull
command to force the pull.
After the pull
command, your local app repo code will have the tagged changes from the KMP repo, and you can commit this to the app repo.
Operations
GitPortal supports a handful of operations to implement the unidirectional code-flow model. Additional operations and features will likely be needed for a bidirectional model. R&D on the bidirectional model is ongoing currently.
Setup
From your local git repo home folder, run setup
to create a local folder and initialize it with the contents of a remote repo.
Pull
Pull updates to a previously setup folder, supplying a specific tag to track the version.
Push
Push changes made in the locally tracked folder to the remote repo, to the supplied branch.
Check
Review the local tracked folder to see if any changes have been made locally. Used to enforce the unidirectional source-sharing model.
Status
Displays the current status of the linked folder.