Commit graph

2969 commits

Author SHA1 Message Date
Martin von Zweigbergk
e02622b143 repo: when abandoning a working copy that a merge, recreate it
I recently needed to test something on top of a two branches at the
same time, so I created a new commit on top of both of them (i.e. a
merge commit). I then ran tests and made some adjustments to the
code. These adjustments belonged in one of the parent branches, so I
used `jj squash --into` to squash it in there. Unfortunately, that
meant that my working copy became a single-parent commit based on one
of the branches only. We already had #2859 for tracking this issue.

This patch changes the behavior so we create a new working-copy commit
with all of the previous parents.
2024-05-29 06:54:30 -07:00
Yuya Nishihara
b0845d1df2 dsl_util: add keyword arguments and parsing helper to FunctionCallNode
This will replace revset_parser::expect_named_arguments(). More tests will be
added by migrating revset parsing.
2024-05-29 22:36:15 +09:00
Yuya Nishihara
da2ef7fe4e dsl_util: use .ok() to drop unprintable error
I used .map_err(|_: Vec<_>|) to clarify that the original data is returned as
an error (so it can't be .unwrap()-ed.) However, it can be said that the error
detail isn't important and .map_err() is too verbose.
2024-05-29 22:36:15 +09:00
Yuya Nishihara
db16a5968b dsl_util: forward upper-bounded expect_*_arguments() to common function
I'm going to add keyword arguments handling, and I want to deduplicate check
for unsupported arguments.
2024-05-29 22:36:15 +09:00
Yuya Nishihara
b55c62beb5 dsl_util: add helper function that formats arguments count error message 2024-05-29 22:36:15 +09:00
Yuya Nishihara
89270a37fb fileset: insert missed blank line 2024-05-29 22:36:15 +09:00
mlcui
4c03506fb5 git: Avoid resetting Git index when trees are identical
This accounts for commit message-only changes which do not change the
tree ID, as well as checkouts between commits with identical tree
contents.

See #3748 for previous work on avoiding resetting HEAD when the
*commits* are identical.
2024-05-29 18:11:26 +10:00
mlcui
e4cfbc10e5 git: Refactor reset_head to share set_git_head_target call
This shares some common code to both the root and the non-root case, and
provides easier access to `mut_repo` in the function - as
`set_git_head_target` mutably borrows `mut_repo`.

This will be used for a cleaner implementation of #3767.
2024-05-29 15:44:47 +10:00
Ilya Grigoriev
e3bb825a21 jj git push: remove the NotFastForward error
Now that we always force push, it should not occur in practice.
2024-05-28 21:38:26 -07:00
Ilya Grigoriev
12081166f6 test_git.rs: delete now-useless test 2024-05-28 21:38:26 -07:00
Ilya Grigoriev
777da99533 jj git push: always force-push, all safety logic now in push_negotiation
This should be a no-op, though that is not necessarily obvious in corner
cases.

Note that libgit2 already performs the push negotiation even when
pushing without force (without `+` in the refspec).
2024-05-28 21:38:26 -07:00
Ilya Grigoriev
8d3dd17b51 jj git push: safety checks in push negotiation, "force-with-lease"
As explained in the commit, our logic is a bit more complicated than
that of `git push --force-with-lease`. This is to match the behavior of
`jj git fetch` and branch conflict resolution rules.
2024-05-28 21:38:26 -07:00
Ilya Grigoriev
b0306eb742 jj git push: no-op push negotiation, plumb data to it
Hopefully, splitting the no-op portion will make the following commits
easier to review.
2024-05-28 21:38:26 -07:00
Ilya Grigoriev
b54d962d58 test_git.rs: add two more commits to PushSetup, rename them
The new names are a bit clearer. Soem tests already use a
`sideways_commit`, `parent_of_main_commit` will be needed in
an upcoming test.
2024-05-28 21:38:26 -07:00
Martin von Zweigbergk
1e3b49abf5 revset: use FsRepoPathUiConverter in RevsetWorkspaceContext 2024-05-28 21:36:40 -07:00
Martin von Zweigbergk
058461ebb1 fileset: replace FilesetParseContext by RepoPathUiConverter 2024-05-28 21:36:40 -07:00
Martin von Zweigbergk
3b702250a6 repo_path: add type for formatting and parsing RepoPath, use in CLI
We want to move UI-independent logic that's currently in `jj-cli` into
`jj-lib`. `WorkspaceCommandHelper` is perhaps the most important part
to start moving. As I was looking into what to move from
`WorkspaceCommandHelper`, the first thing I saw there was the
`cwd`. It might seem like a good candidate to start moving. However,
when running a server, you might be running operations on repos stored
in database, so `cwd` and the workspace root don't make sense then
(because the repo is not stored at a particular path).

So, instead, this patch starts abstracting out our uses of those two
paths by adding an enum for converting between `RepoPath` and paths as
they are presented in the UI. I added a variant for repos stored in a
file system, and made `WorkspaceCommandHelper` use that to show that
it works. We'll probably add a server variant later.

I put the new type in `repo_path.rs` because at least the
file-system-based implementation is closely related to
`RepoPath::parse_fs_path()`.
2024-05-28 21:36:40 -07:00
Martin von Zweigbergk
7e6a968415 conflicts: consider the empty tree a non-legacy tree
Since we no longer depend on legacy trees being preserved when we
build new trees or merge trees, we can consider the root tree a
non-legacy tree.
2024-05-27 06:25:27 -07:00
Martin von Zweigbergk
43bf8667d8 conflicts: always write tree-level conflicts from MergedTreeBuilder
Before this patch, `MergedTreeBuilder::write_tree()` would create a
new legacy tree if the base tree was a legacy tree. This patch makes
it always write multiple root trees instead (if there are conflicts).

We still support reading legacy conflicts if the
`format.tree-level-conflicts` config is set.
2024-05-27 06:25:27 -07:00
Martin von Zweigbergk
8e6e04b929 conflicts: always use tree-level format for merged trees
It's been about six months since we started using tree-level conflicts
by default. I can't imagine we would switch back. So let's continue
the migration by always using tree-level conflicts when merging trees,
even if all inputs were legacy trees.
2024-05-27 06:25:27 -07:00
Martin von Zweigbergk
26085f236e rewrite: minor simplification of rebase_with_empty_behavior()
This is a small refactoring to return a bit less information from the
block where we merge trees.
2024-05-27 06:22:12 -07:00
mlcui
a075a5c6ca git: Only reset Git index if non-empty
In chromium/src.git, this gives an approximate ~0.83s speedup for
commands if the Git index is empty, and a ~0.14s slowdown if the Git
index is non-empty.

As most users using jj will likely be using jj to write to a colocated
repo - and therefore avoid modifying the Git index - this should be a
general speedup for most colocated checkouts.
2024-05-27 11:35:13 +10:00
Yuya Nishihara
b31f75bc94 dsl_util: introduce visitor-based generic alias substitution
The original expand_node() body is migrated as follows:
- Identifier -> fold_identifier()
- FunctionCall -> fold_function_call()

expand_defn() now manages states stack by itself, which simplifies lifetime
parameters.
2024-05-26 11:21:45 +09:00
Yuya Nishihara
0efd2aa316 dsl_util: add trait for alias body parsing
This could be a closure argument passed to expand_aliases(), but it's nice
that the parsing function is constrained by the aliases map type.
2024-05-26 11:21:45 +09:00
Yuya Nishihara
7be4a0a560 dsl_util: add visitor-like API primarily designed for alias substitution
The templater implementation of FoldableExpression is a stripped-down version
of expand_node(). It's visitor-like because I'm going to write generic alias
substitution rules over abstract expression types (template, revset, fileset.)

Naming comes from rustc.
https://rust-unofficial.github.io/patterns/patterns/creational/fold.html
2024-05-26 11:21:45 +09:00
Yuya Nishihara
5061d4b831 dsl_util: add trait for alias substitution errors
This is basically the same as the previous patch, but for error types. Some
of these functions could be encoded as "E: From<AliasExpandError<'i>>", but
alias substitution logic is recursive, so it would have to convert E back and
force.
2024-05-26 11:21:45 +09:00
Yuya Nishihara
cf6357459d dsl_util: add trait that constructs ExpressionKind of basic AST node types
This isn't fancy, but we'll need some generic way to return either original
or substituted expression node. I think this is the simplest abstraction.
2024-05-26 11:21:45 +09:00
Yuya Nishihara
68160a4e77 git_backend: forcibly invalidate in-memory packed-refs cache on gc()
gix 0.63 is now available.

#3537
2024-05-24 10:09:44 +09:00
Yuya Nishihara
97023b8da6 fileset, templater: extract basic AST node types
I'm going to extract generic alias substitution functions, and these AST types
will be accessed there. Revset parsing will also be migrated to the generic
functions.
2024-05-23 10:18:36 +09:00
Yuya Nishihara
0c05c541a1 fileset, templater: insert intermediate InvalidArguments error type
This will help extract common FunctionCallNode<'i, T> type. We don't need
freedom of arbitrary error type choices, but implementing From<_> is the
easiest option I can think of. Another option is to constrain error type by
the expression type T through "T::ParseError: ArgumentsParseError" or
something, but it seemed a bit weird that we have to use trait just for that.
2024-05-23 10:18:36 +09:00
Yuya Nishihara
f65ba88109 tree: take sub_tree_recursive() argument as &RepoPath
Since RepoPath is now a slice type, it can be constructed without cloning the
backing buffer. Let's simply use it instead of the iterator type.
2024-05-23 10:14:48 +09:00
Martin von Zweigbergk
cd5e82d0d3 tree: make sub_tree_recursive() public
These functions (in `Tree` and `MergedTree`) are safe to use. We have
a duplicate of these functions at Google, which would be nice to
avoid.
2024-05-22 11:21:18 -07:00
Martin von Zweigbergk
aecee1d6cc tree: make MergedTreeVal::to_merge() public
I don't think there's any harm in this function being public. We have
a duplicate of it at Google.
2024-05-22 11:20:43 -07:00
Martin von Zweigbergk
b227dde787 conflicts: indicate executable conflict in git-format diff 2024-05-22 06:46:58 -07:00
Martin von Zweigbergk
07bb1d81b7 tree_builder: propagate errors from write_tree() 2024-05-22 06:46:38 -07:00
Martin von Zweigbergk
1970ddef15 tree: propagate errors from sub_tree()/path_value() 2024-05-22 06:46:38 -07:00
Martin von Zweigbergk
facfb71f7b test_merged_tree: reduce duplication and wrapping with helper lambdas
I'm about to make `[Merged]Tree::path_value()` return a `Result`. This
will help even more then.
2024-05-22 06:46:38 -07:00
Yuya Nishihara
2143cc3686 fileset: consolidate signature of invalid arguments error constructors
For the same reason as the templater changes. These FunctionCallNode types will
be extracted as utility type.
2024-05-22 10:18:05 +09:00
Yuya Nishihara
7a230395c2 fileset: implement expect_no_arguments() as method 2024-05-22 10:18:05 +09:00
dploch
a49da4ad01 revset: implement a 'reachable(src, domain)' expression
This revset correctly implements "reachability" from a set of source commits following both parent and child edges as far as they can go within a domain set. This type of 'bfs' query is currently impossible to express with existing revset functions.
2024-05-21 10:52:31 -04:00
dploch
5125eab505 union_find: implement a library for the Union-Find algorithm 2024-05-21 10:52:31 -04:00
Thomas Castiglione
13c8f32ceb local_working_copy: fix some clippy lints that only show up on Windows 2024-05-21 14:37:17 +08:00
Thomas Castiglione
59d3a2c866 local_working_copy: when all sides of a conflict are executable, materialise the conflicted file as executable
Fixes #3579 and adds a testcase for an executable conflict treevalue.
2024-05-21 14:37:17 +08:00
Ilya Grigoriev
1f7c4ec60a conflicts: label closing delimeter with conflict number
This follows up on https://github.com/martinvonz/jj/pull/3459 and adds a
label to the closing delimeter of each conflict, e.g.  "Conflict 1 of 3
ends".

I didn't initially put any label at the ending delimeter since the
starting delimeter is already marked with "Conflict 1 of 3". However,
I'm now realizing that when I resolve conflicts, I usually go from top
to bottom. The first thing I do is delete the starting conflict
delimeter. It is when I get to the *end* of the conflict that I wonder
whether there are any more conflicts left in the file.
2024-05-20 18:36:51 -07:00
Yuya Nishihara
c04fb7d33a templater: migrate to generic dsl_util::AliasesMap type 2024-05-20 10:32:18 +09:00
Yuya Nishihara
2cbc4f9996 revset: extract generic dsl_util::AliasesMap<P> type
As I'm going to extract generic alias substitution helpers, there should be
a common map type.
2024-05-20 10:32:18 +09:00
Yuya Nishihara
6916fae853 revset, templater: extract trait that parses alias declaration
Revset/TempalteAliasesMap will be extracted as a generic map type over
P: AliasDeclarationParser.
2024-05-20 10:32:18 +09:00
Yuya Nishihara
467d73f1e6 revset: make .get_symbol/function() compatible with TemplateAliasesMap
These map types will be combined.
2024-05-20 10:32:18 +09:00
Yuya Nishihara
3db1f9fe5d revset: extract aliases_map.function_names()
TemplateAliasesMap has a similar function for symbols, and I'm going to extract
a common aliases map type.
2024-05-20 10:32:18 +09:00
Philip Metzger
bbb9ca10cd lib: Add RevsetExpression::is_empty(), which filters out empty commits.
This is a useful helper for programmatic revsets. Users were also migrated.
2024-05-19 00:20:05 +02:00
Yuya Nishihara
3e51e93265 fileset: box FunctionCallNode to make enum smaller
For the same reason as the previous commit.
2024-05-18 09:53:52 +09:00
Martin von Zweigbergk
66aced5dc8 merge_view: remove heads removed by other side also in Google repos
When I addded the workaround in 256988de65, I missed the comment
just below explaining that heads removed by the other side were
already handled. Since that's not handled when using non-default
indexes now, we need to handle it in an `else` block.
2024-05-16 06:09:59 -07:00
Yuya Nishihara
c17a75624e signing: remove redundant "exit status" from SSH backend error
Follows up 550f44b7c1 "gpg: drop redundant "exit status" from error message."
2024-05-14 10:24:28 +09:00
Martin von Zweigbergk
550f44b7c1 gpg: drop redundant "exit status" from error message
Apparently we currently get things like "GPG failed with exit status
exit status: 2".
2024-05-13 08:30:00 -07:00
Martin von Zweigbergk
ee9d3271c1 cleanup: propagate errors from Commit::predecessors() 2024-05-13 07:39:14 -07:00
Martin von Zweigbergk
0a758e7024 cleanup: propagate errors from Commit::parents()
The function now returns an iterator over `Result`s, matching
`Operation::parents()`.

I updated callers to also propagate the error where it was trivial.
2024-05-13 07:39:14 -07:00
Martin von Zweigbergk
256988de65 repo: add a workaround for merging repo views with Google's index
We do a 3-way merge of repo views in a few different
scenarios. Perhaps the most obvious one is when merging concurrent
operations. Another case is when undoing an operation.

One step of the 3-way repo view merge is to find which added commits
are rewrites of which removed commits (by comparing change IDs). With
the high commit rate in the Google repo (combined with storing the
commits on a server), this step can get extremely slow.

This patch adds a hack to disable the slow step when using a
non-standard `Index` implementation. The Google index is the only
non-standard implementation I'm aware of, so I don't think this will
affect anyone else. The patch is also small enough that I don't think
it will cause much maintenance overhead for the project.
2024-05-12 08:59:44 -07:00
Yuya Nishihara
de4ea5bc5a revset: move basic argument helpers to separate module
parse_function_argument_to_file/string_pattern() functions aren't moved.
They are more like functions that transform parsed tree to intermediate
representation.
2024-05-11 16:50:14 +09:00
Yuya Nishihara
f82c946ebe revset: move parsing functions to separate module
These functions will be reimplemented, and they will return a parsed tree
instead of RevsetExpression tree.
2024-05-11 16:50:14 +09:00
Yuya Nishihara
e6aa8906f7 revset: move alias types to separate module
Alias expansion is purely substitution of parsed tree, which should belong to
the first parsing stage.
2024-05-11 16:50:14 +09:00
Yuya Nishihara
68db9c142c revset: extract parser types to separate module
I'm planning to rewrite the parser in a similar way to fileset/template parsing,
and the revset_parser module will host functions and types for the first stage.
I haven't started the rewrite, but it seems good to split the revset module
even if we reject the idea.
2024-05-11 16:50:14 +09:00
Yuya Nishihara
cfc18b0432 revset: make RevsetParser type private
It's unlikely that client codes and integration tests have to use the pest
API directly.
2024-05-11 16:50:14 +09:00
Alexander Potashev
07559f24ec Refuse to split an empty commit with jj split.
Rationale: The user may be confused by the empty diff in the diff editor
tool if they accidentally run `jj split` on a wrong (empty) commit.
2024-05-10 19:37:28 +02:00
dploch
3a0929b876 index_store: add more scope to write_index()
This is more consistent with the other method and it makes some extension operations easier, by giving access to the OpStore and other relevant context for custom index extensions.
2024-05-10 09:22:09 -04:00
Martin von Zweigbergk
dbba2edc57 commit: add a helper for returning parent tree of Commit
The pattern of getting the parent tree of a commit gets repeated a
bit. Let's add a helper on `Commit`.
2024-05-07 19:35:03 -07:00
Martin von Zweigbergk
428e209304 cleanup: consistently use BackendResult
We have the type alias so we should use it consistently.
2024-05-07 19:35:03 -07:00
Martin von Zweigbergk
2e44741e02 repo: move new commit ids into RewriteType enum
`RewriteType::Rewritten` must have exactly one replacement. I think
it's better to encode that in the type by attaching the value to the
enum variant. I also renamed the type to just `Rewrite` since it now
has attached data and `Type` sounds like a traditional data-free enum
to me.
2024-05-06 12:58:40 -07:00
Martin von Zweigbergk
c6bb94de42 repo: make RewriteType private
Looks like I forgot this in some recent refactoring.

I don't really see any harm in making the type public later. I might
want to make `rebase_descendants()` not clear `parent_mapping` and
instead provide a way of accessing it afterwards (removing the need
for the `_return_map()` flavors).  We'll see if that ends up
happening. For now it can be private anyway.
2024-05-06 12:58:40 -07:00
dploch
20af8c79ef revset: support custom filter extensions 2024-05-06 10:42:01 -04:00
dploch
387ae9bce1 revset: support defining custom revset functions 2024-05-06 10:42:01 -04:00
dploch
cfa595199a revset: make a bunch of parsing types public 2024-05-06 10:42:01 -04:00
dploch
4e0abf0631 revset: make RevsetParseContext opaque 2024-05-06 10:42:01 -04:00
Ilya Grigoriev
70b517ca64 conflicts.rs: label conflict number and sides next to conflict markers
For example, 

```
<<<<<<< Conflict 1 of 3
+++++++ Contents of side #1
left 3.1
left 3.2
left 3.3
%%%%%%% Changes from base to side #2
-line 3
+right 3.1
>>>>>>>
```

or

```
<<<<<<< Conflict 1 of 1
%%%%%%% Changes from base to side #1
-line 3
+right 3.1
+++++++ Contents of side #2
left 3.1
left 3.2
left 3.3
>>>>>>>
```

Currently, there is no way to disable these, this is TODO for a future
PR. Other TODOs for future PRs: make these labels configurable. After
that, we could support a `diff3/git`-like conflict format as well, in
principle.

Counting conflicts helps with knowing whether you fixed all the
conflicts while you are in the editor.

While labeling "side #1", etc, does not tell you the commit id or
description as requested in #1176, I still think it's an improvement.
Most importantly, I hope this will make `jj`'s conflict format less
scary-looking for new users.

I've used this for a bit, and I like it. Without the labels, I would see
that the two conflicts have a different order of conflict markers, but I
wouldn't be able to remember what that means. For longer diffs, it can
be tricky for me to quickly tell that it's a diff as opposed to one of
the sides. This also creates some hope of being able to navigate a
conflict with more than 2 sides.

Another not-so-secret goal for this is explained in
https://github.com/martinvonz/jj/pull/3109#issuecomment-2014140627. The
idea is a little weird, but I *think* it could be helpful, and I'd like
to experiment with it.
2024-05-05 18:42:14 -07:00
Ilya Grigoriev
f43a810fe0 conflicts.rs: Teach jj to parse conflict markers that are followed by a label
The format is 7 characters of the separator followed by a space and arbitrary
text, followed by a newline. Separator followed by a newline is also allowed.
E.g.:

<<<<<<< Random text
%%%%%%% Random text
 line 2
-line 3
+left
 line 4
+++++++ Random text
right
%%%%%%% Random text
 line 2
+forward
 line 3
 line 4
>>>>>>> Random text

This commit only allows reading such conflicts.

I considered allowing longer separators (`<<<<<<<<<<<<<< Random text`), but we
wouldn't currently write them, so let's be strict for now.

7 characters if they are followed by a space and arbitrary text
2024-05-05 18:42:14 -07:00
Martin von Zweigbergk
3dab92d2e9 cli: move revsets.log default to config file 2024-05-05 09:08:14 -07:00
Martin von Zweigbergk
f958957f9e cli: drop support for old ui.default-revset config
We replaced it by `revsets.log` in 0.8.0, which is long enough that
users should have been able to switch.
2024-05-05 09:08:14 -07:00
Martin von Zweigbergk
0d1ff8a150 merged_tree: propagate errors from TreeEntriesIterator
We shouldn't panic if we fail to read a tree from the backend.
2024-05-01 06:10:08 -07:00
Martin von Zweigbergk
dbf2a98903 rewrite: add CommitRewriter::record_abandoned_commit()
We already have two uses for this function and I think we're soon
going to have more.

The function record the old commit as abandoned with the new parents,
which is typically what you want. We could record it as abandoned with
the old parents instead but then we'd have to do an extra iteration to
find the parents when rebasing any children. It would also be
confusing if
`rewriter.set_parents(new_parents).record_abandoned_commit()` didn't
respect the new parents.
2024-04-30 20:03:57 -07:00
dploch
586ab1f076 revset: add a SymbolResolverExtension trait to provide custom resolvers 2024-04-26 10:55:34 -04:00
dploch
bad9e9e3d7 revset: convert commit and change prefix resolvers into partial symbol resolvers 2024-04-26 10:55:34 -04:00
dploch
7bdf2b3945 revset: homogenize the logic of various symbol resolution steps into a common trait 2024-04-26 10:55:34 -04:00
dploch
cf78532bd8 revset: add two new error variants to support extensions 2024-04-26 10:55:34 -04:00
Yuya Nishihara
5b769c5c9e fileset, revset, templater: add support for single-quoted raw string literals
Since fileset/revset/template expressions are specified as command-line
arguments, it's sometimes convenient to use single quotes instead of double
quotes. Various scripting languages parse single-quoted strings in various ways,
but I choose the TOML rule because it's simple and practically useful. TOML is
our config language, so copying the TOML syntax would be less surprising than
borrowing it from another language.

https://github.com/toml-lang/toml/issues/188
2024-04-25 11:14:33 +09:00
Yuya Nishihara
a74bf89df5 revset: reuse parse_symbol_rule_as_literal() to parse string symbol
For the same reason as the previous commit. Single-quoted string literal will
be handled there.
2024-04-25 11:14:33 +09:00
Yuya Nishihara
37bd966357 fileset: extract inner function that parses string-like literal
I'm going to add single-quoted string literal.
2024-04-25 11:14:33 +09:00
Yuya Nishihara
528ccb318e fileset: fall back to bare pattern/string if no operator-like character found
While I like strict parsing, it's not uncommon that we have to deal with file
names containing spaces, and doubly-quoted strings such as '"Foo Bar"' look
ugly. So, this patch adds an exception that accepts top-level bare strings.
This parsing rule is specific to command arguments, and won't be enabled when
loading fileset aliases.
2024-04-24 12:02:07 +09:00
Martin von Zweigbergk
9d7ed54f8e git_backend: add a README to conflicted commits
When you use e.g. `git switch` to check out a conflicted commit,
you're going to end up with the `.jjconflicts-*` directories in your
working copy. It's probably not obvious what those mean. This patch
adds a README file to the root tree to try to explain to users what's
going on and how to recover.

The authoritative information about conflicts is stored in the
`jj:trees` commit header. The contents of conflicted commits is only
used for preventing GC. We can therefore add contents to the tree
without much consequence.
2024-04-22 06:22:54 -07:00
Yuya Nishihara
9f4a7318c7 tests: compare git refs loaded from disk, not in-memory cache values
This addresses the test instability. The underlying problem still exists, but
it's unlikely to trigger user-facing issues because of that. A repo instance
won't be reused after gc() call.

Fixes #3537
2024-04-22 18:46:28 +09:00
Yuya Nishihara
527713a851 tests: fix potential mtime flakiness in git gc tests
Apparently, these gc() invocations rely on that the previous "git gc" packed
all refs so there are no loose refs to compare mtimes. If there were new (or
remaining) loose refs, mtime comparison could fail. I also added +1sec to
effectively turn off the keep_newer option, which isn't important in these
tests.
2024-04-22 18:46:28 +09:00
Evan Mesterhazy
f9a3021a7a Simplify calls to CommitRewriter::replace_parents()
Now that it takes `IntoIterator` the caller doesn't need to clone
the input `CommitIds`.
2024-04-21 23:31:17 -04:00
Evan Mesterhazy
2b0aa84c9d CommitRewriter::rewrite_parents(): Take IntoIterator instead of &[CommitId]
CommitIds are often manipulated by reference, so this makes the API more
flexible for cases where the caller doesn't already have a Vec or array of
owned CommitIds.

In many cases `rewrite_parents()` does not even need to clone the input
CommitIds.  This refactor allows the clone to be avoided if it's unnecessary.

There might be other APIs that would benefit from a similar change. In general,
it seems like there are a lot of places where we're writing
`&[commit_x.id().clone, commit_y.id().clone()]` and similiar.

- [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/flexibility.html#functions-minimize-assumptions-about-parameters-by-using-generics-c-generic)
2024-04-21 23:31:17 -04:00
Evan Mesterhazy
bbd9c7c7cb Implement advance-branches for jj commit
## Feature Description

If enabled in the user or repository settings, the local branches pointing to the
parents of the revision targeted by `jj commit` will be advanced to the newly
created commit. Support for `jj new` will be added in a future change.

This behavior can be enabled by default for all branches by setting
the following in the config.toml:

```
[experimental-advance-branches]
enabled-branches = ["glob:*"]
```

Specific branches can also be disabled:
```
[experimental-advance-branches]
enabled-branches = ["glob:*"]
disabled-branches = ["main"]
```

Branches that match a disabled pattern will not be advanced, even if they also
match an enabled pattern.

This implements feature request #2338.
2024-04-20 10:26:04 -04:00
Martin von Zweigbergk
8bb92fa6fa working_copy: allow load_working_copy() to return error
It's reasonable for a `WorkingCopy` implementation to want to return
an error. `LocalWorkingCopyFactory` doesn't because it loads all data
lazily. The VFS-based one at Google wants to be able to return an
error, however.
2024-04-19 15:22:37 -07:00
Austin Seipp
ddfdf5e357 cli: allow snapshot.max-new-file-size to be a raw u64
Previously, this command would work:

    jj --config-toml='snapshot.max-new-file-size="1"' st

And is equivalent to this:

    jj --config-toml='snapshot.max-new-file-size="1B"' st

But this would not work, despite looking like it should:

    jj --config-toml='snapshot.max-new-file-size=1' st

This is extremely confusing for users.

This config value is deserialized via serde; and while the `HumanByteSize`
struct allegedly implemented Serde's `visit_u64` method, it was not called by
the deserialize visitor. Strangely, adding an `visit_i64` method *did* work, but
then requires handling of overflow, etc. This is likely because TOML integers
are naturally specified in `i64`.

Instead, just don't bother with any of that; implement a `TryFrom<String>`
instance for `HumanByteSize` that uses `u64::from_str` to try parsing the string
immediately; *then* fall back to `parse_human_byte_size` if that doesn't work.
This not only fixes the behavior but, IMO, is much simpler to reason about; we
get our `Deserialize` instance for free from the `TryFrom` instance.

Finally, this adjusts the test for `max-new-file-size` to now use a raw integer
literal, to ensure it doesn't regress. (There are already in-crate tests for
parsing the human readable strings.)

Signed-off-by: Austin Seipp <aseipp@pobox.com>
Change-Id: I8dafa2358d039ad1c07e9a512c1d10fed5845738
2024-04-19 13:03:24 -05:00
Martin von Zweigbergk
d6b41c18c9 parallelize: rewrite using transform_descendants()
`jj parallelize` was a good example of a command that can be
simplified by the new API, so I decided to rewrite it as an example.

The rewritten version is more flexible and doesn't actually need the
restrictions from the old version (such as checking that the commits
are connected). I still left the check for now to keep this patch
somewhat small. A subsequent commit will remove the restrictions.
2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
e682543570 repo: take owned commit IDs to MutableRepo::new_parents()
We always call `.to_vec()` on the slice, so let's just have the caller
pass in an owned vector instead.
2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
87c65ee0f9 rewrite: make CommitRewriter::replace_parents() remove repeats 2024-04-18 21:06:52 -07:00
Martin von Zweigbergk
96f5ca47d4 repo: add method for tranforming descendants, use in rebase_descendants()
There are several existing commands that would benefit from an API
that makes it easier to rewrite a whole graph of commits while
transforming them in some way.

`jj squash` is one example. When squashing into an ancestor, that
command currently rewrites the ancestor, then rebases descendants, and
then rewrites the rewritten source commit. It would be better to
rewrite the source commit (and any descendants) only once.

Another example is the future `jj fix`. That command will want to
rewrite a graph while updating the trees. There's currently no good
API for that; you have to manually iterate over descendants and
rewrite them.

This patch adds a new `MutableRepo::transform_descendants()` method
that takes a callback which gets a `CommitRewriter` passed to it. The
callback can then decide to change the parents, the tree, etc. The
callback is also free to leave the commit in place or to abandon it.

I updated the regular `rebase_descendants()` to use the new function
in order to exercise it. I hope we can replace all of the
`rebase_descendant_*()` flavors later.

I added a `replace_parent()` method that was a bit useful for the test
case. It could easily be hard-coded in the test case instead, but I
think the method will be useful for `jj git sync` and similar in the
future.
2024-04-18 21:06:52 -07:00
Yuya Nishihara
18f94bbb8b cli: suggest root:"<path>" if cwd-relative path is not in workspace
Closes #3216
2024-04-19 09:35:47 +09:00
Martin von Zweigbergk
d38228d0c5 rewrite: move check for unchanged parents onto CommitRewriter 2024-04-18 08:08:51 -07:00