147 Commits

Author SHA1 Message Date
Yuya Nishihara
443391bf8f view: store Option<RefTarget> in maps, add extension trait to flatten Option
Alternatively, we can wrap BTreeMap<String, Option<RefTarget>> to flatten
Option<&Option<..>> internally, but doing that would be tedious. It would
also be unclear if map.remove(name) should construct an absent RefTarget if
the ref doesn't exist.
2023-07-18 18:12:09 +09:00
Martin von Zweigbergk
e033f9139f cleanup: use let-else now that we're on Rust 1.65+ 2023-07-18 09:50:22 +01:00
Yuya Nishihara
0461a8575a refs: add stub constructors for absent RefTarget, replace None with it
Now we're mostly ready to reimplement RefTarget on top of
Conflict<Option<CommitId>>.
2023-07-17 08:24:24 +09:00
Yuya Nishihara
9c69a7cb15 refs: leverage Option<RefTarget> extension methods
is_fast_forward() has any() loop that defaults to true, so comment added.
2023-07-17 08:24:24 +09:00
Yuya Nishihara
4cfe2591b6 refs: turn RefTarget::adds()/removes() into iterator, rename accordingly
Since RefTarget will be reimplemented on top of Conflict<Option<CommitId>>,
we won't be able to simply return a slice of type &[CommitId]. These functions
are also renamed in order to disambiguate from Conflict::adds()/removes().
2023-07-17 08:24:24 +09:00
Yuya Nishihara
44eb83be46 refs: migrate other pattern matches against RefTarget enum 2023-07-17 01:13:21 +09:00
Yuya Nishihara
e55c533add refs: add constructor of Some(RefTarget::Normal(id))
If RefTarget is migrated to new Conflict type, this function will create
RefTarget(Conflict::resolved(Some(id))).

We still need some .unwrap() to insert Option<RefTarget> into map, but maps
will be changed to store new RefTarget type, and their mutation API will
guarantee that Conflict::resolved(None) is eliminated.
2023-07-17 01:13:21 +09:00
Yuya Nishihara
78eea06c36 view: unify set/remove_remote_branch() functions to take Option<RefTarget> 2023-07-15 05:57:49 +09:00
Yuya Nishihara
3be462266c view: unify set/remove_git_ref() functions to take Option<RefTarget>
New function takes name by reference since it doesn't always need an owned
String.
2023-07-15 05:57:49 +09:00
Yuya Nishihara
5218591a82 view: unify set/clear_git_head() functions to take Option<RefTarget>
If we migrate RefTarget to new Conflict-based type, it won't store
Conflict<CommitId>, but Conflict<Option<CommitId>>. As the Option will
be internalized, new RefTarget type will also represent an absent target.
The 'target: Option<RefTarget>' argument will be replaced with new RefTarget
type.

I've also renamed the function for consistency with the following changes.
It would be surprising if set_local_branch(name, target) could remove the
branch. I feel the name set_local_branch_target() is less confusing.
2023-07-15 05:57:49 +09:00
Yuya Nishihara
79955d9cb3 git: do not import/export local branch named "HEAD"
Git CLI rejects it (though the data model would probably work fine with
"HEAD" branch.) This ensures that HEAD@git in JJ world is not an exported
branch named "HEAD".
2023-07-11 16:29:27 +09:00
Yuya Nishihara
c1b87d4721 git: add logic to prevent invalid branch name from being exported
I also made remote HEAD branch banned to keep it sync with parse_git_ref().
2023-07-11 16:29:27 +09:00
Waleed Khan
54dba51a08 docs: warn about missing docs for jj-lib crate 2023-07-10 18:28:59 +03:00
Ilya Grigoriev
d81c599153 clippy: fix nightly clippy warnings *except* for needless_raw_string_hashes
This is (almost) a result of running

    cargo +nightly clippy --workspace --all-targets --fix \
      --  -A 'clippy::needless_raw_string_hashes'

with yesterday's nightly clippy.

