Commit Graph

3815 Commits

Author SHA1 Message Date
Martin von Zweigbergk
b29ab46fe4 github: mention Google CLA requirement in PR template
As requested in PR #1942.
2023-08-03 22:24:07 +00:00
Martin von Zweigbergk
d1b3a0a3e3 readme: fix typo (fix adopted from #1942) 2023-08-03 22:10:01 +00:00
Yuya Nishihara
dd5cc843da revset_graph: remove unneeded Vec<IndexGraphEdge> cloning 2023-08-04 06:19:22 +09:00
Yuya Nishihara
8dc59a3d69 revset_graph: discard cache of edges that won't be accessed anymore
This appears to be a bit slower (1.170s -> 1.211s with "log -R git -r 'tags()'
-Tcommit_id --ignore-working-copy"), but seemed better than keeping growing
cache.
2023-08-04 06:19:22 +09:00
Waleed Khan
e1c194ce67 working_copy: rename WorkItem -> DirectoryToVisit 2023-08-03 19:09:59 +00:00
Glen Choo
16ef3f7edc docs: call out manual branch management
Many new users coming from Git get confused that branches don't
automatically follow commits. Call this out and give hints to the
expected workflow.
2023-08-03 11:28:00 -07:00
Waleed Khan
84f807d222 working_copy: traverse filesystem in parallel
This improves `jj status` time by a factor of ~2x on my machine (M1 Macbook Pro 2021 16-inch, uses an SSD):

```sh
$ hyperfine --parameter-list hash before,after --parameter-list repo nixpkgs,gecko-dev --setup 'git checkout {hash} && cargo build --profile release-with-debug' --warmup 3 './target/release-with-debug/jj -R ../{repo} st'
Benchmark 1: ./target/release-with-debug/jj -R ../nixpkgs st (hash = before)
  Time (mean ± σ):      1.640 s ±  0.019 s    [User: 0.580 s, System: 1.044 s]
  Range (min … max):    1.621 s …  1.673 s    10 runs

Benchmark 2: ./target/release-with-debug/jj -R ../nixpkgs st (hash = after)
  Time (mean ± σ):     760.0 ms ±   5.4 ms    [User: 812.9 ms, System: 2214.6 ms]
  Range (min … max):   751.4 ms … 768.7 ms    10 runs

Benchmark 3: ./target/release-with-debug/jj -R ../gecko-dev st (hash = before)
  Time (mean ± σ):     11.403 s ±  0.648 s    [User: 4.546 s, System: 5.932 s]
  Range (min … max):   10.553 s … 12.718 s    10 runs

Benchmark 4: ./target/release-with-debug/jj -R ../gecko-dev st (hash = after)
  Time (mean ± σ):      5.974 s ±  0.028 s    [User: 5.387 s, System: 11.959 s]
  Range (min … max):    5.937 s …  6.024 s    10 runs

$ hyperfine --parameter-list repo nixpkgs,gecko-dev --warmup 3 'git -C ../{repo} status'
Benchmark 1: git -C ../nixpkgs status
  Time (mean ± σ):     865.4 ms ±   8.4 ms    [User: 119.4 ms, System: 1401.2 ms]
  Range (min … max):   852.8 ms … 879.1 ms    10 runs

Benchmark 2: git -C ../gecko-dev status
  Time (mean ± σ):      2.892 s ±  0.029 s    [User: 0.458 s, System: 14.244 s]
  Range (min … max):    2.837 s …  2.934 s    10 runs
```

Conclusions:

- ~2x improvement from previous `jj status` time.
- Slightly faster than Git on nixpkgs.
- Still 2x slower than Git on gecko-dev, not sure why.

For reference, Git's default number of threads is defined in the `online_cpus` function: ee48e70a82/thread-utils.c (L21-L66). We are using whatever the Rayon default is.
2023-08-03 18:20:49 +00:00
Waleed Khan
326be7c91e working_copy: send updates via channel
In preparation of traversing the filesystem in parallel, send updates via `channel`.

An alternative is to modify shared mutable state, e.g. put `self.file_states` behind a mutex or use a concurrent hash-map. This risks leaving the `TreeState` in an invalid state if an error occurs, and makes invariants harder to reason about.

Using a channel introduces a small performance regression. (I didn't try out the concurrent hash-map approach.)

```sh
$ hyperfine --parameter-list hash before,after --setup 'git checkout {hash} && cargo build --profile release-with-debug' --warmup 3 './target/release-with-debug/jj -R ../nixpkgs st'
Benchmark 1: ./target/release-with-debug/jj -R ../nixpkgs st (hash = before)
  Time (mean ± σ):      1.533 s ±  0.013 s    [User: 0.587 s, System: 0.926 s]
  Range (min … max):    1.510 s …  1.559 s    10 runs

Benchmark 2: ./target/release-with-debug/jj -R ../nixpkgs st (hash = after)
  Time (mean ± σ):      1.563 s ±  0.021 s    [User: 0.607 s, System: 0.936 s]
  Range (min … max):    1.518 s …  1.595 s    10 runs

Summary
  ./target/release-with-debug/jj -R ../nixpkgs st (hash = before) ran
    1.02 ± 0.02 times faster than ./target/release-with-debug/jj -R ../nixpkgs st (hash = after)
```
2023-08-03 17:56:05 +00:00
Waleed Khan
174704d752 working_copy: extract visit_directory function for snapshotting 2023-08-03 17:40:18 +00:00
Waleed Khan
515fb02049 working_copy: extract WorkItem to top-level struct 2023-08-03 09:49:22 -07:00
Yuya Nishihara
edc34f0616 ui: use std::io::IsTerminal instead of crossterm equivalent
Let's switch to the std one as our MSRV >= 1.70.0.
2023-08-03 23:07:01 +09:00
Martin von Zweigbergk
bf2af12b3b docs: describe push.branch-prefix 2023-08-03 05:12:13 +00:00
Yuya Nishihara
0b9d23c3ad cli: add option to generate textual diff by external command
This is basic implementation. There's no config knob to enable the external
diff command by default. It reuses the merge-tools table because that's how
external diff/merge commands are currently configured. We might want to
reorganize them in #1285.

If you run "jj diff --tool meld", GUI diff will open and jj will wait for
meld to quit. This also applies to "jj log -p". The "diff --tool gui" behavior
is somewhat useful, but "log -p --tool gui" wouldn't. We might want some flag
to mark the tool output can't be streamed.

Another thing to consider is tools that can't generate directory diffs. Git
executes ext-diff tool per file, but we don't. Difftastic can compare
directories, and doing that should be more efficient since diffs can be
computed in parallel (at the expense of unsorted output.)

Closes #1886
2023-08-03 13:53:37 +09:00
Yuya Nishihara
65b06e92ed cli: error out if ui.diff.format configuration is invalid
As I'm going to add "--tool <name>" option, we'll anyway need error handling
there.
2023-08-03 13:53:37 +09:00
Yuya Nishihara
673036a3aa merge_tools: ensure that temporary directory path is valid UTF-8
Otherwise, command substitution would fail.
2023-08-03 13:53:37 +09:00
Yuya Nishihara
d17ef14956 merge_tools: extract 2-way diff checkout helper
The directory prefix is renamed to "jj-diff-" as I'm going to use it for
"jj diff --tool <external-diff-generator>".
2023-08-03 13:53:37 +09:00
Yuya Nishihara
bcbb4f215c merge_tools: remove implicit conversion of io::Error
Since ExternalToolError has non-unique io::Error variants, implicit conversion
can be source of bugs.
2023-08-03 13:53:37 +09:00
Yuya Nishihara
36cc1fbfdd merge_tools: don't use debug format to embed source error message 2023-08-03 13:53:37 +09:00
Yuya Nishihara
a16c92b59f merge_tools: remove "Error" suffix from enum variants
If I added a similar but private enum, clippy complained about that.
2023-08-03 13:53:37 +09:00
Martin von Zweigbergk
24e754b979 cli: add short form -c for jj git push --change
I use `--change` a lot and somehow still didn't think to add a short
form until @ilyagr (?) mentioned it somewhere recently.
2023-08-03 03:26:31 +00:00
Martin von Zweigbergk
b6c65c12ac readme: clarify that snapshotting doesn't result in a chain of commits
It's not clear at all right now that snapshotting the working copy
results in it being amended.
2023-08-02 21:13:46 +00:00
Martin von Zweigbergk
82be7f727c readme: format with IntelliJ
This makes it easier for me to make further changes. Hopefully it
won't make it harder for others.
2023-08-02 21:13:46 +00:00
Ilya Grigoriev
44903ed603 cli status: rearrange sections
Puts the commit summary the working copy before the info about parent
commits, to match the output after most mutating commands.

Also puts the working copy diff before the commit summary, to keep it next to
the info about the working copy commit.
2023-08-02 12:14:04 -07:00
Ilya Grigoriev
d591b6776d cli templates: include change id and more in short commit description
Include change id as well as (empty) and (conflict) markers in short commit
description.

Unlike `jj log`,

* (conflict) is put in parentheses to distinguish it from the commit
description  when the output is not colored.

* the change id is placed right before the commit id to put it into a
predicteble place, even if the short commit description takes up more than one
line. The commit id can be important for commit descriptions in commands like
`abandon`.
2023-08-02 12:14:04 -07:00
Ilya Grigoriev
e667824ad9 cli templates: change default short id length from 12 to 8
This makes including the change id into the short
commit description in the following commit look less
noisy.
2023-08-02 12:14:04 -07:00
dependabot[bot]
14d7f60603 cargo: bump the cargo-dependencies group with 1 update
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.4...v0.38.6)

---
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>
2023-08-02 09:05:01 -07:00
Martin von Zweigbergk
6ee8feea86 docs: clarify that GitHub discussions are fine (not only Discord)
Someone on HN (justifiably) seemed to think that we only accept
questions on Discord.
2023-08-02 13:49:02 +00:00
Ilya Grigoriev
8c9fc9880c cli: Add hint if user tries to use nonexistent jj restore -r 2023-08-01 15:28:00 -07:00
Ilya Grigoriev
315f698231 cli: New -changes-in argument to jj restore + docs
Also updates docstrings for `diffedit`, `abandon` in related ways. The changes
are a bit too intertwined to comfortable split into a separate commit.
2023-08-01 15:28:00 -07:00
Martin von Zweigbergk
a8de6f3695 docs: revert to using revset operator : instead of ::
Since our latest release doesn't support `::`, we shouldn't tell the
user to use it.

This commit should be backed out once we've released jj 0.9.0.
2023-08-01 21:58:43 +00:00
Martin Clausen
c696d7c62f Correct typo 2023-08-01 20:42:30 +00:00
dependabot[bot]
7751cea47c cargo: bump the cargo-dependencies group with 3 updates
Bumps the cargo-dependencies group with 3 updates: [pest](https://github.com/pest-parser/pest), [pest_derive](https://github.com/pest-parser/pest) and [serde](https://github.com/serde-rs/serde).


Updates `pest` from 2.7.1 to 2.7.2
- [Release notes](https://github.com/pest-parser/pest/releases)
- [Commits](https://github.com/pest-parser/pest/compare/v2.7.1...v2.7.2)

Updates `pest_derive` from 2.7.1 to 2.7.2
- [Release notes](https://github.com/pest-parser/pest/releases)
- [Commits](https://github.com/pest-parser/pest/compare/v2.7.1...v2.7.2)

Updates `serde` from 1.0.179 to 1.0.180
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.179...v1.0.180)

---
updated-dependencies:
- dependency-name: pest
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
- dependency-name: pest_derive
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-01 09:14:15 -07:00
Martin von Zweigbergk
48b1a1c533 working_copy: in ignored directories, visit only already tracked paths
`.gitignores` in ignored directories should be ignored. Before this
commit, we would visit ignored directories like any others if there
were any ignored paths in them.

I've done a lot of preparation for this commit, but There's still a
bit of duplication between the new code and the existing code. I don't
mind improving it if anyone has suggestions. Otherwise I might end up
doing that when I get back to working on snapshotting tree-level
conflicts soon.

This fixes #1785.
2023-08-01 06:31:52 +00:00
Martin von Zweigbergk
bcba1c6682 working_copy: rename sub_path to path
The `sub_path` is created by joining `dir` to a basename. I think
calling it just `path` is clear, especially since its the main path
involved in each iteration of the loop.
2023-08-01 06:31:52 +00:00
Martin von Zweigbergk
02f2325fae working_copy: add test for .gitignores in ignored directory
This tests the scenario that was repored in #1785.
2023-08-01 06:31:52 +00:00
Martin von Zweigbergk
aff483c431 working_copy: test changes in tracked-but-ignored directory
It's currently the same code path for handling changes to tracked
paths in ignored directories as outside ignored directories, but I'm
about to change that.

I also updated the assertion in the test to compare all entries
instead of just the tree id, so it's easier to spot errors if it
fails.
2023-08-01 06:31:52 +00:00
Martin von Zweigbergk
0dc5d967ae working_copy: move a duplicate statement out of match block 2023-08-01 06:31:52 +00:00
Martin von Zweigbergk
b48b3780c8 working_copy: replace FileStateUpdate by Option
The `FileStateUpdate` enum now looks very similar to `Option`, so
let's just use that. I also renamed `get_updated_file_state()` to
`get_updated_tree_value()` since it returns a `TreeValue`.
2023-08-01 06:31:52 +00:00
Martin von Zweigbergk
035d4bbbae working_copy: remove file state for deleted files in only one place
We currently remove the file state for deleted files after walking the
working copy and noticing that the file is not there. However, in the
case of files that have been replaced by special files like Unix
sockets, we delete the file state inside the loop. Let's simplify a
tiny bit by not doing that.
2023-08-01 06:31:52 +00:00
Martin von Zweigbergk
3f23508b5f docs: mention jj split for git commit -p use case 2023-07-31 23:26:06 +00:00
Martin von Zweigbergk
5bd3dca21b github: run only with MSRV, not stable
We run a separate build on CI with the MSRV so we notice if we
accidentally break the MSRV. However, as we talked about on Discord,
the opposite is very unlikely - that we accidentally break the build
with the stable release without breaking the MSRV build. Also, we
explicitly run Clippy with the stable release, and formatting with the
nightly release. So, let's just do the regular build and tests with
the MSRV.
2023-07-31 18:41:06 +00:00
dependabot[bot]
77108d28c7 github: bump the github-dependencies group with 1 update
Bumps the github-dependencies group with 1 update: [EmbarkStudios/cargo-deny-action](https://github.com/embarkstudios/cargo-deny-action).

- [Release notes](https://github.com/embarkstudios/cargo-deny-action/releases)
- [Commits](e0a440755b...a50c7d5f86)

---
updated-dependencies:
- dependency-name: EmbarkStudios/cargo-deny-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 15:56:35 +00:00
dependabot[bot]
3aabc42f19 cargo: bump the cargo-dependencies group with 1 update
Bumps the cargo-dependencies group with 1 update: [serde](https://github.com/serde-rs/serde).

- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.177...v1.0.179)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-31 08:48:33 -07:00
Martin von Zweigbergk
4fa2a27f38 working_copy: treat a missing file state as dirty
If we don't have a recorded state for a file, we assume that it's new,
so we add it to the tree as the type it appears on disk. That means we
won't check if it exists as a conflict in the current tree. As another
step towards making the file state just a cache, let's instead treat
this case as a dirty file, so we look up the current value from the
tree. That means that adding files will be a tiny bit slower, but I
doubt it will be noticeable (we need to read the file from disk and
write it to the backend anyway).
2023-07-31 05:59:30 +00:00
Martin von Zweigbergk
cb8ff84cc8 working_copy: don't pass FileState through get_updated_file_state()
Since the caller now has the `FileState`, there's no need to pass it
in by value only to get it back in the return value.
2023-07-31 05:59:30 +00:00
Martin von Zweigbergk
01feb40fbb working_copy: handle deleted files outside get_updated_file_state()
This is simpler, and it will enable further simplfications.
2023-07-31 05:59:30 +00:00
Martin von Zweigbergk
5cc2c91453 working_copy: pass in PathBuf and Metadata to get_updated_file_state()
This will let us call the function even if we don't have a `DirEntry`.
2023-07-31 05:59:30 +00:00
Martin von Zweigbergk
37d9aae894 working_copy: handle ignored files outside of get_updated_file_state()
I want to replace the `DirEntry` argument to
`get_updated_file_state()` by a `PathBuf` and a `Metadata`. To avoid
always reading the metadata, we need to check for ignored files
outside of `get_updated_file_state()`. I also think that gives the
call site a nice symmetry in how we use the `git_ignore` for
directories (`.matches_all_files_in()`)) and files
(`.matches_file()`).
2023-07-31 05:59:30 +00:00
Martin von Zweigbergk
be8d471e76 working_copy: preserve executable-ness from tree on Windows
This removes another little bit (literally) of dependency on the
cached file state by reading the old executable bit from the current
tree instead. That helps make it possible to discard the file states
without affecting the resulting snapshot, as we may want to do with
Watchman.
2023-07-31 05:48:32 +00:00
Martin von Zweigbergk
37a770e8b4 working_copy: make write_conflict_to_store() also handle conflicts
With this change, `write_path_to_store()` contains all the logic for
reading a file from disk and writing it to a `TreeBuilder`, making the
code for added and modified files more similar.
2023-07-31 05:48:32 +00:00