Introduction: Why Git is not just "git push"
\n\nIf you write in Kotlin, you know how pleasant this language is: concise, safe, modern. But even the most elegant code turns into chaos if the team doesn't have a clear Git workflow. Have you ever tried to merge a branch where one developer renamed half the files, another refactored coroutines, and a third accidentally committed `build.gradle.kts` with local paths?
\n\nA Git workflow for Kotlin developers is not just boring rules. It is your shield against conflicts, a guarantor of a stable `main`, and a way to avoid spending Monday figuring out "who broke what." In this article, we will break down a real pipeline: from setting up `.gitignore` for Kotlin to automated checks via Gradle and pre-commit hooks.
\n\nLet's bring order to the repository!
\n\n1. The Basics: Setting up a repository for Kotlin
\n\n1.1. The right .gitignore for Kotlin
\n\nThe first thing everyone should do is forget about copy-pasting templates from GitHub. Kotlin projects have specific folders that should not end up in the repository. Here is a minimal gentleman's set:
\n\n# Kotlin & JVM\n*.class\n*.jar\n*.war\n*.ear\nbuild/\n!gradle/wrapper/gradle-wrapper.jar\n\n# IDE (IntelliJ IDEA)\n.idea/\n*.iml\n*.iws\nout/\n\n# OS\n.DS_Store\nThumbs.db\n\n# Gradle\n.gradle/\nlocal.properties\n\n\nNote: we explicitly exclude `.idea/` — this will save colleagues from conflicts in IDE configs. And `local.properties` (path to SDK) is a purely local thing.
\n\n1.2. Git hooks: your personal linter
\n\nA Git workflow for Kotlin developers is unthinkable without pre-commit hooks. They run before a commit is created. The most popular tool is pre-commit with plugins for Kotlin.
\n\nExample config `.pre-commit-config.yaml`:
\n\nrepos:\n - repo: https://github.com/pre-commit/mirrors-ktlint\n rev: v0.50.0\n hooks:\n - id: ktlint\n args: ["--format"]\n\n - repo: https://github.com/detekt/detekt\n rev: v1.23.1\n hooks:\n - id: detekt\n\n\nNow, before each commit, `ktlint` will format the code, and `detekt` will check for potential bugs. No more "forgot to run the linter"!
\n\n2. Branching strategy: choosing your workflow
\n\n2.1. Git Flow — classic for large projects
\n\nFor Kotlin monoliths or projects with strict releases, the classic Git Flow is suitable. Main branches:
\n\n- \n
main— only stable code that is in production. \n develop— integration branch for development. \n feature/*— each new feature. \n release/*— release preparation (bug fixes, version updates). \n hotfix/*— urgent fixes in production. \n
Example for Kotlin: you are developing a new coroutine processing function. You create a branch feature/coroutine-flow, work on it, then merge it into develop. When enough features accumulate for a release, you create release/2.1.0, fix bugs there, and only then merge into main.
2.2. GitHub Flow — for CI/CD and fast releases
\n\nIf you are writing a microservice on Ktor or Spring Boot and deploying every day, Git Flow will be overkill. Use GitHub Flow:
\n\n- \n
- The
mainbranch is always ready for deployment. \n - Each task is a
feature/namebranch. \n - After completion — Pull Request, code review, automated tests, merge into
main. \n - Immediately after the merge — deployment (ideally). \n
Perfect for Kotlin projects with good test coverage.
\n\n2.3. Trunk-based — for the bold
\n\nWorking at a startup or on a pet project? Trunk-based (everyone commits to main with short commits) speeds up development, but requires