https://github.com/mitsuhiko/insta/issues/389 causes numerous additional
`needless_raw_string_hashes` warnings, but it will hopefully be fixed soon.
For now, I recommend appending the second line to your invocations.
2023-07-09 22:28:22 -07:00
Yuya Nishihara
2606a1073d git: extract helper that merges pseudo @git targets in branches map 2023-07-09 10:39:43 +09:00
Yuya Nishihara
895ebef55c git: refactor git_ref_filter construction in fetch()
branch_name_filter() can be dynamically dispatched, but I think branching
by Some(regex)|None is simpler here.
2023-07-09 10:08:46 +09:00
Yuya Nishihara
a934547720 git: consistently ignore unrelated refs on fetch()
Since "jj git fetch --branch '*'" doesn't import unrelated remote and local
refs, "jj git fetch" shouldn't do either.
2023-07-09 10:08:46 +09:00
Yuya Nishihara
a21397bfff git: move remove/rename remote logic to library
These functions are somewhat similar to git::import/export_refs() in that
git_refs and branches are manipulated.
2023-07-09 10:08:07 +09:00
Yuya Nishihara
f3d6616057 view: add default formatting to RefName, use it to print unexported branches 2023-07-09 00:51:15 +09:00
Ilya Grigoriev
597a74d51b git fetch: limit export of deleted refs to provided globs 2023-07-03 11:01:22 -07:00
Ilya Grigoriev
371e7f46e2 git fetch: do a git export of deleted branches before fetch 2023-07-03 11:01:22 -07:00
Ilya Grigoriev
fde3c3f581 git.rs: create export_some_refs 2023-07-03 11:01:22 -07:00
Ilya Grigoriev
a50cfec008 lib/git.rs: inline functions used only once, rename others
I now believe that jj will need to store git-tracking refs for both local and
remote-tracking branches of the git repo for the long term. See
https://github.com/martinvonz/jj/issues/1666#issuecomment-1597806451

More refactoring will likely happen when that bug is fixed.
2023-07-03 11:01:22 -07:00
Ilya Grigoriev
59b354992a git export: export deletion of forgotten remote-tracking branches 2023-07-03 11:01:22 -07:00
Ilya Grigoriev
b6a9423f38 git export: (almost) no-op refactor to export_refs to use RefName
This follows 3779b45, but in this case the refactor makes the logic more
complicated. The main goal here is to prepare for the next commit.
2023-07-03 11:01:22 -07:00
Yuya Nishihara
061fbeb2f8 op_store: make RefTarget return removes/adds as slice, .clone() as needed 2023-07-02 14:39:45 +09:00
Waleed Khan
d1453a0c7c cleanup: fix clippy lint 2023-07-01 18:10:32 -07:00
Yuya Nishihara
915f76f4d9 git: use RegexSet in place of concatenating multiple glob patterns
Perhaps, this would handle patterns like ["a(b", "c)"] better. It might not
be correct to error out on "(", but should be better than building wrong
regexp pattern "a(b|c)".
2023-07-02 09:49:07 +09:00
Yuya Nishihara
a07574a233 git: pass RefName enum to git_ref_filter callback
I think it's slightly better to compare each ref fragment than building
"refs/remotes/{remote}/{branch}" pattern to be matched.
2023-07-02 09:49:07 +09:00
Yuya Nishihara
3779b45b94 git: use type-safe RefName enum extensively in import_some_refs()
I was thinking of adding GitRefName newtype, but the RefName type can serve
the same role.
2023-06-28 23:11:08 +09:00
Yuya Nishihara
1d9552406b git: leverage parse_git_ref() to test reference kind 2023-06-28 23:11:08 +09:00
Glen Choo
7afaa2487b git: add .gitmodules parser
This only parses the fields relevant to us, i.e.:

- name: the stable identifier of the submodule
- path: the path to the submodule in the current commit
- url: the remote we can clone the submodule from

The full list of .gitmodules fields can be found at
https://git-scm.com/docs/gitmodules.
2023-06-27 10:07:00 -07:00
Martin von Zweigbergk
f64e4816df git: remove unused push_commit() 2023-06-26 14:28:51 +02:00
Yuya Nishihara
d1701a5d95 git: on import_refs(), avoid loading git commit object if it's known
With my colocated "linux" repo, this appears to save ~50ms startup overhead.
Since the repo has lots of indirect tags, we can't eliminate tag object
loading at all. But still, it's faster than falling back to peel_to_commit().
2023-06-23 16:26:13 +09:00
Yuya Nishihara
8b0c01d1e9 git: return early from import_refs() if no commits to abandon
This saves another 150ms needed to set up binary heap with ~4000 wanted
and unwanted heads.
2023-06-16 09:45:41 +09:00
Yuya Nishihara
5fda093481 git: unify loop that consumes stale/excluded git refs 2023-06-16 09:45:41 +09:00
Yuya Nishihara
aa2359fdec git: rename new_git_heads to pinned_git_heads as it isn't always "new" 2023-06-16 09:45:41 +09:00
Yuya Nishihara
c8eb1a3c9c git: remove uninteresting old refs from list of heads to abandon
Since unchanged refs should be pinned by new_git_heads, we only need to
consider about "changed" old_git_targets. This allows us to return early
if hidable_git_heads.is_empty().
2023-06-16 09:45:41 +09:00
Yuya Nishihara
cf2c14296b git: on import_refs(), don't clobber view's heads with known HEAD@git
In colocated mid-size "linux" repo, this saves ~450ms needed to do
enforce_view_invariants(). We could instead make add_head() to return early,
but the condition would be a bit weird since HEAD@git is typically a parent
of known heads, not a head itself.
2023-06-16 09:45:41 +09:00
Ilya Grigoriev
a483252cf2 revset: allow checking out git-tracking (@git) branches 2023-06-12 14:31:44 -07:00
Ilya Grigoriev
8df945b71d cmd: have jj branch list report git-tracking (@git) branches
This doesn't change the way @git branches are stored in `git_refs` as opposed
to inside `BranchTarget` like normal remote-tracking branches. There are
subtle differences in behavior with e.g. `jj branch forget` and I'm not sure
how easy it is to rewrite `jj git import/export` to support a different
way of storage.

