2836 Commits

Author SHA1 Message Date
Martin von Zweigbergk
9702684a4d settings: read and parse timestamp from config only once 2022-03-10 12:38:07 -08:00
Martin von Zweigbergk
18861c67c3 settings: allow setting author/commit timestamp via config
I'm not sure it'll be useful, but it seems nice to be able to set the
same values via config or environment variables. Perhap we should
simply use `config::Environment` to make everything configurable via
environment variables, but I'll leave that for later.
2022-03-10 12:38:07 -08:00
Martin von Zweigbergk
e0115d2af7 commit_builder: move signature() to UserSettings
It's useful to have `signature()` live on `UserSettings` because that
will let us cache information (such as the timestamp) in the
instance. It will also make it easier to have the timestamp settable
via regular config files. I don't know that that will be useful, but
it seems like a clean way of implementing it if we can have
environment variables simply as an overlay of configs.
2022-03-10 12:38:07 -08:00
Martin von Zweigbergk
fc1731a180 diff: switch from BTreeMap to sorted Vec for unchanged ranges
We don't really need a BTreeMap for keeping the unchanged ranges. The
only place it helps a bit is when refining a diff because we may then
insert some more unchanged ranges in the list. I think there has to be
very many unchanged ranges for that to matter, however. This patch
therefore replace the BTreeMap by a sorted Vec. `cargo bench` says
that a few tests got ~20% faster.

I'm looking into this code now because I'm thinking of copying some of
it for the "partial conflict resolution" tool I'm working on for
Mercurial.
2022-03-10 00:33:17 -08:00
Martin von Zweigbergk
934564bf8d diff: also sort base ranges by end point
I wanted to replace the BTreeMap by a Vec and noticed that we actually
sometimes end up having a `0..n` range followed by a `0..0` after
refinement. We currently compare those two as equal because I had not
thought that we could end up attempting to add two ranges with the
same start point. When trying to insert the second range (`0..0`), the
BTreeMap will keep the existing key (`0..n`) and replace the
value. That's probably works, but it's clearly not what I
intended. Let's fix by sorting by the end point if the start point is
equal. This actually improves some benchmarks by a few percent (maybe
because the subsequent compaction can then remove the `0..0` range).
2022-03-10 00:33:17 -08:00
Martin von Zweigbergk
42252a2f00 cli: on jj init --git-repo=., use relative path to .git/
When the backing Git repo is inside the workspace (typically directly
in `.git/`), let's point to it by a relative path so the whole
workspace can be moved without breaking the link.

Closes #72.
2022-03-05 09:37:48 -08:00
Martin von Zweigbergk
0c6d89581e tests: pass timestamps via env vars for reproducible hashes
This patch introduces a `JJ_TIMESTAMP` environment variable that lets
us specify the timestamp to use in tests. It also updates the tests to
use it, which means we get to simplify the tests a lot now that that
the hashes are predictable.
2022-03-05 08:48:42 -08:00
Martin von Zweigbergk
648cfd698c cleanup: run rustfmt 2022-02-27 10:59:28 -08:00
Cole Mickens
fbe8eb47db lib/settings: try to load from platform config_dir 2022-02-26 00:09:34 -08:00
Waleed Khan
76974a9050 build: suppress unstable_name_collisions warnings on stable
Originally, I had thought that these warnings would only potentially show up in nightly because there was a feature which exposed these functions, and we would be able to enable that feature and conditionally not define the conflicting methods. But it looks like these warnings also show up in stable. I've just suppressed each of them individually. Other options would be to rename them and just make them wrapper methods, or to disable `unstable_name_collisions` warnings at a higher scope (possibly including at the crate level).
2022-02-23 23:41:55 -08:00
Waleed Khan
9202aae8b1 build: conditionally use map_first_last feature if available 2022-02-20 22:21:14 -08:00
Waleed Khan
dd3272fe90 build: use assert_matches crate
The `assert_matches` feature is nightly-only, so use this crate as a shim.
2022-02-20 22:21:14 -08:00
Waleed Khan
261cd1a1c4 build: add shims for nightly feature map_first_last 2022-02-20 22:16:07 -08:00
Martin von Zweigbergk
108b785a36 cli: don't panic on invalid config
If `~/.jjconfig` is invalid, we currently simply panic. That results
in a poor error message. We should handle the error instead.

