martinvonz / jj

A Git-compatible VCS that is both simple and powerful
https://martinvonz.github.io/jj/
Apache License 2.0
8.39k stars 289 forks source link

Docs: minor things in github.md #1989

Closed joyously closed 1 year ago

joyously commented 1 year ago

The simplest way to start with Jujutsu, is creating a stack of commits, before creating any branch.

# Start a new commit off of main

This is a bit confusing, since isn't main a branch?


# Create a branch so we can push it to GitHub $ jj branch create bar -r @-

Can you add a comment to indicate if this puts multiple commits or just the previous commit on the new branch (since the original sentence says "creating a stack of commits") ?


$ jj git push --change $revision

Is this the literal command, with $revision, or is the user supposed to fill in the number?


$ # Give the fix a description and create a new working-copy on top. $ jj commit -m 'address pr comments' $ # Update the branch to point to the new commit. $ jj branch set your-feature -r @- $ # Push it to your remote $ jj git push.

First, that push command probably should not have a dot? Would it be the same thing to do the following commands? $ jj describe 'address pr comments' $ jj branch set your-feature #not sure of flags here $ jj git push

PhilipMetzger commented 1 year ago

Sorry for the late response.

This is a bit confusing, since isn't main a branch?

The guide is written in an Git oriented way and as of Git 2.28 main is the default branch.

Can you add a comment to indicate if this puts multiple commits or just the previous commit on the new branch (since the original sentence says "creating a stack of commits") ?

The command puts only a single commit on the mentioned branch.

Is this the literal command, with $revision, or is the user supposed to fill in the number?

The user is supposed to fill out the commit id, e.g the two highlighted characters in the commit id.

First, that push command probably should not have a dot?

Yes, some rephrasing probably dropped the comment that followed.

Would it be the same thing to do the following commands? $ jj describe 'address pr comments' $ jj branch set your-feature #not sure of flags here $ jj git push

Thats correct, it is an equivalent workflow, if you do jj branch set your-feature -r @ in your second command. But to get a new commit, you're required to jj new which jj commit does for you.

joyously commented 1 year ago

The guide is written in an Git oriented way and as of Git 2.28 main is the default branch.

So the comment could say: # Start a new commit off of default branch

Can you add a comment to indicate if this puts multiple commits or just the previous commit on the new branch (since the original sentence says "creating a stack of commits") ?

The command puts only a single commit on the mentioned branch.

OK, then the text talking about a stack of commits shouldn't be plural, or the command should push the whole stack?

Is this the literal command, with $revision, or is the user supposed to fill in the number?

The user is supposed to fill out the commit id, e.g the two highlighted characters in the commit id.

Please make that clear in the text since it looks like a variable that will get filled in somehow.

First, that push command probably should not have a dot?

Yes, some rephrasing probably dropped the comment that followed.

So, the dot should be removed.

Would it be the same thing to do the following commands? $ jj describe 'address pr comments' $ jj branch set your-feature #not sure of flags here $ jj git push

Thats correct, it is an equivalent workflow, if you do jj branch set your-feature -r @ in your second command. But to get a new commit, you're required to jj new which jj commit does for you.

OK, it seems odd to me to force a net commit and then reference back one to push. I'm still not sure I understand jj.

PhilipMetzger commented 1 year ago

So the comment could say: # Start a new commit off of default branch

Correct.

OK, then the text talking about a stack of commits shouldn't be plural, or the command should push the whole stack?

The text talking about a stack is still correct, as you can push dependant commits while repeatedly creating branches.

For example:

$ # Hack on stuff
$ jj commit -m "Add foo"
$ jj branch create feature-foo -r @-  # create branch feature-foo for "Add foo"
$ # Hack on stuff
$ jj commit -m "Add bar"
$ jj branch create foo-continued -r @-  # create branch foo-continued for "Add bar"
$ jj git push # pushes both feature-foo and foo-continued, which depend on each other, a so called stack

To simplify the above workflow jj git push --change exists, which creates an branch named push-$revid for each revision.

Please make that clear in the text since it looks like a variable that will get filled in somehow.

Is this clearer?

$ jj git push --change $revision # Here $revision refers to the full commit id or the first two highlighted characters in the commit id

OK, it seems odd to me to force a net commit and then reference back one to push. I'm still not sure I understand jj.

