Commit graph

4385 commits

Author SHA1 Message Date
Yuya Nishihara
d16da967c9 git_backend: rename variables per git.write-change-id-header config name 2025-04-10 05:10:47 +00:00
Yuya Nishihara
c4767c3de4 git_backend: do not ignore config error at loading path 2025-04-10 05:10:47 +00:00
Benjamin Brittain
0b6d0a7a75 git_backend: derive the change ID from the git change-id header
When read/writing commits from the git-backend, populate the git commit
header with a backwards hash of the `change-id`. This should enable
preserving change identity across various git remotes assuming a
cooperative git server that doesn't strip the git header.

This feature is behind a `git.write-change-id-header` configuration flag
at least to start.
2025-04-09 16:42:56 +00:00
Emily
e5478bbf7b cargo: use gix/zlib-rs feature
This uses `zlib-rs`, a native Rust library that is comparable in
performance to `zlib-ng`. Since there’s no complicated C build
and gitoxide only has one hashing backend now, this lets us drop our
`packaging` feature without adding any awkward build requirements.

`zlib-rs` is generally faster at decompression than
`zlib-ng`, and faster at compression on levels 6 and 9; see
<https://trifectatech.org/blog/zlib-rs-is-faster-than-c/>
for details.

I couldn’t get reliable‐looking benchmark results out of my
temperamental laptop; `hyperfine` seemed to think that some random
`jj` workloads I tested might be slightly slower than with `zlib-ng`,
but it wasn’t unambiguously distinguishable from noise, so I’d
like to see measurements from others.

It’s certainly a lot faster than the previous default, and I
think it’s likely that `zlib-rs` will continue to get faster
and that it’s more than worth avoiding the headaches of a native
library with a CMake build dependency. (Though on the other hand,
if distributions move in the direction of shipping `zlib-ng` by
default, maybe there will be more motivation to make `libz-ng-sys`
support system libraries.)
2025-04-08 22:12:25 +00:00
Yuya Nishihara
51d4f49b4c files: add iterator adaptor that splits hunks into left/right merges 2025-04-08 09:12:39 +00:00
Yuya Nishihara
38ecdcf62e files: add functions that return merge result as Merge<_>/Option<_>
The version that returns Merge<_> will be used in diff functions. The added
helper functions will also be used in order to apply word-level merging.

Since we cannot express FnOnce(impl IntoIterator<..>) where the argument type is
controlled by callee, this patch adds helper trait to bridge collect_*()
functions.
2025-04-08 01:35:55 +00:00
Yuya Nishihara
624cb66210 files: rename merge() to merge_hunks()
I'll add new merge() function that returns the result as Merge<BString>.
2025-04-08 01:35:55 +00:00
Yuya Nishihara
8b32eafb9a files: extract iterator from merge_hunks()
This helps implement variants of file::merge() that return Merge<BString> or
Option<BString>. collect_hunks() could be implemented as FromIterator for
MergeResult. It would enable .collect(), but I don't think this abstraction
would generally be useful. The other types to which we want to collect the
outcome is Option<BString> and Merge<BString>. They could technically implement
FromIterator, but it would be weird if .collect() into Merge<BString> panicked
because of incompatible merge shapes.