Closes #55.
2022-02-19 23:38:23 -08:00
Martin von Zweigbergk
7c247116b9 repo: remove code for upgrading old repos to have .jj/store/git/
1b6efdc3f8ed moved `.jj/git/` into `.jj/store/` for consistency with
the layout of native stores. It provided automatic format upgrades for
repos with the old format. It's been about four months now, so let's
remove the migration code.
2022-02-17 22:44:05 -08:00
Martin von Zweigbergk
03e6b8c0e6 working_copy: take Tree, not CommitId, as argument to check_out()
We no longer need the commit ID, so we shouldn't make the callers pass
it. This lets us simplify several tests, because they no longer to
create commits just to check out a tree in the working copy.
2022-02-13 12:14:34 -08:00
Martin von Zweigbergk
315e5e87a3 working_copy: take a tree object instead of ID in TreeState::check_out()
The callers mostly have the tree object available anyway.
2022-02-13 12:12:08 -08:00
Martin von Zweigbergk
00c9a1ae11 working_copy: stop taking commit ID in LockedWorkingCopy::finish()
We used to use the value to detect races, but we use the tree ID and
the operation ID these days, so we don't need the commit ID.

By changing this, we can avoid creating some commit IDs in tests,
which is why I tackled this issue now.
2022-02-12 23:48:06 -08:00
Martin von Zweigbergk
cde3609163 working_copy: stop taking initial checkout in constructor
We don't use the value anymore.
2022-02-12 23:45:05 -08:00
Martin von Zweigbergk
993de96fc7 working_copy: stop keeping track of commit ID 2022-02-12 17:22:37 -08:00
Martin von Zweigbergk
e098c01935 working_copy: replace commit ID by tree ID for checking for changes
What matters for the working copy is the tree ID. We should be able to
remove the commit ID. This patch gets us close.
2022-02-12 17:16:19 -08:00
Martin von Zweigbergk
537b1de7d9 working_copy: move check of old commit ID on checkout to higher level
There are only two callers of `LockedWorkingCopy::check_out()`. One is
in `commands.rs`. That caller already checks after taking the lock
that the old commit ID is as expected. The other caller is
`WorkingCopy::check_out()`. We can simply move the check to that level
since it's the only caller that cares now.
2022-02-12 14:27:40 -08:00
Martin von Zweigbergk
117bf13708 cargo: upgrade backoff 2022-02-09 22:21:39 -08:00
Martin von Zweigbergk
33cc6b1253 cargo: upgrade blake2 2022-02-09 22:19:04 -08:00
Martin von Zweigbergk
b74851e005 working_copy: make sure discarded update is not visible
`LockedWorkingCopy::discard()` shouldn't result in changes to the
on-disk state, but `LockedWorkingCopy::check_out()` may have already
written a state file, which is surprising. The changes also remain in
memory, which is also surprising. Let's fix both of those issues.
2022-02-09 10:40:51 -08:00
Martin von Zweigbergk
cce12261d8 matchers: add a matcher for path prefixes (#52)
It's useful to be able to match path prefixes for many commands,
e.g. to allow `jj restore src` to restore all files in under `src/`
(or a file called `src`). I also plan to use it for sparse checkouts.

We'll need to be able to match path prefixes
2022-02-06 14:49:22 -08:00
Martin von Zweigbergk
d49892431b matchers: make visit() return cloned sets instead of references
This is just to avoid the lifetime parameter. It was a premature
optimization to return a reference (we don't even use the matchers
yet, so it cloning these sets clearly doesn't show up in profiling).
2022-02-05 20:24:53 -08:00
Martin von Zweigbergk
f294df6e8e view: inline checkout() into remaining few callers 2022-02-05 15:43:37 -08:00
Martin von Zweigbergk
e871f64d1e tests: don't create workspaces in index tests 2022-02-05 13:45:41 -08:00
Martin von Zweigbergk
abedeeaacf tests: rename init_repo() to init_workspace()
Most tests need a repo but don't need a working copy. Let's have a
function for setting up a test repo. But first, let's free up the name
`init_repo()` by renaming it to `init_workspace()` (which is also more
accurate).
2022-02-05 13:02:19 -08:00
Martin von Zweigbergk
c09a4e15c5 workspace: add a function for initializing additional workspace (#13) 2022-02-02 17:00:03 -08:00
Martin von Zweigbergk
5fd060ca18 workspace: load repo from another workspace if .jj/repo is a file (#13)
In workspaces added after the initial one, the idea is to have
`.jj/repo` be a file whose contents is a path to the location of the
repo directory in some other workspace.
2022-02-02 13:47:07 -08:00
Martin von Zweigbergk
a6ef792ba6 repo: initialize without checkouts, let Workspace add it (#13)
As part of creating a new repository, we create an open commit on top
of the root and set that as the current checkout. Now that we have
support for multiple checkouts in the model, we also have support for
zero checkouts, which means we don't need to create that commit on top
of the root when creating the repo. We can therefore move out of
`ReadonlyRepo`'s initialization code and let `Workspace` instead take
care of it. A user-visible effect of this change is that we now create
one operation for initilizing the repo and another one for checking
out the root commit. That seems fine, and will be consistent with the
additional operation we will create when adding further workspaces.
2022-02-02 11:09:12 -08:00
Martin von Zweigbergk
012b4c4d8e revsets: add syntax for a particular workspace's checkout (#13)
Because we record each workspace's checkout in the repo view, we can
-- unlike other VCSs -- let the user refer to any workspace's checkout
in revsets. This patch adds syntax for that, so you can show the
contents of the checkout in workspace "foo" with `jj show foo@`. That
won't automatically commit that workspace's working copy, however.
2022-02-02 10:05:31 -08:00
Martin von Zweigbergk
a41fcb39eb repo: respect workspace ID for old checkout (#13)
When checking out a new commit, we look at the old checkout to see if
it's empty so we should abandon it. We current use the default
workspace's checkout. We need to respect the workspace ID we're given
in `MutableRepo::check_out()`, and we need to be able to deal with
that workspace not existing yet (i.e. this being the first checkout in
that workspace).
2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
ac0d040bb5 rewrite: update all checkouts, not just the default workspace's (#13) 2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
6d3e2017f8 view: merge checkouts for all workspaces, not just the default one (#13) 2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
766c01a6d9 view: add workspace_id argument to set_checkout() (#13) 2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
fb8fbdc4b3 working_copy: keep track of workspace ID (#13)
This patch makes it so the workspace ID can be stored in
`.jj/working_copy/checkout`. The workspace ID is still always
"default".
2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
0098edd3d2 op_store: add support for tracking multiple workspaces (#13)
This patch teaches the `View` object to keep track of the checkout in
each workspace. It serializes that information into the `OpStore`. For
compatibility with existing repos, the existing field for a single
workspace's checkout is interpreted as being for the workspace called
"default".

This is just an early step towards support for multiple
workspaces. Remaining things to do:

 * Record the workspace ID somewhere in `.jj/` (maybe in
   `.jj/working_copy/`)

 * Update existing code to use the workspace ID instead of assuming
   it's always "default" as we do after this patch

 * Add a way of indicating in `.jj/` that the repo lives elsewhere and
   make it possible to load a repo from such workspaces

 * Add a command for creating additional workspaces

 * Show each workspace's checkout in log output
2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
ca055d91d9 workspace: store repo in .jj/repo/ (#13)
The `.jj/` directory contains information about two distinct parts:
the repo and the working copy. Most subdirectories are related to the
repo; only `.jj/working_copy/` is about the working copy. Let's move
the repo-related bits into a new `.jj/repo/` subdirectory. That makes
it clearer that they're related to the repo. It will probably also be
easier to manage when we have support for multiple workspaces backed
by a single repo.
2022-02-02 08:15:22 -08:00
Martin von Zweigbergk
35f0c17380 workspace: rename some symbols related to .jj/ to jj_dir (#13) 2022-01-28 21:31:51 -08:00
Martin von Zweigbergk
0725d4326d repo: don't create unused .jj/view/ directory 2022-01-28 21:27:13 -08:00
Martin von Zweigbergk
81edd92523 workspace: take over creation of .jj/working_copy/ from repo.rs (#13)
It's clearly `Workspace`'s job to create `.jj/working_copy/`, I must
have just forgotten to move it there.
2022-01-28 20:35:13 -08:00
Martin von Zweigbergk
0c8a116771 rewrite: fix auto-rebasing after "branchy" rewrites
The `DescendantRebaser` was designed to help with rebasing in two
different use cases: 1) after regular rewriting of commits where the
change ID is preserved, and 2) after importing moved branches from
other repo (e.g. backing Git repo or remote). Many of the tests are
for the second use case, such as where a branch was moved
forward. However, I just noticed that there's a pretty common scenario
from the first use case that is not supported.

Let's say you have this history:

```
D
|
C C'
|/
B B'
|/
A
```

Here we want C' to be rebased onto B' and then D to be rebased onto
C''. However, because of the support for moving branches forward, we
would not rebase commits that were already rewritten, such as C' here
(see affected tests for details), which resulted in D getting rebased
onto C', and both B and B' remaining visible.

I think I was thinking when I designed it that it would be nice if you
could just tell `DescendantRebaser` that any descendants of a commit
should be moved forward. That may be useful, but I don't think we'll
want that for the general case of a branch moving forward. Perhaps
we'll want to make it configurable which branches it should happen
for. Either way, the way it was coded by not rebasing already
rewritten commits did not work for the case above. We may be able to
handle both cases better by considering each rewrite separately
instead of all destinations at once. For now, however, I've decided to
keep it simple, so I'm fixing the case above by sacrificing some of
the potentially useful functionality for moving branches forward.

Another fix necessary for the scenario shown above was to make sure we
always rebase C' before D. Before this patch, that depended on the
order in the index. This patch fixes that by modifying the topological
order to take rewrites into account, making D depend not only on C but
also on C'. (I suppose you could instead say that C depends on both B
and C'; I don't know if that'd make a difference.)
2022-01-27 22:20:14 -08:00
Martin von Zweigbergk
5b93ae6d4b rewrite: make it possible to rebase descendants multiple times
Despite what the documentation said, we don't clear the record of
rewritten and abandoned commits at the end. This change fixes that,
and adds a test showing that it's possible to call
`MutableRepo::rebase_descendants()` multiple times.
2022-01-27 22:11:07 -08:00
Martin von Zweigbergk
10ebf35c27 repo: add a convenience function for rebasing all descendants
All non-test users of `create_descendant_rebaser()` just want to
rebase all commits, so let's make that easy.
2022-01-27 08:28:44 -08:00
Martin von Zweigbergk
9f8c6fe07d clippy: return_self_not_must_use is now disabled (pedantic) by default 2022-01-26 22:13:09 -08:00
Martin von Zweigbergk
38180555de working_copy: keep track of operation ID (#13)
When there are concurrent operations that want to update the working
copy, it's useful to know which operation was the last to successfully
update the working copy. That can help use decide how to resolve a
mismatch between the repo view's record and the working copy's
record. If we detect such a difference, we can look at the working
copy's operation ID to see if it was updated by an operation before or
after we loaded the repo.

If the working copy's record says that it was updated at operation A
and we have loaded the repo at operation B (after A), we know that the
working copy is stale, so we can automatically update it (or tell the
user to run some command to update it if we think that's more
user-friendly).

Conversely, if we have loaded the repo at operation A and the working
copy's record says that it was updated at operation B, we know that
there was some concurrent operation that updated it. We can then
decide to print a warning telling the user that we skipped updating
because of the conflict. We already have logic for not updating the
working copy if the repo is loaded at an earlier operation, but maybe
we can drop that if we record the operation in the working copy (as
this patch does).
2022-01-19 19:15:29 -08:00
Martin von Zweigbergk
419efb88f9 working_copy: update stale comment on LockedWorkingCopy
The recent refactoring introducing `WorkgingCopy::start_mutation()`
(25d19e8a65b8) made this comment incorrect.
2022-01-19 15:12:45 -08:00