I'll try to explain it, with conventional VCS you either have commited work (something in a commit) and uncommited work (the working copy, which holds all uncommited work). Jujutsu turns this relationship around, as the working-copy itself is also a commit, which means that you can apply every operation which works on a commit on the working-copy. The working-copy commit is always attached to it's parent which can be any commit.

So these graphs are equivalent:

# favorite $vcs           # Jujutsu
(uncommited work)  @ (working-copy commit)
===                |
C                  C
|                  |
B                  B
|                  |
A                  A

If you haven't tried jj out yet, I'd suggest doing so, to help you understand it.

PhilipMetzger commented 1 year ago

Can you add a comment to indicate if this puts multiple commits or just the previous commit on the new branch (since the original sentence says "creating a stack of commits") ?

The command puts only a single commit on the mentioned branch.

To correct myself, it puts both commits on the branch. As the difference from${default-branch}@remote..your-branch are these two commits.

joyously commented 1 year ago

Are you going to add your new example with the two branches?

I'll try to explain it, with conventional VCS you either have commited work (something in a commit) and uncommited work (the working copy, which holds all uncommited work). Jujutsu turns this relationship around, as the working-copy itself is also a commit, which means that you can apply every operation which works on a commit on the working-copy.

So instead of explaining it, you reinforced my view that it is odd to make a new empty commit and refer backwards to the previous one with @- to push it. One of the problems I have with Git is that it puts too much mental load on the user. I thought jj was alleviating that somewhat, but it looks like I have to keep track of even more.

PhilipMetzger commented 1 year ago

One of the problems I have with Git is that it puts too much mental load on the user. I thought jj was alleviating that somewhat, but it looks like I have to keep track of even more.

No, you still are correct, jj reduces the mental load.

So instead of explaining it, you reinforced my view that it is odd to make a new empty commit and refer backwards to the previous one with @- to push it.

I probably missunderstood your question, could you rephrase it for my benefit?

JJ does not force you to create a new commit, but people have it ingrained in them that they start new work with commit. With JJ the command is only a builtin alias to jj describe -m "message" && jj new.

Are you going to add your new example with the two branches?

I don't think so, it will be rather appropriate for #1960.

necauqua commented 1 year ago

So instead of explaining it, you reinforced my view that it is odd to make a new empty commit and refer backwards to the previous one with @- to push it.

This is just git brain not letting you go :) I promise you once you get used to it jj is so much simpler yet more powerful than vanilla git (if you never get used check out git-branchless)

While @ is techincally indeed a "new commit", it's the new commit you're editing, it's not final and it's basically what replaces the staging area - and the parent commit is more or less "finalized" and ready to be pushed unless you edit it

You can try jj edit @- and see how it looks like, now you're editing the parent, and each time you make changes to the repo and run any jj command those changes will get amended to was-@- (which is now @ as you're editing it) and rebase its child (which was @ but now its @+)

Ok that last sentence probably really didn't help but it all will click, git model is so engrained in the brain it is indeed a bit hard for people to grasp the beauty of jjs model sadly 🤷

Also indeed jj commit is just short for jj describe && jj new, same as jj merge is also a shortcut for simply calling jj new on >= 2 commits - those shortcuts are handy when coming from git (and just as a shorthand in case of commit), but they add confusion too

Saying that, I remembered the words someone said somewhere: in git you git commit to finish a commit, in jj you jj new to start a new one

joyously commented 1 year ago

You can try jj edit @- and see how it looks like, now you're editing the parent, and each time you make changes to the repo and run any jj command those changes will get amended to was-@- (which is now @ as you're editing it) and rebase its child (which was @ but now its @+)

THIS is the more I have to keep track of, so it is adding mental load. I have to know which commands make a new commit and which don't, as well as where my @ is parented.

This is just git brain not letting you go :)

Not. I don't have much experience with Git.

I probably misunderstood your question, could you rephrase it for my benefit?

I gave an alternate example to see if it was the same thing. Other parts of the documentation stress that @ is just another commit, so I didn't find your example of using @- helpful. In fact, it was a little confusing because if you read docs out of order, you don't know what @ is. So, to improve this doc, show multiple examples of how to do things. I'm not sure if the branch part is clear yet. This doc is about GitHub, so it's the pushing part that is important, but you might want to mention other commands that talk to GitHub.