I've decided to call these "local-git tracking branches" since they track
branches in the local git repository. "local git-tracking" branches sounds a
bit more natural, but these could be confused with there are no remote
git-tracking branches. If one had the idea these might exist, they would be
confused with remote-tracking branches in the local git repo.

This addresses a portion of #1666
2023-06-12 14:31:44 -07:00
Yuya Nishihara
6ba684a395 index: replace use of walk_revs() with revset API
I've added a helper function because the construction of the range expression
is a bit noisy. It could be a Repo method, but I don't want to make it a
default implementation of the trait method.

revset::walk_revs() let the caller handle RevsetEvaluationError since the
evaluation engine may error out even with such a trivial query. For now, most
callers just .unwrap() the error as before.
2023-05-24 01:02:37 +09:00
Yuya Nishihara
1675aec388 git: handle lock error that could occur while adding GC-preventing refs
If I spawned ~20 "jj status &" processes, some of them panicked there.
Spotted when debugging #924.
2023-05-22 08:36:29 +09:00
Ilya Grigoriev
db8fcf933a export_refs: add or edit some comments (no-op)
This is supposed to make `export_refs` a little more readable.
2023-05-17 17:57:58 -07:00
Ilya Grigoriev
344b3bfa59 import_refs/export_refs: refactor conversion from branch names to refs (no-op)
This is supposed to make `import_refs` and `export_refs` a little less prone to typos
2023-05-17 17:57:58 -07:00
Ilya Grigoriev
714aff63e6 git.rs: properly abandon commits from moved/deleted branches on remote (#864)
This bug concerns the way `import_refs` that gets called by `fetch` computes
the heads that should be visible after the import.

Previously, the list of such heads was computed *before* local branches were
updated based on changes to the remote branches. So, commits that should have
been abandoned based on this update of the local branches weren't properly
abandoned.

Now, `import_refs` tracks the heads that need to be visible because of some ref
in a mapping keyed by the ref. If the ref moves or is deleted, the
corresponding heads are updated.

Fixes #864
2023-05-17 17:57:58 -07:00
Ilya Grigoriev
07e7b82a0d import_refs/export_refs: rename some local variables (no-op)
This is supposed to make `import_refs` and `export_refs` a little more
readable.
2023-05-17 17:57:58 -07:00
Yuya Nishihara
92cfffd843 git: on external HEAD move, do not abandon old branch
The current behavior was introduced by 20eb9ecec10f "git: don't abandon
HEAD commit when it loses a branch." While the change made HEAD mutation
behavior more consistent with a plain ref operation, HEAD can also move on
checkout, and checkout shouldn't be considered a history rewriting operation.

I'm not saying the new behavior is always correct, but I think it's safer
than losing old HEAD branch. I also think this change will help if we want
to extract HEAD management function from git::import_refs().

Fixes #1042.
2023-05-11 10:15:31 +09:00
Grégoire Geis
104f8e154c Fix Git/SSH on Windows
There were two issues on my end:
1. `known_hosts` doesn't seem to be recognized
2. SSH Agent is ignored despite running

A workaround for 1. is to set the HOME environment variable on Windows, so I added a hint to suggest this. Ideally we would add a `certificate_check` callback to the remote callbacks, but the git2 crate doesn't expose whether the certificate check already succeeded, which makes it useless for this purpose (as we'd be prompting users to accept a certificate even though that certificate is already known to be valid).

As for 2., I changed the behavior from "check SSH Agent if some env variables exist" to "check SSH Agent and only fail if some env variables exist". On Windows SSH Agent doesn't use these env variables (but trying to communicate with it will still work), so now Windows properly works with SSH Agent.
2023-05-04 23:57:06 +09:00
Martin von Zweigbergk
9c91f8190d tracing: bump a few trace events from DEBUG to INFO
Now that we don't print INFO-level events by default, we can start
using that level.
2023-05-03 11:40:23 -07:00