commits
Previously, the function relied on both the `self.parent_mapping` and
`self.rebased`. If `(A,B)` was in `parent_mapping` and `(B,C)` was in `rebased`,
`new_parents` would map `A` to `C`.
Now, `self.rebased` is ignored by `new_parents`. In the same situation,
DescendantRebaser is changed so that both `(A,B)` and `(B,C)` are in
`parent_mapping` before. `new_parents` now applies `parent_mapping` repeatedly,
and will map `A` to `C` in this situation.
## Cons
- The semantics are changed; `new_parents` now panics if `self.parent_mapping`
contain cycles. AFAICT, such cycles never happen in `jj` anyway, except for
one test that I had to fix. I think it's a sensible restriction to live with;
if you do want to swap children of two commits, you can call
`rebase_descendants` twice.
## Pros
- I find the new logic much easier to reason about. I plan to extract it into a
function, to be used in refactors for `jj rebase -r` and `jj new --after`. It
will make it much easier to have a correct implementation of `jj rebase -r
--after`, even when rebasing onto a descendant.
- The de-duplication is no longer O(n^2). I tried to keep the common case fast.
## Alternatives
- We could make `jj rebase` and `jj new` use a separate function with the
algorithm shown here, without changing DescendantRebaser. I believe that the new
algorithm makes DescendatRebaser easier to understand, though, and it feels more
elegant to reduce code duplication.
- The de-duplication optimization here is independent of other changes, and
could be used on its own.
We could add Layout struct holding these parameters, but I don't think that's
needed just for two parameters.
Added pub(super) where needed. There are a few pub(super) fields that look
suspicious, which will be fixed by the subsequent patches.
into_segment() could be added instead of save_in(), but I decided to wrap
save_in(). save_in() may squash ancestor files, so it could be considered an
index-level operation.
Added pub(super) where needed or makes sense.
This tries to clarify the fact that the branches must be remote and the syntax
for specifying them as globs.
Cc @yuja, https://github.com/martinvonz/jj/pull/2625#discussion_r1423379351
Here is the result (excerpt):
```
$ jj branch track --help
Start tracking given remote branches
A tracking remote branch will be imported as a local branch of the same name. Changes to it
will propagate to the existing local branch on future pulls.
Usage: jj branch track [OPTIONS] <BRANCH@REMOTE>...
Arguments:
<BRANCH@REMOTE>...
Remote branches to track
By default, the specified name matches exactly. Use `glob:` prefix to select
branches by wildcard pattern. For details, see
https://github.com/martinvonz/jj/blob/main/docs/revsets.md#string-patterns.
Examples: branch@remote, glob:main@*, glob:jjfan-*@upstream
```
Added pub(super) where needed.
This wouldn't matter, but seemed slightly better.
Added pub(super) where needed or makes sense.
IndexLoadError isn't store-specific, but I think it's better to put I/O
stuff in the store module.
default_index_store.rs is relatively big, and it contains types and impls in
arbitrary order. Let's split them into sub modules. After everything moved,
mod.rs will only contain tests.
Bumps the cargo-dependencies group with 3 updates: [libc](https://github.com/rust-lang/libc), [rustix](https://github.com/bytecodealliance/rustix) and [tokio](https://github.com/tokio-rs/tokio).
Updates `libc` from 0.2.150 to 0.2.151
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.150...0.2.151)
Updates `rustix` from 0.38.27 to 0.38.28
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.27...v0.38.28)
Updates `tokio` from 1.34.0 to 1.35.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.34.0...tokio-1.35.0)
---
updated-dependencies:
- dependency-name: libc
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: cargo-dependencies
- dependency-name: rustix
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: cargo-dependencies
- dependency-name: tokio
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: cargo-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
There's only one caller, and we have common code at the call site.
I'm going to remove 'index lifetime from InternalRevset so Revset<'static>
can be easily constructed from DefaultReadonlyIndex. As the first step, this
series removes some lifetime complexity from EvaluationContext methods.
We don't need an descendant iterator API, but it helps to add separate function
to collect into HashSet<IndexPosition> instead of returning a pair of
ordered vec and set.
This prints a hint about using `jj new <first conflicted commit>` and
`jj squash` to resolve conflicts. The hint is printed whenever there
are new or resolved conflicts.
I hope this hint will be useful especially for new users so they know
which commit to resolve conflicts in first. It may not be obvious that
they should start with the bottommost one. I hope the hint will also
be useful for more more experienced user by letting them just copy the
printed command without first running `jj log` to find the right
commit..
When e.g. `jj rebase` results in new conflicts, it's useful for the
user to learn about that without having to run `jj log` right
after. This patch adds reporting of new conflicts created by an
operation. It also add reporting of conflicts that were resolved or
abandoned by the operation.
There was no measurable performance impact when rebasing a single
commit in the Linux kernel repo.
The wrapper type isn't needed for the mutable layer, but this mirrors the
readonly type structure. Test cases are also migrated to be using the index
wrapper so long as we don't have to care for the nesting of the segment files.
Prepares for splitting MutableIndexImpl into segment and index wrapper types.
Not all reasons are actionable, but we print hint in common cryptic cases.
The idea is that the ReadonlyIndexSegment is a sub component of the index. The
Index trait could be implemented for any Segment type, but we don't need a
public interface to access sub segment as an index.
I'm going to split the internal Segment types and the public Index types
in order to clarify the layering concept. The public Index types will be
wrappers like DefaultReadonlyIndex.
Strictly speaking, ReadonlyIndexImpl is a segment + parent pointer pair,
but I think calling it a segment is pretty okay. It could be called a
ReadonlyIndexFile, but "File" can't apply to the mutable part.
This matches the store naming: impl IndexStore for DefaultIndexStore. I also
added minimal doc comment and Debug.
I'm going to rename the impl types, and I don't want to think about the
names of these downcast functions.
FailedToDelete/Set reasons are boxed because gix error types aren't small.
They could be casted to std::error::Error if needed.
Gitoxide errors don't implement PartialEq. We could instead stringify the
errors, but there aren't many callers who expect FailedRefExportReason to
be comparable.
Gitoxide errors don't implement PartialEq, and I don't think it makes sense
to test equality of InternalGitError objects.
Bumps the cargo-dependencies group with 1 update: [rustix](https://github.com/bytecodealliance/rustix).
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.26...v0.38.27)
---
updated-dependencies:
- dependency-name: rustix
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: cargo-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
We use .as_any() to downcast to the backend impl instead.
Bumps the cargo-dependencies group with 1 update: [once_cell](https://github.com/matklad/once_cell).
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.18.0...v1.19.0)
---
updated-dependencies:
- dependency-name: once_cell
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: cargo-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
The git_target path is normalized and managed by jj, so we don't need a
fallback mechanism. Let's make it stricter.
Bumps the github-dependencies group with 1 update: [actions/setup-python](https://github.com/actions/setup-python).
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)
---
updated-dependencies:
- dependency-name: actions/setup-python
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: github-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
Thanks to everyone who's contributed!
Before, an absolute path would be saved in the git_target file if .git is a
symlink. That's not wrong, but seemed a bit weird. Let's consolidate the
behavior across .git file types.
Apparently, I forgot to update it in 1db033504ca9 "repo, workspace: remove
'static lifetime bound from initializer functions."
Apparently, libgit2 doesn't deduce "core.bare" config from the directory name,
but gitoxide implements it correctly. So we shouldn't blindly canonicalize
the Git repository path. Fortunately, the saved git_target path isn't a fully-
canonicalized form (unless user explicitly sepcified "--git-repo ./.git"), so
we don't need a hack to remap git_target back to the symlink path.
is_colocated_git_workspace() is adjusted since the git_workdir is no longer
resolved from the fully-canonicalized repo path, at least in our code. Still we
have the ".git/.." fallback because test_init_git_colocated_symlink_gitlink()
would otherwise fail. I haven't figured out why, and the test might be actually
wrong compared to the git CLI behavior, but let's not change that for now.
Fixes #2668
A git repo created by the "repo" tool doesn't have core.base set, which means
the "bare"-ness relies on the directory name. Gitoxide appears to parse it
correctly, whereas libgit2 doesn't. That's why the symlinked .git repo is no
longer processed as a colocated repo.
#2668
Bumps the github-dependencies group with 2 updates: [DeterminateSystems/nix-installer-action](https://github.com/determinatesystems/nix-installer-action) and [DeterminateSystems/magic-nix-cache-action](https://github.com/determinatesystems/magic-nix-cache-action).
Updates `DeterminateSystems/nix-installer-action` from 8 to 9
- [Release notes](https://github.com/determinatesystems/nix-installer-action/releases)
- [Commits](https://github.com/determinatesystems/nix-installer-action/compare/07b8bcba1b22d847db7ee507180c33e115499665...cd46bde16ab981b0a7b2dce0574509104543276e)
Updates `DeterminateSystems/magic-nix-cache-action` from a04e6275a6bea232cd04fc6f3cbf20d4cb02a3e1 to 1402a2dd8f56a6a6306c015089c5086f5e1ca3ef
- [Release notes](https://github.com/determinatesystems/magic-nix-cache-action/releases)
- [Commits](https://github.com/determinatesystems/magic-nix-cache-action/compare/a04e6275a6bea232cd04fc6f3cbf20d4cb02a3e1...1402a2dd8f56a6a6306c015089c5086f5e1ca3ef)
---
updated-dependencies:
- dependency-name: DeterminateSystems/nix-installer-action
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: github-dependencies
- dependency-name: DeterminateSystems/magic-nix-cache-action
dependency-type: direct:production
dependency-group: github-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
Bumps the cargo-dependencies group with 1 update: [clap](https://github.com/clap-rs/clap).
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.10...v4.4.11)
---
updated-dependencies:
- dependency-name: clap
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: cargo-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
In https://github.com/martinvonz/jj/pull/2665#issuecomment-1837552283,
a user used `$base` instead of one of the `$output`s and nothing worked.
This seems like a natural mistake to make, the config is confusing.
This adds an initial `jj util gc` command, which simply calls `git gc`
when using the Git backend. That should already be useful in
non-colocated repos because it's not obvious how to GC (repack) such
repos. In my own jj repo, it shrunk `.jj/repo/store/` from 2.4 GiB to
780 MiB, and `jj log --ignore-working-copy` was sped up from 157 ms to
86 ms.
I haven't added any tests because the functionality depends on having
`git` binary on the PATH, which we don't yet depend on anywhere
else. I think we'll still be able to test much of the future parts of
garbage collection without a `git` binary because the interesting
parts are about manipulating the Git repo before calling `git gc` on
it.
This matches how most other commands with subcommands are handled.
I think this is a variant of the problem fixed by 7fda80fc2221 "tree: simplify
conflict before resolving at hunk level." We need to simplify() the conflict
before and after extracting file ids because the source conflict values may
contain trees to be cancelled out, and the file values may differ only in exec
bits. Since the legacy tree passes a simplified conflict in to this function,
I made the merged tree do the same.
Fixes #2654
Otherwise an empty subtree would be added to the parent tree.
If the stored tree contained an empty subtree, simplify() wouldn't work
against new "absent" subtree representation. I don't know if there's a
such code path, but I believe it's very rare to encounter the problem.
#2654
See comments inline for details. Cc #2600.
In particular, I wanted to make sure these behaviors are not affected by #2646.
They don't seem to be.
The tests ended up weirder than expected because of
https://github.com/martinvonz/jj/issues/2600#issuecomment-1835418824. Even
though, right now, the behavior of tests is unaffected by that issue, the
*expected* behavior is different.
Branches move around a little confusigly with `abandon`. We do want to keep
them, to test their behavior, but we can show the change id to make things
clearer.
Previously, the function relied on both the `self.parent_mapping` and
`self.rebased`. If `(A,B)` was in `parent_mapping` and `(B,C)` was in `rebased`,
`new_parents` would map `A` to `C`.
Now, `self.rebased` is ignored by `new_parents`. In the same situation,
DescendantRebaser is changed so that both `(A,B)` and `(B,C)` are in
`parent_mapping` before. `new_parents` now applies `parent_mapping` repeatedly,
and will map `A` to `C` in this situation.
## Cons
- The semantics are changed; `new_parents` now panics if `self.parent_mapping`
contain cycles. AFAICT, such cycles never happen in `jj` anyway, except for
one test that I had to fix. I think it's a sensible restriction to live with;
if you do want to swap children of two commits, you can call
`rebase_descendants` twice.
## Pros
- I find the new logic much easier to reason about. I plan to extract it into a
function, to be used in refactors for `jj rebase -r` and `jj new --after`. It
will make it much easier to have a correct implementation of `jj rebase -r
--after`, even when rebasing onto a descendant.
- The de-duplication is no longer O(n^2). I tried to keep the common case fast.
## Alternatives
- We could make `jj rebase` and `jj new` use a separate function with the
algorithm shown here, without changing DescendantRebaser. I believe that the new
algorithm makes DescendatRebaser easier to understand, though, and it feels more
elegant to reduce code duplication.
- The de-duplication optimization here is independent of other changes, and
could be used on its own.
This tries to clarify the fact that the branches must be remote and the syntax
for specifying them as globs.
Cc @yuja, https://github.com/martinvonz/jj/pull/2625#discussion_r1423379351
Here is the result (excerpt):
```
$ jj branch track --help
Start tracking given remote branches
A tracking remote branch will be imported as a local branch of the same name. Changes to it
will propagate to the existing local branch on future pulls.
Usage: jj branch track [OPTIONS] <BRANCH@REMOTE>...
Arguments:
<BRANCH@REMOTE>...
Remote branches to track
By default, the specified name matches exactly. Use `glob:` prefix to select
branches by wildcard pattern. For details, see
https://github.com/martinvonz/jj/blob/main/docs/revsets.md#string-patterns.
Examples: branch@remote, glob:main@*, glob:jjfan-*@upstream
```
Bumps the cargo-dependencies group with 3 updates: [libc](https://github.com/rust-lang/libc), [rustix](https://github.com/bytecodealliance/rustix) and [tokio](https://github.com/tokio-rs/tokio).
Updates `libc` from 0.2.150 to 0.2.151
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.150...0.2.151)
Updates `rustix` from 0.38.27 to 0.38.28
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.27...v0.38.28)
Updates `tokio` from 1.34.0 to 1.35.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.34.0...tokio-1.35.0)
---
updated-dependencies:
- dependency-name: libc
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: cargo-dependencies
- dependency-name: rustix
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: cargo-dependencies
- dependency-name: tokio
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: cargo-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
I'm going to remove 'index lifetime from InternalRevset so Revset<'static>
can be easily constructed from DefaultReadonlyIndex. As the first step, this
series removes some lifetime complexity from EvaluationContext methods.
We don't need an descendant iterator API, but it helps to add separate function
to collect into HashSet<IndexPosition> instead of returning a pair of
ordered vec and set.
This prints a hint about using `jj new <first conflicted commit>` and
`jj squash` to resolve conflicts. The hint is printed whenever there
are new or resolved conflicts.
I hope this hint will be useful especially for new users so they know
which commit to resolve conflicts in first. It may not be obvious that
they should start with the bottommost one. I hope the hint will also
be useful for more more experienced user by letting them just copy the
printed command without first running `jj log` to find the right
commit..
When e.g. `jj rebase` results in new conflicts, it's useful for the
user to learn about that without having to run `jj log` right
after. This patch adds reporting of new conflicts created by an
operation. It also add reporting of conflicts that were resolved or
abandoned by the operation.
There was no measurable performance impact when rebasing a single
commit in the Linux kernel repo.
I'm going to split the internal Segment types and the public Index types
in order to clarify the layering concept. The public Index types will be
wrappers like DefaultReadonlyIndex.
Strictly speaking, ReadonlyIndexImpl is a segment + parent pointer pair,
but I think calling it a segment is pretty okay. It could be called a
ReadonlyIndexFile, but "File" can't apply to the mutable part.
Bumps the cargo-dependencies group with 1 update: [rustix](https://github.com/bytecodealliance/rustix).
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.26...v0.38.27)
---
updated-dependencies:
- dependency-name: rustix
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: cargo-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
Bumps the cargo-dependencies group with 1 update: [once_cell](https://github.com/matklad/once_cell).
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.18.0...v1.19.0)
---
updated-dependencies:
- dependency-name: once_cell
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: cargo-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
Bumps the github-dependencies group with 1 update: [actions/setup-python](https://github.com/actions/setup-python).
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)
---
updated-dependencies:
- dependency-name: actions/setup-python
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: github-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
Apparently, libgit2 doesn't deduce "core.bare" config from the directory name,
but gitoxide implements it correctly. So we shouldn't blindly canonicalize
the Git repository path. Fortunately, the saved git_target path isn't a fully-
canonicalized form (unless user explicitly sepcified "--git-repo ./.git"), so
we don't need a hack to remap git_target back to the symlink path.
is_colocated_git_workspace() is adjusted since the git_workdir is no longer
resolved from the fully-canonicalized repo path, at least in our code. Still we
have the ".git/.." fallback because test_init_git_colocated_symlink_gitlink()
would otherwise fail. I haven't figured out why, and the test might be actually
wrong compared to the git CLI behavior, but let's not change that for now.
Fixes #2668
Bumps the github-dependencies group with 2 updates: [DeterminateSystems/nix-installer-action](https://github.com/determinatesystems/nix-installer-action) and [DeterminateSystems/magic-nix-cache-action](https://github.com/determinatesystems/magic-nix-cache-action).
Updates `DeterminateSystems/nix-installer-action` from 8 to 9
- [Release notes](https://github.com/determinatesystems/nix-installer-action/releases)
- [Commits](https://github.com/determinatesystems/nix-installer-action/compare/07b8bcba1b22d847db7ee507180c33e115499665...cd46bde16ab981b0a7b2dce0574509104543276e)
Updates `DeterminateSystems/magic-nix-cache-action` from a04e6275a6bea232cd04fc6f3cbf20d4cb02a3e1 to 1402a2dd8f56a6a6306c015089c5086f5e1ca3ef
- [Release notes](https://github.com/determinatesystems/magic-nix-cache-action/releases)
- [Commits](https://github.com/determinatesystems/magic-nix-cache-action/compare/a04e6275a6bea232cd04fc6f3cbf20d4cb02a3e1...1402a2dd8f56a6a6306c015089c5086f5e1ca3ef)
---
updated-dependencies:
- dependency-name: DeterminateSystems/nix-installer-action
dependency-type: direct:production
update-type: version-update:semver-major
dependency-group: github-dependencies
- dependency-name: DeterminateSystems/magic-nix-cache-action
dependency-type: direct:production
dependency-group: github-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
Bumps the cargo-dependencies group with 1 update: [clap](https://github.com/clap-rs/clap).
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/v4.4.10...v4.4.11)
---
updated-dependencies:
- dependency-name: clap
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: cargo-dependencies
...
Signed-off-by: dependabot[bot] <support@github.com>
This adds an initial `jj util gc` command, which simply calls `git gc`
when using the Git backend. That should already be useful in
non-colocated repos because it's not obvious how to GC (repack) such
repos. In my own jj repo, it shrunk `.jj/repo/store/` from 2.4 GiB to
780 MiB, and `jj log --ignore-working-copy` was sped up from 157 ms to
86 ms.
I haven't added any tests because the functionality depends on having
`git` binary on the PATH, which we don't yet depend on anywhere
else. I think we'll still be able to test much of the future parts of
garbage collection without a `git` binary because the interesting
parts are about manipulating the Git repo before calling `git gc` on
it.
I think this is a variant of the problem fixed by 7fda80fc2221 "tree: simplify
conflict before resolving at hunk level." We need to simplify() the conflict
before and after extracting file ids because the source conflict values may
contain trees to be cancelled out, and the file values may differ only in exec
bits. Since the legacy tree passes a simplified conflict in to this function,
I made the merged tree do the same.
Fixes #2654
See comments inline for details. Cc #2600.
In particular, I wanted to make sure these behaviors are not affected by #2646.
They don't seem to be.
The tests ended up weirder than expected because of
https://github.com/martinvonz/jj/issues/2600#issuecomment-1835418824. Even
though, right now, the behavior of tests is unaffected by that issue, the
*expected* behavior is different.