PhilipMetzger commented 1 year ago

I gave an alternate example to see if it was the same thing. Other parts of the documentation stress that @ is just another commit, so I didn't find your example of using @- helpful. In fact, it was a little confusing because if you read docs out of order, you don't know what @ is. So, to improve this doc, show multiple examples of how to do things.

Ok, this is something actionable which I can do in the pr. The workflows are the same. To re-iterate my point, It does not matter, if a commit is created or not, it's just convenience.

I'm not sure if the branch part is clear yet. This doc is about GitHub, so it's the pushing part that is important, but you might want to mention other commands that talk to GitHub.

Do you mean branch creation locally with jj branch create or jj git push? At the moment, there are only two commands which interact with remotes, jj git fetch and jj git push where only jj git push is able to create new branches on the remote.

joyously commented 1 year ago

Do you mean branch creation locally with jj branch create or jj git push? At the moment, there only two commands which interact with remotes, jj git fetch and jj git push where only jj git push is able to create new branches on the remote.

I don't know enough to answer this, but expect the doc to lay it all out for me. Isn't there a clone command that would access a remote? If I use a branch command, can I "clone" the branch from GitHub? Or is that some other command? (How do I grab someone's branch to test it without polluting my repo?)

necauqua commented 1 year ago

THIS

I mean to do the same in git you need to checkout a new temp branch at parent commit, amend things to that commit and manually rebase the child onto it (which for some people is hard as they don't know to use very not confusingly named --onto), switch back to the child branch and delete the temp branch - and in jj you can edit the commit basically directly and it will all just work automagically 🤷

I have to know which commands make a new commit and which don't, as well as where my @ is parented.

Well, the main command that creates new commits is jj new, jj merge/commit are just shorthands I'd be happy to get rid of; And anyway.. yes?. This does not seem like a lot of mental load to me

For the @ parenting - again, ..yes? It is still a VCS with commits and stuff and you have to know (by using basic jj log) what commit are you on etc.. It's not by any means harder than git and our argument is that it's easier than git because of the changes/improvements jj makes to some of git concepts.

Hearing that you don't have much experience with git you may have not met that much of git complications that jj solves/adjusts really well, especially those related to staging area or rebases. At least the oplog/undo is a killer feature that's kind of not really in git (reflog being the closest thing) :) For the git brain comment - oh well often people are confused about @ similarly to you because they've done too much git 🤷

Anyway my responses have been off the topic - yeah, the docs are kind of oriented more at people familiar with git and might miss some things that to us seem obvious, thanks for laying out some of them

joyously commented 1 year ago

It is still a VCS with commits and stuff and you have to know (by using basic jj log) what commit are you on etc..

This is the git brain talking. Please Apply your explanation to the other part of the docs. From my point of view, the VCS only holds versions that I have designated ready. I understand that jj saves your work in progress so that can be an advantage, but the whole rebase thing is experientially inferior with regard to GitHub and sharing repositories. (I've been following this repo and stopped clicking on the links because GitHub can never find the commits. Maybe that ought to be mentioned here.)

PhilipMetzger commented 1 year ago

I don't know enough to answer this, but expect the doc to lay it all out for me.

I consider that out of scope for this doc, there's even a disclaimer in the document.

Isn't there a clone command that would access a remote?

Yes, there's clone but it's only used for the initial fetch of the repository.

If I use a branch command, can I "clone" the branch from GitHub?

By default jj git clone will copy all active branches, so your coworkers branch should be available locally.

If I use a branch command, can I "clone" the branch from GitHub?

The jj branch commands only work in a local context, so this is not possible.

Or is that some other command? (How do I grab someone's branch to test it without polluting my repo?)

As previously explained, by default your coworkers branch is directly available locally. This means you're able to jj new onto it and continue iterating on it.

To return to an empty commit of the default branch, use jj new $default-branch.

joyously commented 1 year ago

Isn't there a clone command that would access a remote?

Yes, there's clone but it's only used for the initial fetch of the repository.

This was in reference to your comment of "At the moment, there only two commands which interact with remotes", so if clone does, your comment is incorrect.

If I use a branch command, can I "clone" the branch from GitHub?

By default jj git clone will copy all active branches, so your coworkers branch should be available locally.

It won't be there if it is created after my clone command.

Or is that some other command? (How do I grab someone's branch to test it without polluting my repo?)

As previously explained, by default your coworkers branch is directly available locally. This means you're able to jj new onto it and continue iterating on it.

Are you saying I have to clone the whole repo every time a coworker adds a branch? And I don't want to add onto it; I want to test it without messing up what I'm working on. If I do jj git fetch, will it pull in those other branches and I would have to delete them later?

PhilipMetzger commented 1 year ago

This was in reference to your comment of "At the moment, there only two commands which interact with remotes", so if clone does, your comment is incorrect.

To be even more precise, jj git clone is a one-time command. It only exists for the initial clone. But you are correct about the existence of a third command.

It won't be there if it is created after my clone command.

It will be here after every jj git fetch, as Jujutsu fetches all branches by default (arguably a (mis)feature, which confuses a lot of newcomers) , which you must use until something like jj sync gets implemented.

Are you saying I have to clone the whole repo every time a coworker adds a branch?

No, as long as your coworkers branch is available on the remote, jj git fetch will update it.

And I don't want to add onto it; I want to test it without messing up what I'm working on.

Then you should use jj edit $branch-name, inspect the changes and decide how to proceed.

If I do jj git fetch, will it pull in those other branches and I would have to delete them later?

Another (mis)-feature of the default behavior is, that the local branch is persisted until it's deleted on the remote. After this sequence: jj branch forget $branch-name, jj git fetch, jj rebase -d $default-branch, your coworkers branch will be once again available locally. If you do jj branch delete $branch-name, it will be gone for everybody after a jj git push.

joyously commented 1 year ago

I think you can improve this doc by explaining the branches, or linking to a doc that does. It's a pretty common thing for a GitHub user to want to test a PR for review.

PhilipMetzger commented 1 year ago

I think you can improve this doc by explaining the branches, or linking to a doc that does. It's a pretty common thing for a GitHub user to want to test a PR for review.

Which parts do you mean? Most of the things mentioned here, belong into a fully fleshed out tutorial. I consider github.md a crutch until it is created.

joyously commented 1 year ago

Well, my opinion is that people don't read all the docs there are. They jump to the part they need. So I suggest that this particular doc answers the questions they have for GitHub, concerning branches being deleted (or not) and how to get the branch they need to test a PR. If these things apply to more than GitHub, a link to the appropriate section is fine.

necauqua commented 1 year ago

This is the git brain talking

Okay, jj does not replace git completely with new concepts, one of the selling points is git backend and colocated repos; it only improves upon git in some areas which are common pain points for git users and has generally a nicer ux 🤷

So git brain is good in understanding how it works, because ultimately jj is a really nice git frontend at the moment, but it's bad in grasping the new model where instead of finishing commits you start new ones etc.

the whole rebase thing is experientially inferior

I assume you are talking more about rewrites. Most of the things related to rewrites/rebases and so on usually happen in the local clone, you can edit and tidy up the history however you want before pushing - and what I'm trying to sell you is that in jj it's significantly easier to do than in vanilla git.

The workflow where instead of pushing new commits on the feature branch you amend/edit them and force-push the rewritten branch is common in many projects, in this one too, this is not jj-specific although jj does lean into that direction, yes. However you can absolutely just never push rewrites to remotes and just make new commits (that you can freely edit around before pushing) to avoid that issue/workflow.

The issue with bad links is GitHub - I assume it immediately deletes the rewritten commit for some reason (super-aggressive gc?), for example in a GitLab merge request all versions including rewrites are kept intact and you can see the diffs between them etc, it's pretty nice.

From my point of view, the VCS only holds versions that I have designated ready

Does this not answer your own question about why @- should be pushed and not @?

The working copy commit (@) is specifically the one that's not ready to be pushed, as it holds the current state of the repo whatever it is, and when you're done with it, you start a new one with jj new or the convenient shortcut jj commit which also adds/edits a description to the commit you've finished.

This is at the very least not more complicated that what's done in git and many-many longtime git users myself included find pleasure in how easy and convenient this approach of jj makes things

PhilipMetzger commented 1 year ago

I'm going to close this issue, as many points were adressed by #2158. I suggest to move further tutorial and branching related conversations to #1960, which covers a extensive tutorial and a in-depth conversation about branching models.