Merge::resolved() is marked as const fn to clarify it is a trivial constructor.
2025-04-08 01:35:55 +00:00
Yuya Nishihara
7a7e62c0c4 files: document merge() function and result type, rename parameter
I'm going to add variants of this function.
2025-04-08 01:35:55 +00:00
Yuya Nishihara
10328967a1 tests: remove files::merge() wrapper, construct Merge in alternate form 2025-04-08 01:35:55 +00:00
Yuya Nishihara
8b949f7e93 tests: use indoc! {""} to format multi-line merge inputs 2025-04-08 01:35:55 +00:00
Austin Seipp
907c62018b cargo: update prost to 0.13.5
We haven't updated `prost` in a while, and the reason for that is
probably because the code generation output slightly changed, which
would have caused dependabot to exclude that package from its updates as
a failure. (At least, I suspect that's what happened.)

This lets us drop a dependency on `itertools 0.12.x` because the prost
0.13.5 release weakened its constraints, allowing `itertools 0.13.x`.
Now we only depend on two major versions of itertools (0.10 + 0.12)
instead of three (previously four).

Signed-off-by: Austin Seipp <aseipp@pobox.com>
2025-04-08 01:02:25 +00:00
Martin von Zweigbergk
40d9256a11 fix: make FileFixer::fix_files() take &mut self
It can be useful for fixers to record some information about the
inputs they processed. For example, the `FileFixer` we use in our
server at Google get more detailed error information back from its
formatter tools. We may want to record these errors in our
`FileFixer`'s state so we can then return that to the client.
2025-04-07 15:43:47 +00:00
Benjamin Tan
4b03108c19 rewrite: move_commits: use MutableRepo::transform_commits
This allows the removal of some duplicated code which performs the
topological sorting of commits to be moved.
2025-04-05 16:03:03 +00:00
Benjamin Tan
2a647e6911 repo: MutableRepo: add transform_commits function
This function is similar to `transform_descendants_with_options`, but
only rewrites the given commits and not their descendants. This will
allow `rewrite::move_commits` to transform a given set of commits
without iterating through their descendants twice (once when computing
new parents and once when rewriting commits).
2025-04-05 16:03:03 +00:00
Benjamin Tan
61ef7d9af3 repo: MutableRepo::transform_descendants_with_options: add new_parents_map
The `new_parents_map` will allow the parents of each commit to be
customized before the `transform_descendents` callback is invoked. This
is useful when the order of commits needs to be changed, whereby setting
the new parents in the default callback might lead to repeated rebasing
and cycles if the new parent has not been visited in the reverse
topological order traversal.
2025-04-05 16:03:03 +00:00
Benjamin Tan
17386f59ed repo: MutableRepo: split find_descendants_to_rebase into two functions
`MutableRepo::find_descendants_to_rebase` was finding descendants to
rebase, and ordering them. This is now split into two functions.
2025-04-05 16:03:03 +00:00
Emily
350da7d013 cargo: bump gix to 0.71.0
Fix GHSA-794x-2rpg-rfgr.

`gix::Repository::work_dir` was renamed to `workdir` (though strangely
not the `gix::ThreadSafeRepository` version), and `lossy_config`
is now off by default in all configurations.
2025-04-04 04:28:42 +00:00
Emily
71a619c19f tests: don’t use git2 in testutils 2025-04-03 19:03:44 +00:00
Emily
f14b3bf9a8 git: respect GIT_* environment variables in git2 tests
Previously, this was calling `git_repository_open()`,
which is equivalent to `git_repository_open_ext()` with
`flags = GIT_REPOSITORY_OPEN_NO_SEARCH` and `ceiling_dirs =
NULL`. This changes `ceiling_dirs` to an empty string, and adds
`GIT_REPOSITORY_OPEN_FROM_ENV` to `flags` when we’re in test code.

`GIT_REPOSITORY_OPEN_FROM_ENV` is used to respect the Git configuration
path environment variables, which is what we want for the test
hermeticity code. It works like this:

* `config_path_system` will use `$GIT_CONFIG_SYSTEM` because `use_env`
  will be set.
  
* `config_path_global` will use `$GIT_CONFIG_GLOBAL` because `use_env`
  will be set.
  
* `git_config__find_xdg` and `git_config__find_programdata` will find
  impure system paths and load them even when `$GIT_CONFIG_GLOBAL` is
  set, contrary to Git behaviour, so we need to set `$XDG_CONFIG_HOME`
  and `$PROGAMDATA`.

It has a few other effects, which I will exhaustively enumerate to
show that they are benign:

* It respects `$GIT_WORK_TREE` and `$GIT_COMMON_DIR`. These would
  already break our tests, I think, so we’re assuming they’re
  not set. (Possibly we should set them explicitly.)

* When opening a repository, it will:

  * Set the starting path for the search to `$GIT_DIR` if it’s
    `NULL`, but we do set it, so no change.

  * Initialize `ceiling_dirs` to `$GIT_CEILING_DIRECTORIES` if it’s
    `NULL`, but we do set it, so no change.

  * Respect `$GIT_DISCOVERY_ACROSS_FILESYSTEM` and set the
    `GIT_REPOSITORY_OPEN_CROSS_FS` flag appropriately. However,
    this is only checked on subsequent iterations of the loop in
    `find_repo_traverse`, and we set `GIT_REPOSITORY_OPEN_NO_SEARCH`
    which causes it to never enter a second iteration.

  * Use `ceiling_dirs` in `find_ceiling_dir_offset`, but the result is
    ignored when `GIT_REPOSITORY_OPEN_NO_SEARCH` is set, so changing
    from `NULL` to the empty string doesn’t affect behaviour. (It
    also would always return the same result for either value, anyway.)
2025-04-03 19:03:44 +00:00
Aleksey Kuznetsov
20dd35c1d5 commit: Make Commit::store_commit return &Arc<backend::Commit>
The underlying type is already under Arc
2025-04-02 14:46:20 +00:00
Martin von Zweigbergk
9763143d65 fix: always rewrite descendants of fixed commits 2025-04-02 14:04:08 +00:00
Martin von Zweigbergk
70cd3ea67f fix: show bug when descendant is already fixed
If a commit needs fixing but its descendant does not, we currently
skip rewriting the descendant, which means it will instead be rebased
when the transactions finished. That usually results in
conflicts. This adds a test case for that case.
2025-04-02 14:04:08 +00:00
Ilya Grigoriev
bb902b69b5 Revert "git_backend: stop writing tree ids to proto"
This reverts commit b8ca9ae and adds a comment.

In commit 4d42604 (a year ago), we started writing the trees involved in
conflicted commits to the Git commit object in addition to the proto
storage. We validated that the two record matched when reading commits
until as recently as f7b14be (about a week ago). Just after that, in
commit b8ca9ae, we stopped writing the tree ids to the proto storage.
That means that any version of jj between 4d42604 and f7b14be would
error fail when reading a conflicted commit created by new versions.
While we don't guarantee forward compatibility, it's easy to do so here,
so let's be friendly to older versions by rolling back b8ca9ae so we
continue to write the conflicted tree ids to both places for a while
more.

(Thanks to Martin for the detailed explanation!)

Fixes https://github.com/jj-vcs/jj/issues/6185
2025-03-31 23:19:21 +00:00
Yuya Nishihara
3f5f872204 view: rename workspace "id" to "name"
This matches the current implementation.
2025-03-31 03:39:29 +00:00
Yuya Nishihara
e66c545438 view: replace WorkspaceId by string-like newtypes
I think this makes more sense because WorkspaceId is currently a human-readable
name. In error/status messages, workspace names are now printed in revset
syntax.

New WorkspaceId types do not implement Default. It would be weird if string-like
type had non-empty Default::default(). The DEFAULT constant is provided instead.
2025-03-31 03:39:29 +00:00
Yuya Nishihara
f87db58617 view: rename RemoteRefState::Tracking to Tracked
In jj's model, a local bookmark "tracks" remote bookmarks. It's wrong to call
a remote bookmark state as "tracking".
2025-03-31 01:41:31 +00:00
Yuya Nishihara
e4982a9c33 git: report HEAD export failure as warning
It's safe to commit transaction even if HEAD couldn't be updated due to
concurrent changes.

Closes #6098
2025-03-30 01:46:00 +00:00
Yuya Nishihara
cd1ee943e6 git: split GitResetHeadError, add UpdateHeadRef variant
This helps handle "HEAD" export failure differently. At this point, the set of
error variants look distinct enough to split the error types.
2025-03-30 01:46:00 +00:00
Yuya Nishihara
c33be3839d git: remove redundant error context messages, rename variants
Wrapped errors are usually displayed after "Failed to import refs ...", etc., so
the context is obvious. I also removed "Internal"/"Error" for consistency.
2025-03-30 01:46:00 +00:00
Yuya Nishihara
d6be4a598e git: use GitRefName newtypes in push functions 2025-03-28 01:29:30 +00:00
Yuya Nishihara
fb8e45d6f9 view: introduce GitRefName newtypes
We don't reuse the RefName type here because fully-qualified Git ref name
shouldn't be considered a local ref name in jj.
2025-03-28 01:29:30 +00:00
Yuya Nishihara
bcf3d5869b revset: add optional local variables to RevsetParseContext 2025-03-27 13:23:58 +00:00
Yuya Nishihara
483e7941b4 revset: add support for local variables expansion
I think this can be used in order to substitute remote name in the default push
revset expression?

  push(remote) = remote_bookmarks(remote=remote)..@
2025-03-27 13:23:58 +00:00
Yuya Nishihara
ffad6fe96f revset: extract internal context struct from RevsetParseContext
This allows callers to mutate RevsetParseContext if needed.

RevsetParseContext was changed to an opaque struct at 4e0abf0631 "revset: make
RevsetParseContext opaque." I think the intent there was to hide implementation
details from revset extension functions. This is now achieved by opaque
LoweringContext.

Another reason of this change is that aliases_map is no longer needed when
transforming AST to UserRevsetExpression.
2025-03-26 13:03:41 +00:00
Yuya Nishihara
3656a62bf5 git: use RemoteName newtype in remote management functions 2025-03-26 13:03:37 +00:00
Yuya Nishihara
aa0327667f git: extract default_fetch_refspec(remote) helper 2025-03-26 13:03:37 +00:00
Yuya Nishihara
d44251a2a5 git: use RemoteName newtype in push functions 2025-03-26 13:03:37 +00:00
Yuya Nishihara
4ff2827d00 git: use RemoteName/RefName newtypes in fetch functions 2025-03-26 13:03:37 +00:00
Yuya Nishihara
b9f51ff992 ref_name: add RefName::to_remote_symbol(remote) for convenience 2025-03-26 13:03:37 +00:00
Yuya Nishihara
02722eae54 view: port bookmark/tag name types to RefName/RemoteName
I tried to minimize this patch, but it seemed rather complicated than porting
most callers all at once. Remote management functions in git.rs are unchanged.
They'll be ported separately.

With this change, many non-template bookmark/remote name outputs should be
rendered in revset syntax.
2025-03-26 11:07:06 +00:00
Yuya Nishihara
05e10920e6 view: wrap (remote, name) pair in RemoteRefSymbol by flatten_remote_bookmarks()
Since RemoteRefSymbol is now hosted by ref_name module, it seems good that
op_store depends on it.
2025-03-26 11:07:06 +00:00
Yuya Nishihara
db4382d395 str_util: add filter_btree_map_*() that can accept Ref/RemoteName newtypes
It's a bit weird that Deref is required, but this helps deduce the query type.
Maybe we can add typed StringPattern wrapper, but I'm not sure if that's a good
idea.

Alternatively, RefNameBuf could implement Borrow<str>, but that means the map
could be looked up by weakly-typed string keys.
2025-03-26 11:07:06 +00:00
Yuya Nishihara
d227479450 git: use "if" to reject bad branch/remote names in parse_git_ref()
This will help port branch/remote names to RefName/RemoteName types.
2025-03-26 11:07:06 +00:00
Yuya Nishihara
cc8a80c548 ref_name: move RemoteRefSymbol types from refs module 2025-03-26 11:07:06 +00:00
Yuya Nishihara
0efc9423d5 ref_name: add RefName and RemoteName newtypes
These types are akin to ObjectId types, but for refs. Perhaps, WorkspaceId can
be ported to impl_name_type!().

These types don't implement Display because it would be source of subtle bugs
if a string-like type could be formatted differently. For example, we would
have to be careful to not format!("refs/heads/{name}") if the name implemented
a default Display in revset syntax.
2025-03-26 11:07:06 +00:00
Yuya Nishihara
c9cd59ada7 content_hash: forward String::hash() to str
This is basically the same as Vec<T> and [T].
2025-03-26 11:07:06 +00:00
Baltasar Dinis
8ae80523e4 git: forward rejection reason on push
We've been finding that a lot of bug reports on `jj git push` come from
sub-standard error reporting on the reasons the failure happens.

It can come from a number of places:
 - hook failure
 - remote branch protection
 - git config

This commit forwards the reason as explained by the ouptut of git push
to help users figure out what is happening.
2025-03-26 04:46:38 +00:00
Baltasar Dinis
89bb1c4e71 git: refactor push ref error reporting
We need to report more complicated errors on push.
Firstly, we can have a mix of unexpected ref locations and remote
rejections. We should report both at the same time.

Second, git gives us a reason for why a push failed.
For this to work, it's relevant to refactor the current error reporting
path to allow us to inject this information.
2025-03-26 04:46:38 +00:00
Martin von Zweigbergk
108aae1d9b git: set --intent-to-add on new files
In colocated repos, we set up the Git index to make `git diff` closely
match `jj diff`. However, `git diff` will not include new files. We're
long talked about using the `git add --intent-to-add` feature to make
the match closer. This patch implements that. It does so both after
updating the working copy and after snapshotting. After updating the
working copy, the new file in the working-copy commit (compared to the
parent(s)) are marked as intent-to-add. After snapshotting, newly
snapshotted files are marked as intent-to-add, and deleted ones that
were previously marked as intent-to-add are removed from the index.

Closes #6122
2025-03-25 13:40:13 +00:00