Commands like "jj git fetch"/"import" can update immutable commits to reflect
the remote changes. When this happens, we should avoid rebasing their immutable
descendants.
I also updated the doc comment for transform_commits(), which already supports
disconnected ranges. Because find_descendants_for_rebase() excludes commits
within parent_mappings, the graph isn't always connected (without this patch).
The new changelog entry also covers the changes from 44146561 "git: look for
predecessors also in locally reachable commits".
When multiple bookmarked revisions exist in a stack, previously merged revisions
were not abandoned because they remained reachable. This patch fixes that by
rewriting merged revisions based on their change IDs and rebasing their
descendants onto the merged head.
The tricky part is that we shouldn't "rewrite" locally hidden revisions that
were remotely reachable (but no longer are). However, we still need to count
them as predecessors for a better evolution history.
There is a known issue where immutable descendants can accidentally be rebased
onto rewritten immutable parents. For example, suppose we have the history
A@origin <- B@origin and A@origin is rewritten remotely. If we fetch only
A'@origin, B@origin ends up being rebased onto A'@origin. Because remote
bookmarks do not move locally, this process creates a new, anonymous B revision.
One way to fix this would be to implement rebase_descendants() that leaves
immutable descendants untouched, while still allowing mutable descendants to be
rebased onto A'@origin.
Since rewriting commits is common in jj, it doesn't make much sense to print a
detailed list of rewritten commits.
This change also helps rewrite locally reachable commits in addition to the
current abandon-unreachable rule.
Writing the command makes the output unnecessarily long, and other jj
subcommands don't output as much detail when summarizing what they did.
In addition, the "No commits were rewritten" message is unnecessary
because the usual "Nothing changed" message is also printed.
--clean deletes each workspace's working_copy/ and state/ directories
after acquiring the lock, so every commit starts from a freshly
checked-out tree. Build artifacts from previous runs are not reused.
Previously, we created a new unique working copy for each invocation
named after the commit ID. This works but can be very slow to rebuild
the working copy and any ignored build artifacts between each
invocation.
Workspaces used for `jj run` are now named `1`, `2`, ..., `N`, where `N`
comes from either `--jobs N`, the config value `run.jobs`, or defaults
to 1.
Remove the single global lock that prevented multiple `jj run` instances
from executing concurrently. Multiple processes wait for each workspace
individually.
Workspaces persist between command invocations so build artifacts are
reused. The `tree_state` file in each is used to check out the next
revision while leaving ignored files in place.
The previous "fresh workspace" behavior will be restored in a future
commit that adds a `--clean` flag.
Also drops the documentation example with default config list template, as
generally it's not useful to list an example TOML block with the default values.
Fixes#9428
This allows jj to support custom options provided by the git server.
For example, chromium sometimes requires `git push -o nokeycheck`
if you intentionally uploaded a private key.
Let's assume we have two concurrent run invocations on a given stack of
commits T1 and T2, started in that order:
T1: 'sleep 10'
T2: 'sleep 1'
T2 blocks completely until T1 finishes. There are two problems with the
current approach:
1. When T1 finishes, it removes the default `run/default` directory its
WCs were put under; but the lock file is put under `run/default/lock`,
which T2 is waiting to grab -- which will subsequently fail with
`ENOENT` because the directory was removed from under it.
2. The working copy was loaded before taking the lock. Let's say T1 and
T2 both actually modify the working copy and subsequently rewrite
some commits. When T1 finishes and T2 starts, T2 will have loaded the
workspace from before T1 had committed its rewrite(s), and thus has
an old stale version of its commits; this will cause divergence for
fairly obvious reasons.
The fixes are simple: A) put the lock file under `run/default.lock`
instead to handle this, and B) take the lock before loading the
workspace.
This also deletes some redundant comments and adds a note about the lock
file requirement.
Signed-off-by: Austin Seipp <aseipp@pobox.com>
When a command passed to `jj run` modifies the working copy, these
changes are supposed to be merged into the working copy.
However, we were simply _replacing_ the old tree with the new tree,
which gave us behavior like `--restore-descendants`. Instead, we need to
do a 3-way merge so the changes accumulate.
A future enhancement will add `jj run --restore-descendants`.
Allows users to set up system-wide config files, for e.g. multi-user setups,
which has lower precedence than per-user config files, unlike $JJ_CONFIG or
--config-file.
closes jj-vcs#7321
So each command no longer requires the `--revisions` by default. This is
similar to `jj fix`'s `revsets.fix`, so maybe we should unify them at
some point.
AFAIK, hooper and arxanas have expressed interest in that.
Run each command from the same subdirectory of the working copy that `jj
run` is run from.
Adds a `--root` option to instead run from the root of the working copy
regardless of where `jj run` is executed from.
This is basically a MVP based on `fix`, caching is not implemented yet.
The core functionality is in `run_inner()` and `rewrite_commit()`.
It also exposes some initial environment variables for scripting purposes.
Stdout and stderr from the commands are buffered then output by the
parent process, matching the behavior of `jj fix`.
While it's a bit odd that the glob pattern and exact remote symbol arguments are
overloaded, the symbol syntax is undeniably convenient.
`RemoteBookmarkNamePattern` and `Display for StringPattern` have been removed as
they are no longer used.
Closes#9226Closes#9426
Warn when adding a Git remote whose configured fetch URL or effective
push URL exactly matches an existing remote. This catches accidental
duplicate remotes while leaving the add operation unchanged.
The warning compares configured URL strings without applying Git URL
rewrite rules. URL equivalence is not reliable across HTTPS, SSH, .git
suffixes, redirects, and rewrite rules, so this is intentionally only an
exact-match warning.
Do not print the matching URL in the warning because remote URLs can
contain embedded credentials. The existing remote name and URL direction
provide enough context for the user to remove the new remote if it was a
mistake.
Fixes#413.
This was recommended on Discord by @joshka at some point. It makes it
easier to test the `render()` function because it's easier to produce
a `Buffer`.
Use `gix::remote::name::validated()` to reject invalid git remote names
(empty strings, whitespace, and other names that git itself would reject)
at the jj-lib level before they propagate to git operations.
Fixes#9099
Color-words diffs use formatter labels to distinguish removed and
added tokens. When color is disabled, those labels are invisible,
so inline word changes can collapse into unreadable text when
stdout is not a TTY.
Render color-words hunks as separate before and after lines
whenever the formatter cannot emit color. This keeps the default
diff format stable while making piped or redirected output
readable.
Color-words tests that rely on inline display force color output
because inlining is only triggered when color is available, ANSI
sequences are stripped before snapshotting to keep the snapshots
readable.
This does not make redirected diffs into git-format patches.
Users still need --git for patch exchange or tools that require
unified diff input.
Fixes#5894.
Related to #6972.
Add support for invoking diff editors (`jj diffedit`, `jj split`, etc.) once per changed file, instead of once with a temporary directory pair. This enables using per-file tools like `vimdiff` for editing.
The new `merge-tools.<tool>.edit-invocation-mode` option controls this independently from `diff-invocation-mode`.
Fixes#7760.
You could just `cat .jj/repo/store/type` instead, but that feels like
too much of an implementation detail.
This can be used in scripting to perform different actions based on the
backend being used. For instance, an `aliases.upload` script may check
that the backend is "git" before running `jj git push`. If more upstream
backends are added in the future, such an alias could be updated to
handle those as well. (Google has its own commit backend, so Google
users may already find benefit in this command.)