[HN Gopher] Jujutsu - A Git-compatible DVCS that is both simple ... ___________________________________________________________________ Jujutsu - A Git-compatible DVCS that is both simple and powerful Author : rolisz Score : 283 points Date : 2022-02-19 17:17 UTC (5 hours ago) (HTM) web link (github.com) (TXT) w3m dump (github.com) | habitue wrote: | I like that this is not "a dvcs written in rust" but rather "a | dvcs with these awesome improvements over git." which | incidentally happens to be written in rust because of course it's | the right language for this. | kazinator wrote: | In git you can reorder any sequence of commits without any | conflicts. Howwever, there is no nice "porcelain" for it. | | The basis for it is the _read-tree_ command. | | In git, every commit is a snapshot and not a delta. (Repeat that | three times.) | | Any arbitrary snapshots of files can be arranged into a git | history. They don't even have to be related. We could take a | tarball of GCC, and make that the first commit. Then a tarball of | Clang and make that the second commit. | | The _read-tree_ command will read any commit 's state into the | index, and from there you can make a commit out of it. | | To reorder some N commits you're looking at, save all of their | hashes somewhere, and then rewind the branch: git reset --hard | HEAD~N. Then use git read-tree to read those hashes in whatever | order you want, committing them one by one. To reuse their commit | messages you have to use commit -C <hash>, though most them | likely don't make any sense, because the text of commit messages | usually talks about changes between a commit and its main parent. | | What will happen is that your history now as N commits which | represent the same _states_ as the N you had there before, in a | different order. For instance if you reverse them, then the | oldest commit has all the features (is the same code baseline) as | what the newest HEAD was previously. And then the subsequent | child commits basically remove all the changes that were made, so | the latest now looks like what the N-th looked like. | | How I sometimes use this: | | Suppose I made a fairly complex change that I would like to break | up so that it is presented as a sequence of two or more states of | the code. | | There are cases when the following workflow is easy: first I make | a commit out of the changes. One commit with everything. That | commit is what I want the final state to look like. Then I revert | some of the changes to produce the state before that state. If I | have mostly been adding things, this might consist of just | deleting them. Or I can do a git reset --patch HEAD^ to | selectively revert. I commit this penultimate state. Then repeat | the process: revert some more changes from that one, commit and | so on, as many times as I see fit. | | So what I end up with is the states of the code I want to present | as a history, but exactly in the wrong order. Using "git rebase | -i" doesn't work nicely; there are ugly conflicts, and some of | them have to be encountered twice. Here is where the git read- | tree trick comes into play: I simply reverse those exact states | of the code to put them in the right order on the branch. After | that I might do a rebase -i just to reword the commit messages to | frame the code states from the POV of being changes from their | parents. | | You might think: why not just "git commit --patch" from the | original working state to produce commits in order. The reason is | that doesn't always make sense. For that you had to remember to | make the commit as you were working. Because say you refactored | something and then made a change. You can't easily do a "git | commit --patch" which separates the refactoring from the change. | Sure, if you do the refactoring and then a commit, and then make | the change, you are good. But suppose you've conflated them | already; now what? You can commit everything and then back out | the changes that were done on top of the refactoring, and commit | that. Then reorder the two states. | mastazi wrote: | > In git, every commit is a snapshot and not a delta. | | I know this, but also I cannot reconcile this whit what happens | when you cherry-pick a commit from another branch. I'm confused | because cherry-pick really seems to be taking out the delta not | the snapshot. | | I'm thinking that cherry-pick takes that commit and makes a | diff with its parent and then that's what you get when you call | it. Is it how it works behind the scenes? | | I'm also thinking that the fact that each commit has at least | one parent means that, conceptually, we can use it as if it was | a delta (at least in the case of commit with one parent only), | if you get what I mean. | | EDIT: I'm not familiar with the internals of Git, just a user. | Commenting out of curiosity. | kazinator wrote: | When you cherry-pick a commit from another branch, it's not | doing anything like a read-tree to make your current work | look like that commit's snapshot state. It's doing something | like three-way merge between that commit, your baseline and a | common ancestor (I'm guessing: the same one that would be | identified by git merge-base <hash0> <hash1>.) That's why | cherry-pick identifies conflicts. | | A cherry-pick deos not just do a diff with its parent 0 and | then patch it onto your work. In many cases, that wouldn't | work because that's not a three-way-merge, but a two-way | merge, which has disadvantages. | | However: there may be situations when the commits are so | distant, it might make sense just to turn that one into a | patch and work the patch onto your baseline. Even if that | needs manual work, it can be simpler. You will only get | conflicts (patch hunk rejects in that case) that are relevant | to that change. I've had lots of experience working with | patch stacks (both before and after Quilt was introduced to | make that a bit easier) so I'm comfortable migrating patches | from one code base to another without a three-way-diff | process within version control. | mastazi wrote: | Yes, I agree about distant commits and turning it into a | patch. | | Thank you for explaining the three-way merge between | baseline, commit and common ancestor, makes sense. | em-bee wrote: | jujutsu looks interesting, but one thing that i find missing from | git is historical branch tracking. once two branches are merged, | git does not tell me which series of commits used to belong to | which branch. i can't check out main from two weeks ago if a | merge happened in the meantime because that information is lost. | | i fear to add such a feature additional information would need to | be stored in the git repo itself which would require a change to | git | mberning wrote: | Congrats and good luck. Git desperately needs a radically | simplified and radically consistent set of porcelain interfaces. | cryptonector wrote: | > It combines features from Git (data model, speed), Mercurial | (anonymous branching, simple CLI free from "the index", revsets, | powerful history-rewriting), and Pijul/Darcs (first-class | conflicts), with features not found in either of them (working- | copy-as-a-commit, undo functionality, automatic rebase, safe | replication via rsync, Dropbox, or distributed file system). | | You lost me at "free from the index". The index is one of the | most important parts of Git that makes _my_ life easier. | Opinionated DVCS UIs make my life harder -- all of them. | | > The working copy is automatically committed | | Right, so, the reason the index is powerful is that I get to do | `git add -e`, `git commit`, and repeat until I'm done or ready to | throw remaining changes away. I very much want the index / | workspace distinction. | | > Automatic rebase | | > Comprehensive support for rewriting history | | This is very welcome. At the very least this confirms something | important: the fallacious argument that "rebase rewrites history, | so it's eeeevil" is finally dead. | throw0101a wrote: | > _You lost me at "free from the index". The index is one of | the most important parts of Git that makes my life easier. | Opinionated DVCS UIs make my life harder -- all of them._ | | Mercurial has an 'index' / staging area, but not exposed by | default. You can access it with some extra CLI options, but | there is an optional idea that may be 'better' and worth | looking into: | | > _If you need the index, you can gain its behavior (with many | additional options) with mercurial queues [1] (MQ).[2] Simple | addition of changes to the index can be imitated by just | building up a commit with hg commit --amend (optionally with | --secret, see phases [3])._ | | * https://www.mercurial- | scm.org/wiki/GitConcepts#Git.27s_stagi... | | [1] is "A Git User's Guide to Mercurial Queues" | | * https://stevelosh.com/blog/2010/08/a-git-users-guide-to- | merc... | | MQs (optionally) expand on the idea of only a single staging | area: | | > _This single "intermediate" area is where git stops. For many | workflows it's enough, but if you want more power MQ has you | covered._ | | > _MQ is called Mercurial Queues for a reason. You can have | more than one patch in your queue, which means you can have | multiple "intermediate" areas if you need them._ | | If you only want to use one queue/index then that's fine too. | cryptonector wrote: | I find Mercurial very difficult to use. I find Git much | easier. | andrewshadura wrote: | It's just because you've been using Git for too long. | Mercurial is much easier to use if you're not exposed to | Git. | [deleted] | yjftsjthsd-h wrote: | If you can rewrite the history that actually got committed, do | you really need a temporary pre-commit staging area? | bonzini wrote: | The index is mostly useful to me to split a commit in | multiple ones. You do that with a sequence of "git add -p" | and "git commit" commands. I am interested in how to do this | with jj, because otherwise it looks like a very interesting | tool. | erik_seaberg wrote: | I prefer "git stash -p" to exclude unfinished changes, | because if I build up a partial commit in the index there's | no way to test it. | cryptonector wrote: | I do that later. I do `git rebase -i` and add `exec` | lines to build each commit that must build. | cryptonector wrote: | `git add -e` is infinitely better. | andrewshadura wrote: | Try git-crecord. | masklinn wrote: | > You do that with a sequence of "git add -p" and "git | commit" commands. | | You can do that with git commit -p. | bonzini wrote: | True but there's usually a "git diff --staged" in the | middle to check what I am committing. | cryptonector wrote: | Exactly! | martinvonz wrote: | > I am interested in how to do this with jj | | `jj split -r <commit>`, where `<commit>` may be the working | copy commit (which is the default). See | https://github.com/martinvonz/jj/blob/main/docs/git- | comparis... for more examples. | detaro wrote: | so just for understanding: repeated `git add -p` followed | by a `git commit` turns into repeated `jj split; jj | squash`, since you create a commit each time? | martinvonz wrote: | That would work, yes, but there's also `jj squash -i` to | move part of the child commit into the parent. There's | also the more generic `jj move` command for moving part | of any commit into any other commit (ancestor, | descendant, sibling), so you `jj squash -i` is equivalent | to `jj move -i --from @ --to @-` (where `@` is syntax for | the working copy commit and `@-` is syntax for its | parents). | cryptonector wrote: | Yes, I do. I often do this (usually in detached HEAD mode!): | : ; $EDITOR some-file ... : ; $build : ; git add | -e # take a few chunks, maybe change them : ; git diff | --staged; git status -uno : ; # lather, rinse, repeat | : ; git commit -m '...' -ev : ; : ; git status | -uno; git diff : ; git add -e # .. : ; # lather, | rinse, repeat until happy : ; : ; git fetch | origin : ; git rebase origin/master : ; # fix any | conflicts : ; : ; # continue until all bug fix / | feature : ; # activity for this issue is complete | : ; : ; # review my changes: : ; git log --patch | origin/master.. : ; : ; # if I have to clean my | history a bit: : ; git rebase -i origin/master : | ; # re-order commits, `edit` commits, `drop` : ; # | commits as needed : ; $build : ; # fix remaining | issues... : ; : ; # finally ready to push: | : ; git push myclone HEAD:refs/heads/this-thing : ; | : ; # open a PR | | Repeat as needed to deal with code review comments until done | and integrated. | c-smile wrote: | Are you human? | | > detached HEAD mode | | Ah, I see, not anymore... | indygreg2 wrote: | The index is a power user feature. Its forced presence in Git | effectively constitutes a usability barrier for new users. | After all, a VCS is effectively a glorified abstraction for | "save a file." Any barrier imposed between changing a file and | committing it can get in the way and confuse people. The Git | index does this. | | Furthermore, the index is effectively a pseudo commit without a | commit message. Any workflow using the index can be implemented | in terms of actual commits itself. | | I think because Git doesn't have strong usability in general | and especially around history rewriting, many Git users feel | that the index or an index equivalent is somehow a required | feature of a VCS because Git's shortcomings give that illusion. | However, if you use a VCS with better history rewriting (such | as Mercurial with evolve), you'll likely come around to my | opinion that the index can be jettisoned without meaningful | loss of functionality or productivity. | cryptonector wrote: | I don't deny that the index is a power feature and that it's | difficult to explain it to newbies. | | Perhaps there's room for new UIs. | | All I'm saying is I need this power. And it has to be easy to | reach for it. | martinvonz wrote: | > You lost me at "free from the index". | | If you click the link that text points you to (i.e. | https://github.com/martinvonz/jj/blob/main/docs/git- | comparis...), there's an explanation there for how to achieve | the same workflows. I get that it's _different_ , but I don't | think it's worse. I consider myself a (former) git power user | (I think I have ~90 patches in Git itself) and I've never | missed the index since I switched to Mercurial ~7 years ago. | | > This is very welcome. | | Thanks :) | omegalulw wrote: | > With Jujutsu, you'd instead use jj split to split the | working copy commit into two commits. | | This is more confusing? Often times when debugging/writing a | fix I would have extraneous code that I wouldn't want to | commit. With an index I'm always sure if what I commit, but | with this workflow you have to keep track of such stuff all | the time and if you forget that stuff makes it in? | | Not to mention that another benefit of an index is being able | to change commits and git replaying your working diff. | em-bee wrote: | yeah, i feel this is going to bother me, or at least be | difficult to get used to. | | i often have temporary files that i do not want to commit, | nor do i want to add them to .gitignore (because i want to | commit them later) | | but then, i'll have to spend some time using jj split. if | it is powerful enough then maybe the end result is just | that those files only live in the last commit. | | also, what happens on push? i'd never ever want the working | copy to be pushed to the remote repo. i could not find | anything in the documentation about that. | | (according to the answer here: | https://news.ycombinator.com/item?id=30399554 the working | copy is not supposed to be pushed) | cryptonector wrote: | You cover `git add -p`, but I want `git add -e`. | | Also, I often rebase and `edit` commits to split them or undo | parts of them. | | Rebase and all this is all about making commits that have | just the right content, and keeping history clean and linear. | The tools have to make this possible and easy. | | I get that git feels... barebones for this. You really have | to understand what you're doing when using git like I do, so | I get that it's not very accessible. | | Better UIs are great, but on the other hand, we need to be | able to get down to the low level. | | IMO. | martinvonz wrote: | > You cover `git add -p`, but I want `git add -e`. | | Interesting. I don't think I've heard anyone use `git add | -e` before. It should be easy to add that feature, but it | would be very low priority since so few users seem to like | to manually edit patches. | | > Also, I often rebase and `edit` commits to split them or | undo parts of them. | | You can do that by checking out the commit, then `jj | squash/amend` (aliases) and all descendants will be | automatically rebased on top, and branches pointing to them | will be updated too. There's also `jj edit` for editing the | changes in a commit without updating to it. And there's `jj | split` for splitting a commit (without needing to update to | it). | | > Rebase and all this is all about making commits that have | just the right content, and keeping history clean and | linear. The tools have to make this possible and easy. | | Yes, that's definitely a goal. I think Jujutsu does a much | better job at that than Git does. Did you read | https://github.com/martinvonz/jj#comprehensive-support- | for-r...? | alwillis wrote: | Something that's backend compatible with Git but uses some of | Mercurial's sensibilities? | | Sign me up! | dilap wrote: | I like and use the index in git too, but I wouldn't be so quick | to dismiss other models that might end up solving the same use | cases in a different way... | | From the README, it looks like there's robust support for | editing and splitting commits. So maybe in practice the flow is | similar to using the index, with the added the added benefit | that your work is backed via commits along the way, and the | simplicity of not having the index as an extra concept. | | In general when exvaluating X from the perspective of Y, we | will immediately see the thing's about Y we like that X lacks; | it takes more time to see if perhaps in the fuller context of X | those things are not necessary. | masklinn wrote: | > Right, so, the reason the index is powerful is that I get to | do `git add -e`, `git commit`, and repeat until I'm done or | ready to throw remaining changes away. | | You don't need the index for that. In fact I'd say it gets in | the way because the presence of the one means less pressure on | improving the ability to edit commits: while it's easy to add | stuff to HEAD it's much more painful to remove content from it. | | If that is solved, then the value of the index drops | precipitously, because you can create a commit with a purpose | and select its content instead of having to do it the other way | around then forgetting what change you were trying to craft. | [deleted] | jjthrowaway wrote: | It would be nice if this were in nixpkgs, it's a pain to manage | all the different language environments and it would save me from | trying to get it to compile. | | Right now error[E0554]: `#![feature]` may not | be used on the stable release channel --> | lib/src/lib.rs:15:12 | | | 15 | #![feature(assert_matches)] | | gmfawcett wrote: | If you get it working, please share a flake. :) | kuboble wrote: | 1) What are the advantages of using native backend as compared to | git? | | 2) Are there any potential issues one has to be aware of when | using jj contributing to git repository? | | I remember when I was the only team member using git-svn plugin | my coworkers were confused when I svn-committed many commits at | once with some of them breaking the time order of the svn history | (as git-svn commits in svn were recorded with git timestamp and | not the actual svn- commit timestamps) | martinvonz wrote: | > 1) What are the advantages of using native backend as | compared to git? | | Very few. The disadvantages are generally much larger. The main | advantage is that you won't run into a (harmless) race that | happens once in a while with the git backend | (https://github.com/martinvonz/jj/issues/27). Disadvantages | include not being able to interact with git repo and | performance problems (both size and speed). | | I should add a note about this to the README. | | The backend exists mostly to prove that it's possible and to | make sure that the backend API doesn't become tied to Git. | | > 2) Are there any potential issues one has to be aware of when | using jj contributing to git repository? | | The main one is that you should avoid pushing commits with | conflicts. It won't corrupt the remote repo, but git clients | won't know what to do with the conflicted files. The fix is to | fix the conflict and force push the conflict-free commit. | | I'll file a bug to prevent pushing commits with conflicts. | swagonomixxx wrote: | > A Git-compatible DVCS that is both simple and powerful | | We all know the dig here - Git is not simple. | | Like many tools, Git has evolved significantly over the years. | Git today was not like Git 10 years ago. | | Also, like many replacements to existing tools and software, they | always start out simple and beautiful. Then they grow in | complexity to serve the domain. The reason Git is complicated - | not "simple" - is mostly because version control _is_ complex. | | I also don't agree that Git is hard to use. I feel it is an odd | goal to try to make everything - even tools that experts use - | simple to use, when they are fundamentally not simple. I feel | like Git is sufficiently complex - no more than it needs to be | and certainly not less. | hinkley wrote: | I am by all accounts the SME on git at my company. I often am | the VCS expert at my company. I don't like using tools I don't | understand, and my brain is pretty good at handling problems | that look like graph theory. | | After using git for 6 years git still terrifies me. After 9 | months of svn I performed open heart surgery to remove a 1GB | zip file that some dummy merged before anyone thought to stop | him. It was at least 18 months before I tried something similar | with git and I made copies of my copies to make sure I didn't | fuck it up. And I still almost needed a do-over. | | The level of dread I have using git is pretty close to how I | feel when using a newly sharpened chef's knife - | hypervigilance. And that feeling gets stronger when I hand that | knife to someone else. Be very careful, that's super sharp... | hold still, I'll get you a bandaid. Now you get a mini lecture | on how to hold a knife without cutting yourself next time. | martinvonz wrote: | > I feel like Git is sufficiently complex - no more than it | needs to be and certainly not less. | | Perhaps the biggest mistake (IMO) was to expose the index to | the user. I happened to just watch | https://www.youtube.com/watch?v=31XZYMjg93o (by the person | behind Gitless). They explain the issues well there. | hinkley wrote: | > They told me offline use was a big advantage of git over | svn. But, how are you supposed to use git without Google? | | Shots fired. | KerrAvon wrote: | I haven't watched that video, but I agree -- the index is one | of the biggest hurdles to making git easy to understand and | use for newcomers. It's not hard to explain the fundamental | model of how git works -- it's hard to explain the UI, and | it's hard to explain the index. If you remove the index, | you're only working with commits, and that simplifies the UI | enormously. | hinkley wrote: | I'm gonna watch this video. What's been bugging me for a long | time, as someone who didn't quite get to see all of the | supposed ugliness of Subversion (which by description alone | sounds an awful lot like the rerere situation with Git, which | I have). | | It really feels to me like a commit identifier should be the | combination of a monotonically increasing number and a hash | of the content, rather than an either-or. If I merge or | rebase branches in git, I lose the index, just as I would in | subversion. But at least in svn I have some notion of how far | back commit 12345 is in the tree. ac4def2 could be HEAD or | four years ago. | dark-star wrote: | git is already very simple, at least for the 95% of use-cases | that I need. add, commit, checkout, push, pull.... maybe a branch | and merge here and there, but that's it. | | Of course I cannot remember how exactly the "git rebase" command | works and have to look it up every time, same as all those | switches to the "simpler" commands. | | I guess it all depends on what you need. Python looks really | complicated too, if you start by browsing the function and class | reference. But for someone starting to learn programming, it is | apparently pretty easy (or so I've heard) | freedomben wrote: | This looks like an interesting project, and I'm glad that people | are still thinking about how to improve on version control. | | That said, building a version control system seems like a problem | similar to a social network: the network affect causes an | enormous amount of friction. i.e. most people don't want to use | it until other people are using it. A vicious cycle. | | The fact that it's compatible with git as a backend is really | great though, and is probably the key to driving adoption. | However I have several immediate thoughts that come to mind that | cause me hesitancy. Answers in the README.md would be super | helpful for marketing to me (and deep apology if it's there and I | missed it): | | 1. How does it look to _others_ working on the repo using just | git? For example, "when the working copy is automatically | committed," where does it go? is there a remote branch that | someone could see if they `git fetch` while I'm working? I often | put all sorts of things in the code that I don't want to have | committed, ranging from harmless (a bunch of personal comments or | `IO.puts()`), to very important (API keys and such that I'm | testing with. I always move them to env vars before committing | but for first-pass testing to prove the concept I "hardcode" them | at first).[1] | | 2. Similar to "how does it look to others," what sort of burden | does "all operations you perform in the repo are recorded, along | with a snapshot of the repo state after the operation" put on the | git backend? If I'm hacking on an ffmpeg script and I | (temporarily) copy a 4GB mp4 file into the working directory so I | can easily run `./mycode video.mp4`, does that whole thing get | committed, potentially every time it changes? That could easily | turn into a 40GB set of changes.[1] | | 3. Do you _have_ to use the jj backend to get all the feature? | For example, with a git backend could you get the two things | mentioned above and also "Conflicts can be recorded in commits" | as well? | | A quick section in the README.md about which features require the | jj backend instead of git would be super helpful, and if written | well could answer all of the questions above. | | To sum up my comment in a TL;DR: To really sell me on a project | like this it has to work with git, and being able to quickly tell | which features I can use _with git_ , would make this | substantially more interesting to me. | | [1]: Related: https://xkcd.com/1172/ | martinvonz wrote: | > For example, "when the working copy is automatically | committed," where does it go? | | It becomes a regular git commit with a git ref called something | like `refs/jj/keep/9f1a0fb0-a0aa-4a4b-922f-d6d48687996a` | pointing to it (to prevent GC). It won't get fetched or pushed | by default, except with `--mirror`, I think. | | > If I'm hacking on an ffmpeg script and I (temporarily) copy a | 4GB mp4 file into the working directory so I can easily run | `./mycode video.mp4` | | Yes! You'll have to more diligent about keeping your .gitignore | (or .git/info/exclude, etc) file updated. I plan to add | commands for fixing such mistakes by forgetting the commit. | | > Do you have to use the jj backend to get all the feature? | | Nope, conflicts work with the git backend as well. | https://github.com/martinvonz/jj/blob/main/docs/git-compatib... | has some info. | | > To sum up my comment in a TL;DR: To really sell me on a | project like this it has to work with git, and being able to | quickly tell which features I can use with git, would make this | substantially more interesting to me. | | Makes sense. Thanks for the suggestion! I'll put it on my TODO | list. | freedomben wrote: | Awesome, thanks for the answers and thanks for sharing your | project! I'll give it a try :-) | skrebbel wrote: | Wow, this scratches a lot of my itches about Git. I teach a Git | course at my alma mater, and the things that confuses people the | most (the index, how to undo mistakes etc etc) all seem addressed | head-on. At first glance, this seems substantially easier to | teach than Git. | | The Git compat seems like a great idea for this to really take | off. My team is totally PR based though so if/when doing (Git | compatible) feature branches lands in JJ I'm excited to switch. | wcarss wrote: | > My team is totally PR based though so if/when doing (Git | compatible) feature branches lands in JJ I'm excited to switch. | | I'm trying to find the part of the docs that refers to this | functionality as missing but I can't -- does jj not have the | ability to create, update, pull from, merge branches, etc? | intrepidhero wrote: | > For example, pull-request workflows currently require too | many manual steps. | | Supported but not great I guess? | stouset wrote: | While I agree that git could use a rethink from a user tooling | perspective, I _really_ appreciate the existence of the index. | I'm not tied necessarily to this specific implementation of it, | but having a staging area where chunks are added piecemeal is | an enormous benefit. | | I honestly wish git forced `-p` for operations that support it. | I've worked on too many teams where people would just commit | everything in their working directory, and it would inevitably | make reviewing their PRs a nightmare. Particularly with times | where changes were accidentally committed wholesale that | shouldn't have been part of that set of changes. | skrebbel wrote: | I'm not opposed to carefully crafting a good commit, I'm | opposed to a state-heavy, badly named, inconsistent feature | to do it. And if you use any decent git UI (including -p on | the CLI), you don't really need it to be that persistent very | often. It could just be a list of chunks to select in the | "make commit" window, which is of course exactly how most git | UIs "make commit" window looks. It's a single step then, no | intermediary persistent state (with three names). | | JJ seems to workaround this in the other direction, by making | the concept of commits and rebases much more lightweight, | which i think is a refreshing enough take that I'd like to | try it. | Hendrikto wrote: | > I've worked on too many teams where people would just | commit everything in their working directory, and it would | inevitably make reviewing their PRs a nightmare. | | And they always claim to review and clean their commits | before pushing, or at least before merging, but never do. | pjc50 wrote: | > just commit everything in their working directory | | But that's what they've tested. I've had far more problems in | the other direction, where the commit doesn't contain the | complete set of things that it's supposed to but because all | the tooling - every single IDE and compiler - is looking at | the working directory not the index, I've missed something. | | The index is _definitely_ confusing for new users and users | of other VCS. | | > having a staging area where chunks are added piecemeal is | an enormous benefit. | | It would be quite fun if we could have hierarchical commits, | so I could add bits to a commit without having to | squash/amend. Then you'd see the top-level work item as a | "commit" and the individual changes as "subcommits". | stouset wrote: | Like I said, I'm not sold on git's specific implementation. | But breaking things into smaller, focused commits is--in my | experience--a hallmark of good development practice. | | There should absolutely be better tooling around it, so | that these piecemeal commits can be tested in isolation | from one another. That's a far better approach than just | throwing up our hands and committing everything in the | working tree, even if half of it has nothing to do with | what's intended. | throw0101a wrote: | > _It would be quite fun if we could have hierarchical | commits, so I could add bits to a commit without having to | squash /amend. Then you'd see the top-level work item as a | "commit" and the individual changes as "subcommits"._ | | Would something like Mercurial's queues be something what | you're looking for? | | * https://stevelosh.com/blog/2010/08/a-git-users-guide-to- | merc... | | See especially "...with Two (or More) Patches" onwards. | hinkley wrote: | "Powerful" has become to me a shibboleth for people who are full | of it. | | I can't recall the last time a coworker who liked things because | they were powerful didn't end up being untrustworthy. Even | dangerous. It's like nobody remembers the Principle of Least | Power. | | That said, I will take someone obsessed with "powerful" over | "flexible" any day of the week. | kjeetgill wrote: | Hm, I guess for tools like this I always read "powerful" _as_ | "flexible" - as in: this tools has strictly more | power/capabilities making it more flexible. In terms of "dev | tool marketing speak" I guess it's the opposite of "robust" | meaning: fewer features that are less likely to break on you. | hinkley wrote: | The only flexible tool I use in the real world is the | Leatherman, and that's for situations when I don't know what | I'll need, or if I'll need it. For every other task I have a | tool that is designed (sometimes quite well) for a set of | tasks that includes the one at hand (see also Alton Brown, no | single-purpose tools). | | The Leatherman is part of my EDC, along with an LED | flashlight with some respectable lumens so I don't have to | use my phone to see in the dark. | | In software this is known as the Unix Philosophy, but we | violate it quite often, and call those tools 'powerful' or | 'flexible'. Everything is a Swiss Army Knife all the time, | and we aren't self-aware enough to see how consistently - and | sometimes badly - we struggle with this. | | But you can't tell an addict they're an addict. They will | fight you to the death about how they Don't Have a Problem. | mdaniel wrote: | That's quite impressive, congratulations! | | The git comparison docs have: | | > Start working on a new change based on the <main> branch -- jj | co main | | Did you consider the recent git nomenclature change to use | "switch" for branch operations, and "co" for file operations? I | actually can't tell from so deep in my "git Stockholm syndrome" | whether that distinction is really hard on new users or not, but | the fact that git expended the energy meant they thought it was | meaningful | | And, do you have plans on supporting signed commits, either via | gpg or the newfound SSH key signing? | | I'm super excited to try out the conflict resolution mechanism, | because that's a major painpoint for my long-lived PR branches | martinvonz wrote: | Thanks! | | > Did you consider the recent git nomenclature change to use | "switch" for branch operations, and "co" for file operations? | | Actually, isn't "restore" for file operations? My impression | was that everyone agrees that `git checkout` does too many | different things. In particular, it's both for switching | branches and for restoring file content. So they added the new | `git switch` and `git restore` with limited scope. I strongly | suspect that they would have used `git checkout` for the former | if that wasn't already taken by the existing command. | | > And, do you have plans on supporting signed commits, either | via gpg or the newfound SSH key signing? | | No, that's not something I've even started thinking about. I'll | have to read up on how it works in Git first. Patches welcome, | though :) | | > I'm super excited to try out the conflict resolution | mechanism, because that's a major painpoint for my long-lived | PR branches | | You mean so you can continuously rebase them without having to | resolve conflicts right away? Yes, that's one of the benefits | of first-class conflicts. Another benefit, which took me a long | time to realize how useful it is, is the auto-rebase feature. | mdaniel wrote: | > No, that's not something I've even started thinking about. | I'll have to read up on how it works in Git first. Patches | welcome, though :) | | I opened an issue and provided links to the docs, and a link | to the current way that git implements it: | https://github.com/martinvonz/jj/issues/58 | | As I was trying to find the correct command in jj for where | to add the new argument, I realized that this may not play | nice-nice with jj's commit-everything model, so I'm actually | prepared for the issue to be closed WONTFIX :-) | | As for the patches welcome part, I notice that the Google CLA | bot is on your repo. While I do have the CLA signed for my | Gmail address, it seemed like some major tomfoolery to try | and add my current github email address (and the one which | backs my GPG key, to bring this full circle!) to the existing | CLA process. Do you intend to keep that CLA mechanism in | place, or was it just an oversight? | martinvonz wrote: | > I realized that this may not play nice-nice with jj's | commit-everything model | | Yes, I suppose you might not want to sign every working | copy commit, but as you noted on the issue, it would | probably make sense on `jj close/commit` (aliases). | | > Do you intend to keep that CLA mechanism in place | | I started working on this project internally and then open- | sourced it. I don't think I'm allowed to remove the CLA | bot. I understand that it's annoying :( | smichel17 wrote: | I had a discussion about the git cli UX around | branching/stashing/checkout a while back. Perhaps you'll find | it useful: https://news.ycombinator.com/item?id=23807410 | | (I post this somewhat selfishly, as I'm basically describing | how I wish git worked ;) | CGamesPlay wrote: | Interesting ideas! I especially like the automatic rebasing and | associated ideas. | | It's a bit strange to see "jj st" will automatically add all | files to the "working copy" commit. This means that when I | initially create my project, run "npm install" to install 500 MB | of dependencies, and then run "jj st" to figure out what to | include in my first commit, the command is going to copy all of | that into a commit object for no reason. I don't think I like | that behavior, to be honest. Is this a requirement of any of the | other unique features? Could this be turned off, or modified to | be an explicit operation? | | [append] | | To be clear, the fact that it's `jj st` is actually a big part of | the problem for me: this is the command I use to figure out what | to put into my `.gitignore` in the first place! I don't think | that any of the "read-only" commands should be making these kind | of changes. | giovannibonetti wrote: | > The command-line tool is called jj for now because it's easy to | type and easy to replace (rare in English). The project is called | "Jujutsu" because it matches "jj". | | Yeah, it's just a coincidence that the world Jujutsu means magic | in japanese (Zhou Shu ) | jayd16 wrote: | > Entire repo is under version control | | I wonder how this works out for large files and cleaning them up. | martinvonz wrote: | I doesn't work very well yet. See | https://news.ycombinator.com/item?id=30399554. | qbasic_forever wrote: | That's very cool to have support for rsync/dropbox collaboration | of the repo files. I'm always sad that there isn't a maintained | p2p git implementation anymore. I'd love to just dump a bare repo | to a syncthing share and collaborate with a small group of people | accessing it. | danbmil99 wrote: | Does it support lfs, or deal with large binary assets in some | other way? | martinvonz wrote: | No, there's no particular support for large files yet. | jareds wrote: | This looks interesting and I'm glad to see that people are not | viewing SCM as a solved issue. While I don't think I'd use this | on professional projects yet I'm interested at looking at this | for personal projects since I can use the Git back-end and | continue to use Github to host my code. I feel like Git has | become such a DeFacto standard that nothing is going to replace | it any time soon. I've been programming for long enough to | remember feeling the same way about SVN though so I assume | something will eventually supplant Git. | freedomben wrote: | I remember that well too (along with Rational Clearcase), and | you may totally be right, but git does feel different because | it works so well with all sorts of projects, big and small. | There were always operations that required hacks. With git that | doesn't feel the case to me,perhaps with one exception (but I | don't think this is git's fault as much as it's mine for not | knowing git well enough to use the tools it provides): if I'm | working simultaneously on two different branches (for example | one branch is a bug fix that requires 20 minutes to build and | deploy before I can test it, so I work on other things while | it's running), I often have two different checkouts so I can | (mostly) avoid having to git stash. | | That said though, you are probably right something will | eventually supplant git. It would be arrogant to think that my | failure to imagine something better means there isn't anything. | Hendrikto wrote: | What you are describing sounds as if you want worktrees: | https://git-scm.com/docs/git-worktree | freedomben wrote: | Whoa, thank you! That does look like the answer! | jeltz wrote: | I totally agree. Back when I used Subversion it felt to me | like there obviously must be a better way to version control | and that the tool got in my way all the time. Git on the | other hand almost always can solve my problems and while some | things could be improved (confusing UX, a bit too complex, | plus bad handling of conflicts) it is much closer to the | right tool for VCS than Subversion ever was. | fsloth wrote: | What are the problems that Subversion has? My only | experience of svn is of simple personal projects and in | that scope it worked pretty well - not contesting your | opinion, but would like to know at which point svn becomes | problematic. | netghost wrote: | If subversion had branches, they were not nearly as easy | to use as in git. It also didn't have a great notion of | offline work (to my memory). | | For what it's worth, SVN was pretty straightforward and | worked well enough at the time. Later, Mercurial | addressed SVN's deficiencies with a familiar interface. | adamnemecek wrote: | Rust has truly reinvigorated these types of tools. | kyrra wrote: | For those that didn't look, this is 100% rust. | tonetheman wrote: | tuwtuwtuwtuw wrote: | Seems irrelevant to me. Why do you care about the language | choice? | throwaway81523 wrote: | Because this is hacker news, not user news. | usrusr wrote: | People do tend to see tools written in a systems language in | another light than tools written in a glue language. Did you | read it as "rust (not C)" or did you read it as "rust (not | Python)"? | em-bee wrote: | i used to look down on languages other than C, considering | programs written in C a better choice than eg. python. i | have since reversed my stance because i realized that | python is a lot more hackable. i haven't tried rust yet, | but i would prefer it over C for sure. compared to python i | won't know until i actually get familiar with rust. | KerrAvon wrote: | On the negative side: In some environments it's a hurdle to | build programs in Rust. | | On the positive side: It signifies a certain likelihood of | memory and data safety that you won't get in most other | languages. | binarypaean wrote: | Language matters quite a bit to those considering | contributing. It also provides some context for expectations | about performance and reliability thanks to language idioms, | features and culture. | detaro wrote: | But the info is right on the linked page. Somehow I don't | think people who haven't even followed the submission link | aren't the ones to worry about yet for "potential | contributor". | ccbccccbbcccbb wrote: | Because it's trendy to praise brushes instead of paintings, | vinyl pressing quality instead of music, and languages | instead of software these days. | | Jean Baudrillard would call it another level of simulation. | martinvonz wrote: | Note, though, that it depends on libgit2 (which is written in | C). (As pointed out by someone in | https://github.com/martinvonz/jj/issues/56.) | AnonC wrote: | I'm curious to know if this has any similarities with fossil | (https://fossil-scm.org/ ). If it does, it would be nice to see | that in the documentation. | throwaway81523 wrote: | Fossil is ideologically different, it wants to preserve every | artifact, no rebasing allowed. | BiteCode_dev wrote: | " It also means that you can always check out a different commit | without first explicitly committing the working copy changes (you | can even check out a different commit while resolving merge | conflicts)." | | That's really interesting. Having to manage stashes is annoying. | halfdan wrote: | Try using git worktrees: https://geekmonkey.org/rethink-your- | git-workflow-with-git-wo... | pjc50 wrote: | Surprise limitation: you cannot have two worktrees set to the | same branch, or at least that confronted me when I tried it. | jomar wrote: | If you had two worktrees set to the same branch and made a | new commit in one of them (thus changing the commit the | branch ref points to), what would happen in the other | worktree? | | Either it wouldn't have the right commit checked out | anymore, or git would have to miraculously change what | files are checked out in it -- which would likely come as a | big surprise to whatever you were doing in that working | tree. | | Ergo, it is forbidden. | | I periodically find myself creating a new (temporary) | branch referring to the same commit when I want a new | worktree looking at the same place, or just create a new | worktree with a detached HEAD looking at the same commit. | hpfr wrote: | Can you elaborate on why you would want two worktrees set | to the same branch? I think if I were trying to compare two | approaches involving incompatible changes, creating a | branch for one approach would feel more natural anyway, and | then I'd be able to use the worktrees. | CorrectHorseBat wrote: | What is the advantage of using worktrees over another | checkout in another folder? | 0xdky wrote: | You will need a full repository in other directory to | checkout and this will waste storage unless you share | objects via alternate. | jomar wrote: | When you're done with a worktree, you just delete it (via | `git worktree remove`). Any additional branches or stashes | etc are part of the repository that the worktree was part | of, and they (of course) remain. | | When you're done working in a separately cloned repository | in another folder, if you're anything like me, before | deleting it (via `rm -rf`) you'll want to check very | carefully for additional branches, unpushed work, anything | stashed. Deleting an entire repository that's been around | for a while is a risky operation in that it may have | accumulated other unrelated work in addition to the current | branch (which was the primary reason for the clone), and | you'll want to check carefully before deleting the whole | lot. | | Additional worktrees within the same repository are great | for medium-term ephemeral separate strands of work. They | can be created and removed without concern. | ossusermivami wrote: | Optimizations and management really | halfdan wrote: | Duplicate storage as already mentioned, but you will also | lose the ability to merge / doff cross branches if you have | separate checkouts. | cortesoft wrote: | Why would you lose that ability? You can just pull from | the other checkout as an upstream, right? | jonathanlydall wrote: | Worktree allows you to checkout other branches, stashes | or commits which are local only / not yet pushed. | | What's also great is that you don't need to do a pull in | the other folder. Before I discovered worktree, I had my | repository checked out in two places, so was either | pulling both constantly, or when I needed the alternate, | it was often very far behind and I had to pull a lot. | CorrectHorseBat wrote: | Hmm, I tried it once and iirc I couldn't see | commits/branches of the other workspace without pushing | and fetching so I really didn't see any difference. With | different checkouts you can also easily do that by adding | the other checkout as a remote. | dataflow wrote: | Something probably got messed up on your setup (or maybe | you checked out a commit instead of a branch?) because | you definitely can see all worktrees' branches from | inside each other when using git worktree. | CorrectHorseBat wrote: | That makes sense. Now I think about it, The issue | probably was that I was working in a submodule and those | branches are probably not shared. | jonathanlydall wrote: | Yes, as per my other comment, I've noticed with | submodules that the references are isolated between the | different folders, but they do share the same objects in | the .git folder, so you still get efficiency there in not | needing to store or pull duplicate data. | jonathanlydall wrote: | Not sure what you were doing wrong, but I use worktree | regularly and you can absolutely see the same commits | from both the primary and worktree side. | | The great thing about worktrees is that everything local | is still available in the worktree and vice-versa, you | can even stash push on the one side and pop on the other. | You also don't need to push or pull on either side first. | | I have noticed that for submodules, although they share | the .git folder, they don't share references, so you | can't see local branches and stashes between the | worktrees, but sub module pulls are still quicker since | they share objects so those don't need re-pulled on the | other folder. | floatboth wrote: | rebase.autostash=true is also a thing, but the "working copy as | commit" concept does look more interesting. | blagie wrote: | This seems really nice. | | git got the data model really right, and the user space really | wrong. The data model is more important than the user space. | | This is the first project I've seen which appears to understand | and respect /how/ and /why/ the git data model is so elegant. | dane-pgp wrote: | > The data model is more important than the user space. | | For those interested in the different perspectives on how to | weigh those priorities, I recommend starting here: | | https://en.wikipedia.org/wiki/Worse_is_better | somebodythere wrote: | I think the programmer tendency to think of usability as an | implementation detail is probably why open-source app UX was | considered a joke for so many years. Only now is that | perception starting to change, because enough people have | taken an interest in the space who make usability a priority. | carlhjerpe wrote: | The pijul model makes even more sense to my brain, being patch | based solves a lot of branching issues. ___________________________________________________________________ (page generated 2022-02-19 23:00 UTC)