[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)