It turns out that the use case I had for `exactly()` was slightly more
subtle, and I need range support. In particular, usage of `exactly()`
in expressions used by `revsets.log-graph-prioritize` can and will
cause `jj log` to fail if the assertion fails; in my case, a particular
expression I use should be equal to zero-or-one revisions.
This (ab)uses string literal syntax to parse out a range that is like
a subset of Rust's range syntax; in particular unbounded endpoints like
`x..` or `..=y` are not supported. Ideally the grammar would be expanded
to handle this case more smoothly.
Signed-off-by: Austin Seipp <aseipp@pobox.com>
The migration logic is basically the same as 717d0d3d6d "git: on
deserialize/import/export, copy refs/heads/* to remote named git." Now
git::import_refs() processes bookmarks and tags in the same way.
git::export_refs() is unchanged because we don't have any commands that would
move local tags internally.
Git-tracking tags will be stored there. I don't have a concrete plan for proper
remote tags support, but I think tags fetched/pushed internally can be recorded
as remote tags.
I'm thinking of adding remote tags table to support tag mutation commands, so I
think it's time to update the storage format. RefTarget is serialized to a list
of alternate terms because we don't need to support legacy formats here.
Having tests illustrates the behavior. Making this public de-duplicates
the code with ERSC. This also allows determining whether a change id
comes from the header or is synthetic.
This is just a nice-to-have for me, we will also duplicate the code
until this is merged (if that happens).
This fixes the bug described below.
I have `submodule.recurse=true` set in my .gitconfig. When trying
to fetch repos with submodules (e.g. git/git), I got errors like these:
```console
$ jj git fetch
remote: Enumerating objects: 853, done.
remote: Total 853 (delta 448), reused 439 (delta 413), pack-reused 315 (from 2)
Error: Git process failed: External git program failed:
Could not access submodule 'sha1collisiondetection'
```
This error occured when fetching only, *not* when cloning. It occured
even when there wasn't anything to fetch.
I only tested repositories that never had submodules initialized or
fetched (which would have to be done with Git).
I think this helps readability a bit. I updated `TreeDiffEntry` and a
few related places. I think there are many other places where we could
use the new type.
I'm about to add a generic `Diff<T>` that's more similar to
`Merge<T>`, so I want to free up the name. It seems better to have
`Diff<T>` and `ContentDiff` than e.g. `GenericDiff<T>` and `Diff` or
having to use qualified imports.
1.90 was just released, so this seems reasonable, and it finally lets us
use let-chains. This includes all the clippy fixups too, and some small
changes suggested by Ilya.
Signed-off-by: Austin Seipp <aseipp@pobox.com>
With `all:` having gone away, some users (including me) had been using it
to enforce an invariant: by omitting it, an expression was guaranteed to
yield exactly one result. For example, this is important when using tools
like `jj rebase -B/-A`
Instead, let's fix that case by building that functionality into the
revset language itself. The previous behavior can now be enforced via
the term `exactly(x, 1)`
In the future, `n` could also be a range.
Signed-off-by: Austin Seipp <aseipp@pobox.com>
This code was added by 4af678848d "op_store: minimal change to load/store
tracking state of remote branches" (2023-10-16). It's unlikely that the head
operation was written by jj older than that. Remote refs in old views are now
mapped to State::New unconditionally, which should be okay for read-only
operations.
`MergeOptions` isn't currently used directly in either module but it's
more closely related to `tree_merge`. It's possible we will want to
pass it into `ConflictIterator`, however.
`merged_tree.rs` is getting too big. The code for merging/resolving
trees is quite well separated from `MergedTree`'s core logic of
creating a view of the merged input trees on the fly.
I have no idea if we can change the default, but maybe we can conditionally
disable the same-change rule to get rid of hacks in squash_commits(), etc.?
resolve_file_executable() doesn't respect the Store configuration. I'm not sure
if that's the right choice, but it seemed better to accept duplicated change
than falling back to executable=false.
#6369
I'll add same-change rule parameter to disable A+(A-B)=A resolution. Since tree
merging involves content merging, file-level parameters should also be included
in the "tree" merge options. We could add a nested options type, but I don't
think we'll add an option that applies only to tree-level merging. So this patch
unifies these options types as MergeOptions.
merge_ref_targets() uses SameChange::Accept rule explicitly. Since ref changes
are resolved based on ancestry, it seems good to resolve same-change conflicts
as well.
Adds a new `--when.platforms` condition for including configuration.
This is useful when someone syncs their dotfiles across machines.
The values for `platforms` are defined by `std::env::consts::FAMILY` and
``std::env::consts::OS. Any Unix-family platform can be specified using
the value `"unix"`, or individual operation systems can be chosen with
`"linux"`, `"macos"`, or `"windows"`.
Example:
```toml
ui.pager = ["less", "-FRX"]
[[--scope]]
--when.platforms = ["windows"]
ui.pager = ["C:/Program Files/Git/usr/bin/less.exe", "-FRX"]
```
This option affects emptiness of commits, which means indexed changed files can
become stale on configuration change. This problem can also be said for changes
in the diff algorithms, so I don't think we need a logic to invalidate index on
config change.
I have this patch for months, and it seems working good at least for Rust
sources.
Closes#17
I'll add word-by-word merging flag. Since we need to run auto-merge with the
configured options, these options are carried by the Store for now. When we add
a "jj resolve" flag to run auto-merge with different configuration, we might
have to parameterize the options passed in to MergedTree::resolve().
As suggested by @PhilipMetzger
The word "grey" is whitelisted because
- we have a contributor of that name
- we use a library that uses "Grey" as a member of an enum
- I refuse to believe "grey" is not US English
We want these to be `Send` and `Sync` so we can send them between
threads in our multi-threaded backend. This requires a bunch of subsequent
(but obvious) changes throughout cli and the tests.
Co-authored-by: Benjamin Brittain <ben@ersc.io>
Signed-off-by: Austin Seipp <austin@ersc.io>
Signed-off-by: Austin Seipp <aseipp@pobox.com>
It seemed odd that we had to pass ConflictMarkerStyle to snapshot functions.
Suppose materialize/parse functions aren't lossy, we can compare hunks in
Vec<Merge<BString>> form. This should also be robust for configuration changes.
test_materialize_parse_roundtrip_different_markers() is simplified as there
should no longer be "pair" of marker styles.
We haven't written legacy/path-level conflicts since jj 0.11 (Nov
2023). This patch makes the Git backend return legacy conflicts as the
regular JSON-containing files they are represented by.
Legacy trees (those with conflicts recorded at the path level) have
not been created since 0.11 (Nov 2023). We're about to deprecate them
now. This patch removes support for them in the working copy. If
anyone still has a commit checked out at a legacy tree, we will now
interpret that as a modern tree, meaning that any conflicts will
appear as regular files with JSON contents in the previous snapshot,
so if we re-snapshot the working copy (and e.g. the mtime has
changed), these files will become resolved with the conflicts markers
still in them.
I think it's quite unlikely that anyone has working copies this old so
I didn't mention it in the changelog.
Closes https://github.com/jj-vcs/jj/issues/7189
Colocated repos have some advantages and some disadvantages. On the
whole, I think making Git repos colocated by default is a better
trade-off, especially for new users. With the `git.colocate` setting,
(experienced) users can easily change this according to preference.
A non-exhaustive list of pros and cons of colocated repos:
pros:
* Many code editors show the changes one is currently working on based
on Git's "dirty worktree".
* There are a lot of tools that integrate with Git which don't work at
all in non-colocated repositories.
* There are a lot of Git features that Jujutsu doesn't have yet. When
users ask for them, the answer is usually: "Just colocate your repo
and run git directly for now." It's a strength that Jujutsu can focus
on what makes it special and not have to rush the reimplementation of
every niche feature of Git. Examples: `git rebase` tracking file
renames, `git bisect`, `git tag`, `git range-diff`, submodules.
cons:
* Jujutsu performs worse in colocated repositories with lots of refs,
because of the automatic `jj git import`.
* Colocated repos make branch@git references show up in Jujutsu output,
which is usually just aesthetically displeasing or possibly even
confusing to inexperienced users.
* Interleaving jj and (mutating) git commands can lead to confusing
situations. Examples:
* Creating a commit with git instead of jj will often leave a
duplicate "work in progress" commit in Jujutsu's log.
* Some IDEs periodically run `git fetch` in the background. This can
lead to conflicted branches and divergent change IDs, something many
people struggle with.