From: brian m. carlson Date: Thu, 18 Sep 2025 22:22:22 GMT Subject: Re: [RFC] git-rebase-clean: mitigating a “semantic conflict cascade” during rebase Message-ID: In-Reply-To: On 2025-09-18 at 17:02:59, Antonio Mennillo wrote: > Hi Brian, > > Thank you for the thoughtful response, and please excuse me if I am a > bit clumsy — > this is my first interaction with the Git community. > > > Usually we would recommend that each commit be atomic... > > I perfectly understand this best practice. In my context, working with > many junior developers, > it is not always possible to enforce atomic commits. In some > “emergency” situations we > squashed just to make progress, even if that meant losing granularity. Yeah, I've seen that at previous employers. Even where I work now, I definitely see differing levels of interest in atomic commits with nice commit messages. > Your explanation really helped me see things more clearly, and I appreciated > the constructive (non-toxic) way you put it. Well, thank you. > Yes, rerere helps with repeated textual conflicts, but the scenario I > worry about > is semantic: if commit M changes an interface and commit N implements it, then > changing M during rebase can make N semantically invalid. rerere > cannot solve that > — it remembers markers, but cannot understand that “this > implementation no longer > matches the interface.” Yes, this is effectively unavoidable because Git doesn't know the structure of your code or data. For instance, in Rust, I could add a new mandatory-to-implement method to a trait and then all implementations would need an update. > That feedback inspired me to improve the tool. Version 2.0.0 > (literally born today, > thanks to your comment) now works differently: > > 1. Temporarily squash the feature branch (so the rebase is effectively `1/1`) > 2. Resolve conflicts once, with the full final context > 3. Automatically re-expand the squash by replaying saved diffs, restoring > the original commits (with new hashes, as expected in any rebase) You haven't described exactly how this works, but it looks like it performs a fixed set of transforms (e.g., symbol renames). That can be useful, but it isn't sufficient in a lot of cases. For instance, in some work on Git I'm doing, I need to include a header file for a function. It was previously included in another header, but my rebase onto the main branch had it removed, so I need to add it into the C file I'm working on. The only way I can 100% know which commit needs that change programmatically is to try to compile on each commit until it fails, and insert it there. This, of course, requires atomic commits. In a lot of cases, I use git-autofixup[0], which looks at changed lines in the diff to determine which commit to squash the changes into. It's a great idea, but it has limitations, since sometimes a change logically attaches to a commit but isn't close to it in the context of the diff (such as my header inclusion change above), and sometimes I've changed similar lines in an earlier commit A (where my change should be squashed) as well as in later commit B, yet it gets attributed to B accidentally. It's convenient and generally works well, but I have to be careful not to trust it entirely. > I would be very interested in whether the community sees this worth exploring > as an **experimental rebase strategy** (something like `git rebase > --squash-restore`), > or if it overlaps with existing mechanisms I am not aware of. I think the fact that it adds a dependency on tree-sitter is kind of a non-starter for us. We're currently having a mildly contentious discussion over the use of Rust in Git and it won't be mandatory until Git 3.0. It certainly covers some use cases, but it looks like it only handles deletions, file renames, and symbol renames, and the latter only for a small set of file types. There's a lot of cases that it doesn't handle, and I'm afraid that people will end up disappointed by expecting it to magically handle a lot more than it does. That doesn't mean it isn't a useful and valuable tool for many use cases, but users may have much higher expectations that it will magically solve their problems when that isn't the case. I have some tools that I've written myself that are like that, for instance. I'll also point out that we try to avoid hard-coding known languages. People use lots of languages with Git, some of which are not even known to Vim, which has an exceptionally complete list of file types and syntax highlighting. People also do non-code things with Git; for instance, I store my creative writing in a repository, and other people use Git for working on documentation or technical books. As much as possible, we want tooling that works for at least generic text files and ideally, all files. -- brian m. carlson (they/them) Toronto, Ontario, CA