|
|
|
|
|
by globular-toast
496 days ago
|
|
> I agree with you in some sense, but also, kinda don't. That is, I agree that thinking git stores diffs is not correct, but I'm not fully sold on how big of a deal it is to be incorrect here. It's not so much about what actually happens underneath, that should be irrelevant and git just does what it does for practical reasons ultimately (as you point out, with packfiles, but this is definitely not a detail any git user needs to be aware of). The problem I see is that git actually exposes both views of things. A seasoned git user will be used to the "duality" of commits vs diffs (ie. they are two different views of the same thing). Git exposes diffs directly when cherry-picking or rebasing, but at most other times you are working with commits. You don't push/pull diffs, you push/pull commits. It seems like a small thing, but every time I've dug into why somebody is having trouble with git it seems to be they view the world only as diffs. So my question really was whether jj attempts to expose only one or the other. Looking at your explanation I would say it doesn't. It seems to me like changes are very similar to branches in git. At least this is how I think of branches in git, but I tend to be the "git guy" in every place I've worked. I mutate branches all day long by doing git commit amend etc. It seems like the real point here is to get rid of "branch" as that is an overloaded concept and split it into two things: change and bookmark. In many ways it just seems like a reinforcement of the way I (and I guess other "git guys") use git anyway. Interesting! |
|
Some command arguments treat commits as snapshots (e.g. `jj restore --from/--into`, `jj diff --from/--to`, `jj file list -r`) and some commands arguments instead inspect the diffs (e.g. `jj rebase -r/-b/-s`, `jj diff -r`, `jj squash --from`, `jj log <path>`).
The first-class conflicts (https://jj-vcs.github.io/jj/latest/conflicts/) allow jj to be much better at treating commits as diffs than git is. In particular, there's no real difference between merge commits and other commits; any commit can introduce conflicts and any commit can resolve conflicts. We define the changes in a commit as relative to the auto-merged parents. That means that the diff-centric command arguments work in a consistent way for merges too. For example, if you create a new merge commit (`jj new A B ...`), it might have conflicts, but we still consider it empty/unchanged. If you resolve the conflicts, then `jj diff` will show you the conflict resolutions, and `jj rebase` will rebase the conflict resolutions (a bit like git rerere, but it also works on hunks outside of the conflict areas).