# The (Petty) Reason We Didn't End Up Using jj

DevFeed: [The (Petty) Reason We Didn't End Up Using jj](<https://devfeed.tech/articles/the-petty-reason-we-didn-t-end-up-using-jj-24697.md>)

Original publisher: [Read original article](<https://blog.gradle.org/the-petty-reason-we-didnt-end-up-using-jj-at-gradle>)

Author: Laura Kassovic

Published: 2026-06-02T04:00:00Z

Content type: article

Language: en

Sources: [The Gradle Blog](<https://devfeed.tech/sources/the-gradle-blog.md>)

Topics: [Git](<https://devfeed.tech/topics/git.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [Windows](<https://devfeed.tech/topics/windows.md>), [Batch file](<https://devfeed.tech/topics/batch-file.md>)

Tags: [batch](<https://devfeed.tech/tags/batch.md>), [git](<https://devfeed.tech/tags/git.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [how-to](<https://devfeed.tech/tags/how-to.md>), [version-control](<https://devfeed.tech/tags/version-control.md>), [windows](<https://devfeed.tech/tags/windows.md>)

## AI overview

The article explains why Gradle did not adopt Jujutsu (jj) as a replacement for Git in a developer's workflow. The blocker is Jujutsu's lack of support for the per-file line-ending rules in .gitattributes, which causes persistent phantom modifications to gradlew.bat in Gradle repositories.

## Source excerpt

Jujutsu (jj) has been picking up steam as a Git-compatible version control system. When used with its Git backend, jj stores commits and files in Git and works with existing Git repositories, but it does away with the staging area so your working copy is represented as a real commit that updates as you go. Rewriting history is cheap and safe: edit or reorder a commit and jj rebases its descendants for you; conflicts can be recorded instead of halting the operation; and operations can be undone from the operation log. Recently, one of our engineers set out to replace git with jj in their day-to-day flow. Unfortunately, it didn't work out. Not because of anything fundamental about jj's model, but because of a small detail of how Gradle projects are shaped on disk. This is worth writing down, because we suspect a lot of teams in the JVM ecosystem will hit the same wall. The actual blocker: gradlew.bat and .gitattributes A typical Gradle repository ships the Gradle Wrapper, which usually includes gradlew.bat. That script uses labels and goto, which cmd.exe can mishandle when a batch file has LF-only line endings, so gradlew.bat has to be checked out with CRLF to run reliably on Windows. We enforce this with .gitattributes, a file that tells Git how to handle specific files or paths, controlling things like line-ending normalization and whether files are treated as binary or text: *.bat text eol=crlf This is standard Git behavior: the file is stored normalized in the index, and the eol=crlf attribute tells Git to materialize CRLF in the working copy on checkout. Edits are normalized back on the way in. You forget about it after the first commit. jj doesn't read .gitattributes, so it can't apply a per-file rule. There's a long-standing issue (jj-vcs/jj#53) tracking support for at least the eol attribute, but until it lands jj's only lever is the global working-copy.eol-conversion setting. That's the rough equivalent of Git's core.autocrlf: it applies to every file at once