The `CommitBuilder::store` field is used only in
`CommitBuilder::write_to_repo()`, but we can easily get access to the
`Store` from the `repo` argument there, so let's remove the field.
In the `jj git push --change X` code, we start a transaction and then
resolve the argument, which often results in the working copy getting
snapshotted. Since the snapshotting happens in its own transaction,
that means we have two concurrent operations for no good reason. This
patch fixes that by starting the main transaction a little
later. Since that restructuring made it easy to give more detailed
descriptions to the operations, I also did that.
The operation log entry for `jj git push` currently says "import git
refs". That seems like just a bad copy&paste. While it used to be
technically correct that the only effect on the repo was from the
import, now that we have the `jj git push --change`, that is no longer
even true.
It's convenient to push all changed branches every time with `jj git
push`, but sometimes I want to know which branches were actually
pushed. This make the command print what it's going to do.
I'll add a `--dry-run` mode and tests next.
I think I had not added tests for successful push before because I
thought there was some issue with testing it with libgit2. There *is*
an issue, which is that libgit2 requires the remote to be bare when
it's on local disk, but we can very easily make the git repo bare in
this test.
I also updated the error handling in the `git` module to not let
follow-on errors hide the real error and to not fail if two branches
moved to the same commit.
Fetching is typically much expensive than checking out, so if fetching
completes but checking out fails (due to some bug, perhaps), it seems
better to commit the fetch transaction. That way, the user can inspect
the repo and try checking out again.
We used to check only if the destination already had a `.jj/`
directory. This patch changes that to check that the destination is an
empty directory.
Closes#399.
We didn't seem to have any. I included a test for #399.
The tests also showed how the debug formatting (`{:?}`) results in
escaped (e.g.) backslashes on Windows, which is not what we want, so I
also fixed that.
By adding `ui.open-commits=false` in your config, you can now make `jj
checkout` always create a new working-copy commit on top of the
specified commit. If the config is set, open commits will also appear
in the same color as closed commits in `jj log` etc. This will let
some of us experiment with the new UX before we decide if it's a good
idea or not. I left `jj close` in place because it's useful for
setting a description and creating a new commit in one step.
I didn't mention the new config in the release notes because I hope we
can reach a decision and remove the config before the next release.
When rebasing commits after rewrites, we also update all workspaces'
checkouts. If the new commit is closed, we create a new commit on
top. Since we're hoping to remove the open/closed concept, we need a
new condition. I considered creating a new commit on top if the change
ID was different from before the rewrite. However, that would make at
least `jj split` more complicated because it makes the first commit
keep the change ID but it wants the second commit to be checked
out. This patch instead creates the new commit on top only when the
original commit was abandoned.
When a commit gets rewritten, we update any workspaces pointing to the
old commit to check out the rewritten commit. If the rewritten commit
is closed, we create a new working-copy commit on top of it. Since
we're thinking about removing the open/closed concept, we need to make
`jj close` manually create the new working-copy commit.
I think it's conceptually simpler to create a new commit and set that
commit to be the checkout in each workspace than to check out the
commit in one workspace and edit in the others.
I'm about to change how `jj checkout` works w.r.t. open/closed commits
(and in particular by moving some logic from the library crate to the
CLI), so let's make sure we have some test coverage.
If a file gets replaced by a directory right after list files in a
directory but before we stat the file, we currently crash. Let's
instead treat it as a missing file, using the mechanism introduced for
#258.
This patch makes us treat special files (e.g. Unix sockets) as absent
when snapshotting the working copy. We can consider later reporting
such files back to the caller (possibly via callback) so it can inform
the user about them.
Closes#258
This patch is essentially f6a516ff6d taken further, to also apply to
when we write a symlink or a conflict. As with regular files, these
races seem very unlikely to happen, but I found these cases while
working on #258, so let's fix. Fixing it also means that we don't need
to handle these transition cases in the next patch (when
`file_states()` can indicate that the file is e.g. a socket).
This patch adds `jj obslog -p` for including the diff compared to the
predecessor (the first predecessor if there are several). If the
predecessor's parents are different, then we create a temporary tree
by rebasing the predecessor to have the same parents and we use the
result as base for the diff. That way, we avoid polluting the diff
with the changes caused by the rebase. (I don't think we currently
have any commands that can change both parents and content, so the
diff should always be empty for rewrites caused by a rebase.)
Working on this also reminded me that it'll be really nice when we
replace `jj obslog` by something based on the operation log - I really
miss seeing information about the operation in the output (like `hg
obslog` gets from its obsmarkers).