Closed Cretezy closed 4 months ago
I believe we've pretty much achieved consensus on adding --create
to jj branch set
, just nobody has implemented it yet.
It should be fairly straightforward to add if you want to give it a try (check the existing implementations for set
and create
; I wouldn't be surprised if set
had a specific check that the branch exists first, which you could just omit in this case — that's how set
used to function.)
Why have two separate subcommands (set
and create
)? Aren't they really the same thing?
@joyously only from an implementation perspective, I think.
INSERT
and UPDATE
are distinct operations, and you can't use them interchangeably.I think it's okay to deprecate branch create
if we add set --create
/--allow-new
. To me, the verb set
can also mean creation, and the typo problem is mostly addressed by requiring --allow
flags for unusual movements.
I agree with making set
also create branches by default.
The end result of both commands is the same: a branch exists and is set to a revision. I can't think of any use case where we would want to throw an error when setting a branch that doesn't exist.
We could add a --no-create
flag to set
which would error when the branch doesn't exist, restoring the behavior of branch create
.
Once the we decide on the behavior, I can take up creating the PR.
the typo problem is mostly addressed by requiring --allow flags for unusual movements.
The typo problem is addressed for the case when you've typoed a branch name but accidentally produced another valid branch name (which happens), but it doesn't address the case when you create a new branch entirely unintentionally. (I recall cases earlier in my career where I spent some time trying to figure out, for example, why a push wasn't doing anything, where it turned out that I didn't actually update the branch that I thought I did, although this is somewhat mitigated by better tools for visualization.) (cc @ilyagr who I thought had complained about typos as well?)
I can't think of any use case where we would want to throw an error when setting a branch that doesn't exist.
The most obvious error case is when someone makes a typo in a branch name and they intended to update an existing branch.
I'm opposed to making set
the default way to create branches unless
touch
command is also a primary way to create files? Does that resemble how anyone uses the filesystem in a GUI? They are very different; only Unixbrains would consider them the same operation. I think we should re-examine many of those biases, natural to us, before we bring them into jj, which might server a broader audience.jj set
to create) is likely more convenient than having separate commands, so I don't think this criterion is contended.create
for discoverability, even if set --create
exists: https://github.com/martinvonz/jj/issues/3518#issuecomment-2067770819(Another solution is to completely drop branches as a core feature, adopt topics or something else, and stop worrying about whether the branch UI makes sense 🤣)
Another solution is to completely drop branches as a core feature, adopt topics or something else
I'm all for this, but you still have the problem of defining what it is and how it works. If jj
has the branch concept for every backend, it should work the same for every backend. The same goes for topics and tags. I think what confuses things is that the log is shown as a graph, so branch means a line of development. Having it as a pointer to a revision is more like a tag or bookmark, so it doesn't match the graph definition. (yes, I understand how Git does the same thing, but the Git branch moves)
Since there is no "current" branch in jj
the only use is to label the graph and push to Git.
I personally wouldn't hang the design on the fact that people sometimes mistype a name. There is undo
and also can't you rename a branch?
My opinion on the whole create
/set
split is that it generally helps users like myself who tend to litter the branch names with typos. It was really nice when branch set
stopped to create seemingly "correct" branches, which were just typos. I'm in general for keeping both jj branch set --create
and jj branch create
, as they're a good UI. (See a previous discussion here)
I'm also in favor of renaming the current branches concept to bookmarks, as they're totally misleading for long term Git users, and actually accurately describing the current behavior.
I think there's a good amount of reflection from @arxanas's post, but I think there's also one element missing: just because how people work with computers changes doesn't mean everything should adapt. I think keeping creation and setting separate makes a lot of sense from a correctness standpoint. I'd much more strongly prefer we use --allow-new
instead of --create
, to encourage creating branches (or topics, or whatever they become) explicitly.
Using branch set --create
as a default will lead to people blurring out the fact that they are opening themselves to creating new branches, because they'll mentally erase --create
when they think they aren't actually going to be creating. branch set --allow-new
doesn't have the risk of seeing --allow-new
as not being part of the specific context, as it's adding permission, not changing the nature of the operation, from the user's perspective.
the typo problem is mostly addressed by requiring --allow flags for unusual movements.
To be clear, I don't mean jj branch set
should create new branch by default nor --allow-new
/--create
should be the default. It's a footgun.
[EDIT] I was wondering if we would add jj tag set
/create
pair, which seemed redundant because tags usually don't move, but we'll need something like tag set --allow-move
to fix up mistake. It might be better to make "set" be a create-or-overwrite-if-allowed command, and rename the current jj branch set
to e.g. move
, but I'm not sure.
I've opened a PR to add the create option to set: https://github.com/martinvonz/jj/pull/3585
I think the best point for this is that adding -c
at the end of the previous command is quick if the set
command fails due to the branch not existing.
Another alternative could be prompting the user in the CLI to create the branch after set
fails.
I'm a little late to the discussion, but we could have jj branch move
to move branches (what set
does now) and jj branch set
to move or create branches.
(Indeed, as Waleed mentioned, I do regularly make typos and care about them)
From my usage, it's often that I want to quickly create a branch after seeing it doesn't exist. For example:
$ jj branch set test -r @
Error: No such branch: test
Hint: Use `jj branch create` to create it.
$ jj branch set test -r @ -c
Edit: Additionally, it matches the behaviour of other tools like git switch
That's a good point, -c
sounds better in this case.
I want to quickly create a branch after seeing it doesn't exist.
jj branch create
exactly does that.
(I thought create
could be combined into new (create-or-move) set
, but maybe I'm wrong.)
I think the point was that adding -c
to a command-line is easier than replacing "set" with "create". At least, this would avoid a minor hassle for me.
I think the point was that adding
-c
to a command-line is easier than replacing "set" with "create".
Yeah, I agree, but if the user doesn't want to overwrite an existing branch, he doesn't have to try jj branch set
at all. And if he want to do upsert, create-or-move version of set
will do that.
I've added jj branch move --from=REV|NAME
, which can be used in place of typo-safe jj branch set
command #3895, As the next step, I'll probably add jj branch set --allow-new
flag.
I was thinking of introducing the following changes, but (1) can be footgun for existing users. So even if we plan to change the default behavior, it's better to keep the current behavior (with deprecation warning) for a moment.
jj branch set
do upsert by default (i.e. --allow-new
by default)jj branch set --new
(or --deny-move
) option to support "never move, just create" use casejj branch create
Reasons for (1):
set
sometimes adds new item (e.g. jj config set
)Reasons for (2) and (3):
set
can create branch, separate create
command is redundantbranch create
command preserves remote tracking state if existed, which is weird as a "create" operation. If the command were named as set
, this behavior (+ warning message) seems okay. #3884I'm getting less sure about (2) and (3).
Another more controversial idea is:
jj branch create
to jj branch set
jj branch set --allow-move
(or --allow-forward
) option to support "upsert" use caseThe motivation for the rename is that "create" has stronger implication than "set", so it's difficult to extend the behavior by adding command-line flags. However, we want flags because it's easier to type than replacing command name.
Related discussions:
Is your feature request related to a problem? Please describe. When working with Git, I need to remember if a branch is already created before updating it.
For example,
jj branch set my-branch -r @-
gives aError: No such branch
error. I then need to change the command tojj branch create my-branch -r @-
Describe the solution you'd like
An option on
jj branch set
such as-c
/--create
to create the branch if it does not exist.Example:
jj branch set my branch -r @- -c
Describe alternatives you've considered
Writing a shell alias for
jj branch set $args || jj branch create $args
(pseudo-code).