156 Commits

Author SHA1 Message Date
Benjamin Saunders
b55c4ae0a3 git: move progress callback into a struct 2022-11-06 17:31:29 -08:00
Martin von Zweigbergk
416a36a59c git: don't abandon root commit when all refs are gone
If you remove all refs from the backing Git repo and then run `jj git
import`, we would see that all commits disappeared from the Git repo,
so we would remove them from the jj repo too. However, we do that by
doing a history walk from old heads to the new heads, which includes
the root commit when the new heads is an empty set. That means that we
mark the root commit as abandoned, which led to a crash in
`rewrite.rs` (when we try pick the root commit's first parent to use
as parent for rebased commits).
2022-10-29 03:02:26 -07:00
Martin von Zweigbergk
20eb9ecec1 git: don't abandon HEAD commit when it loses a branch
I was trying to create a reproduction script for #412, but the script
ran into another bug first. The script removed all the local and
remote branches from the backing Git repo. I noticed that we would
then try to abandon all commits. We should still count Git HEAD's
target as visible and not try to abandon it. This patch fixes that.
2022-10-29 03:02:26 -07:00
Benjamin Saunders
c03c746f8d cli: report fetch progress continuously 2022-10-23 12:13:25 -07:00
Martin von Zweigbergk
5e539771c5 git: include a hint about possible permission error when push fails
When the remote rejects a push, we now say something like this:

```
Remote rejected the update of some refs (do you have permission to push to ["refs/heads/main"]?)
```

That message could be formatted better, but this seems good enough for
now. We should probably have some more custom conversion from
`GitPushError` to `CommandError` in the CLI layer.
2022-09-27 02:23:05 -07:00
Martin von Zweigbergk
3aaeca9e1c tests: add test for successful push
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.
2022-07-04 22:50:40 -07:00
Martin von Zweigbergk
dc32bb1f95 git: avoid creating a HashSet only to convert to a Vec 2022-04-28 22:46:50 -07:00
Martin von Zweigbergk
57ba9a9409 git: when importing refs, abandon commits that were abandoned in git
Now that I'm using GitHub PRs instead of pushing directly to the main
branch, it's quite annoying to have to abandon the old commits after
GitHub rebases them. This patch makes it so we compare the remote's
previous heads to the new heads and abandons any commits that were
removed on the remote. As usual, that means that descendants get
rebased onto the closest remaining commit.

This is half of #241. The other half is to detect rewritten branches
and rebase on top.
2022-04-28 11:28:09 -07:00
Tal Pressman
4a1576c874 Check SSH_AUTH_SOCK to determine existence of ssh-agent 2022-04-26 08:10:28 -07:00
Martin von Zweigbergk
023e3b7b90 git: fix an obsolete comment about a .jj/ path
The path to the file that indicates the last export to git was changed
when we added support for multiple workspaces.
2022-04-25 15:53:44 -07:00
Martin von Zweigbergk
ccfaf0f601 git: on import, only add ref target as head if target changed (#44)
If you import Git refs, then rebase a commit pointed to by some Git
ref, and then re-import Git refs, you don't want the old commit to be
made a visible head again. That's particularly annoying when Git refs
are automatically updated by every command.
2021-12-11 11:03:40 -08:00
Martin von Zweigbergk
63d1a87ef3 cli: automatically update Git refs and HEAD after command if collocated (#44) 2021-12-11 11:03:40 -08:00
Martin von Zweigbergk
47b3abd0f7 git: add function for exporting to underlying Git repo (#44) 2021-12-11 09:30:12 -08:00
Martin von Zweigbergk
c678a89794 cleanup: fix some issues reported by new clippy and/or rustc 2021-12-10 14:12:45 -08:00
Martin von Zweigbergk
8a2f630ac0 git: start tracking HEAD of underlying Git repo
This patch adds a place for tracking the current `HEAD` commit in the
underlying Git repo. It updates `git::import_refs()` to record it. We
don't use it anywhere yet.

This is part of #44.
2021-12-01 11:08:53 -08:00
Martin von Zweigbergk
a27e77205a git: don't import refs/remotes/origin/HEAD as a branch called "HEAD"
`refs/remotes/origin/*` are usually (remote-tracking) branches, but
`refs/remotes/origin/HEAD` is not.
2021-12-01 08:15:36 -08:00
Martin von Zweigbergk
8cf5dd286a backend: make Vec inside CommitId non-public
The recent e5dd93cbf712, whose description says "cleanup: make Vec
inside CommitId etc. non-public", made all ID types in the `backend`
module *except* for `CommitId` non-public :P This patch makes
2021-11-19 23:19:00 -08:00
Martin von Zweigbergk
27107637f2 git: fix regression in pruning of remote refs
A while ago, I replaced a call to git2-rs's `Remote::fetch()` by calls
to `Remote::download()` and `Remote::update_tips()`. The function is
documented to be a convenience for those function, but it turns out
that the pruning of deleted remote refs is a separate call
(`Remote::prune()`), so we need to call that too.
2021-11-07 16:02:18 -08:00
Martin von Zweigbergk
bdea3ae31a git: don't pass remote credentials callback to Remote::update_tips()
AFAICT, the credentials callback is not used by
`Remote::update_tips()`.
2021-11-07 15:57:19 -08:00
Martin von Zweigbergk
2e4dc019d9 git: don't update public heads for now 2021-10-20 14:23:58 -07:00
Martin von Zweigbergk
28a2c534a0 git: add support for password-less SSH keys
My SSH keys are password-protected, so I haven't been able to test
this patch completely, but I believe it should work. We now use
ssh-agent if `$SSH_AGENT_PID` is set, otherwise we check if
`$HOME/.ssh/id_rsa` exists and assume it's a password-less key. That's
quite hacky but I think it's good enough for now. We eventually need
to move this out of the library crate just like libgit2 has done.

Closes #25.
2021-10-09 09:44:57 -07:00
Martin von Zweigbergk
fc883d1d02 git: extract a function for creating RemoteCallbacks 2021-10-09 09:12:03 -07:00
Martin von Zweigbergk
d434b948f1 git: use git's HTTP proxy configs
I don't have an HTTP proxy to test with, but I hope this is all that's
needed.

Closes #34.
2021-10-09 09:01:47 -07:00
Martin von Zweigbergk
edf7ec0a72 git: don't fetch tags we're not fetching commits for
In the recent switch away from `git2::Remote::fetch()`, I passed
`git2::AutotagOption::All`, which caused cloning of e.g. the `clap`
repo to fail like this:

```
Error: Fetch failed: Error { code: -1, klass: 4, message: "target OID for the reference doesn't exist on the repository" }
```

This commit changes from `All` to `Unspecified`, which respects the
remote's configuration.
2021-09-24 07:46:54 -07:00
Martin von Zweigbergk
eed715dc51 git: try to fix flaky (?) fetch tests by keeping connection open longer
It seems it wasn't Windows that behaved differently when it comes
getting the remote's default branch; the test failed on Ubuntu
too.

The documentation for `Remote::default_branch()` says that it can be
called even after the connection has been closed, but let's see if
calling it while the connection is open helps anyway. To do that, we
have to replicate what `Remote::fetch()` does.
2021-09-22 11:48:42 -07:00
Martin von Zweigbergk
48f237e33e cli: correctly update to remote's default branch after clone
It turns out that `FETCH_HEAD` is not the remote's `HEAD` (it's
actually not even a normal symbolic ref; it contains many lines of
commits and names). We're supposed to ask the remote for its default
branch instead. That's what this patch does.
2021-09-13 22:28:13 -07:00
Martin von Zweigbergk
ce5e95fa80 store: rename Store to Backend and StoreWrapper to Store
For what's currently called `Store` in the code, I have been using
"backend" in plain text. That probably means that `Backend` is a good
name for it.
2021-09-12 12:02:10 -07:00
Martin von Zweigbergk
344435e90f git: add support for pushing multiple ref updates at once 2021-09-11 22:54:29 -07:00
Martin von Zweigbergk
4594932fc0 git: remove trailing single quotes from error messages 2021-08-11 08:21:42 -07:00
Martin von Zweigbergk
81ba65e3a5 git: force push when not known to be a fast-forward
With this change, we no longer fail if the user moves a branch
sideways or backwards and then push.

The push should ideally only succeed if the remote branch is where we
thought it was (like `git push --force-with-lease`), but that requires
rust-lang/git2-rs#733 to be fixed first.
2021-08-04 23:28:42 -07:00
Martin von Zweigbergk
d555e0c326 git: when fetching, prune refs that have been deleted on the remote
Otherwise remote-tracking branches just pile up.

It seems that both git and libgit2 remove the remote-tracking branch
when you push a deletion, so `jj branch --delete foo; jj git push
--branch foo` already sees `foo` disappear locally as well. However,
if a branch has been deleted on the remote, we would never know before
this change.
2021-08-04 23:00:43 -07:00
Martin von Zweigbergk
8b8aff171e cli: delete branch from git remote when pushing locally deleted branch 2021-08-04 22:50:52 -07:00
Martin von Zweigbergk
e57948347e git: extract a function that can be reused for pushing branch-deletion 2021-08-04 22:14:43 -07:00
Martin von Zweigbergk
8738421990 git: update own branch and tag records based on git refs
Now that we have our own representation of branches and tags, let's
update them when we import git refs. The View object's git refs are
now just a record of what the refs are in the underlying git ref last
time we imported them (we don't -- and won't -- provide a way for the
user to update our record of the git refs). We can therefore do a nice
3-way ref-merge using the `refs` module we added recently. That means
that we'll detect conflicts caused by changes made concurrently in the
underlying git repo and in jj's view.
2021-08-04 11:39:07 -07:00
Martin von Zweigbergk
9fb3521bf5 view: rename insert_git_ref() to set_git_ref()
I just feel like `set_git_ref()` is a more natural name (I was looking
for it the other day before I realized I had called it
`insert_git_ref()`).
2021-08-04 08:45:37 -07:00
Martin von Zweigbergk
0aa738a518 view: add support for conflicting git refs in the model
This adds support for having conflicting git refs in the view, but we
never create conflicts yet. The `git_refs()` revset includes all "add"
sides of any conflicts. Similarly `origin/main` (for example) resolves
to all "adds" if it's conflicted (meaning that `jj co origin/main` and
many other commands will error out if `origin/main` is
conflicted). The `git_refs` template renders the reference for all
"adds" and adds a "?" as suffix for conflicted refs.

The reason I'm adding this now is not because it's high priority on
its own (it's likely extremely uncommon to run two concurrent `jj git
refresh` and *also* update refs in the underlying git repo at the same
time) but because it's a building block for the branch support I've
planned (issue #21).
2021-07-24 19:01:56 -07:00
Martin von Zweigbergk
b593e552b8 cleanup: remove some Vec<_> annotations, mostly by using collect_vec() 2021-06-09 14:21:57 -07:00
Martin von Zweigbergk
d42e6c77b2 project: rename project from Jujube to Jujutsu
"Jujutsu" is probably much more familiar and relatable to most
people. Also, I'm still not sure how "jujube" is supposed to be
pronounced :P
2021-05-15 10:28:40 -07:00
Martin von Zweigbergk
5ed14185a0 git: take a MutableRepo instead of a Transaction 2021-03-16 22:05:51 -07:00
Martin von Zweigbergk
1e9d428406 git: skip tags pointing to GPG keys and similar when importing refs 2021-03-14 20:14:18 -07:00
Martin von Zweigbergk
429a1ad7ab git: set authentication callback on fetch as well
I guess I had not run `jj git fetch` from GitHub until I tried to
fetch the result of PR #6 just now.
2021-03-14 17:18:51 -07:00
Martin von Zweigbergk
4b8484e561 rustfmt: configure to group imports 2021-03-14 10:46:25 -07:00
Martin von Zweigbergk
3066381d57 transaction: add accessors for view and evolution directly on transaction 2021-02-13 13:43:48 -08:00
Martin von Zweigbergk
f1666375bd repo: replace Repo trait by enum with readonly and mutable variants
I want to keep the index updated within the transaction. I tried doing
that by adding a `trait Index`, implemented by `ReadonlyIndex` and
`MutableIndex`. However, `ReadonlyRepo::index` is of type
`Mutex<Option<Arc<IndexFile>>>` (because it is lazily initialized),
and we cannot get a `&dyn Index` that lives long enough to be returned
from a `Repo::index()` from that. It seems the best solution is to
instead create an `Index` enum (instead of a trait), with one readonly
and one mutable variant. This commit starts the migration to that
design by replacing the `Repo` trait by an enum. I never intended for
there there to be more implementations of `Repo` than `ReadonlyRepo`
and `MutableRepo` anyway.
2021-02-13 08:31:23 -08:00
Martin von Zweigbergk
79eecb6119 git: mark imported remote-tracking branches as public 2021-01-16 12:14:42 -08:00
Martin von Zweigbergk
19b542b318 git: simplify error handling by passing git repo into git module functions 2021-01-11 00:25:39 -08:00
Martin von Zweigbergk
da0bbbe637 view: start tracking git refs
Git refs are important at least for understanding where the remote
branches are. This commit adds support for tracking them in the view
and makes `git::import_refs()` update them.

When merging views (either because of concurrent operations or when
undoing an earlier operation), there can be conflicts between git ref
changes. I ignored that for now and let the later operation win. That
will probably be good enough for a while. It's not hard to detect the
conflicts, but I haven't yet decided how to handle them. I'm leaning
towards representing the conflicting refs in the view just like how we
represent conflicting files in the tree.
2021-01-10 20:13:22 -08:00
Martin von Zweigbergk
d7b9bd55e8 git: remove unnecessary taking of reference (reported by clippy) 2021-01-02 19:38:18 -08:00
Martin von Zweigbergk
e2d6252766 git: on push, check that remote branch was actually updated
I had missed in `git2-rs`'s documentation that you need to check
in a callback if the remote ref(s) got updated by the push or
not. This adds such a check and a new error variant for rejected
branch updates.
2021-01-02 19:27:42 -08:00
Martin von Zweigbergk
7542c484a8 git: pass ssh credentials from ssh-agent on push
I tried to push a commit from my Jujube repo to GitHub using `jj
git push --branch main` and it became clear that we need to pass
SSH credentials. This commit hopefully fixes that. I've only made
it pass credentials for ssh-agent for now, because that seems to
be enough to make it work for me personally. If this commit
becomes visible on GitHub, it should mean that it worked.
2021-01-02 19:27:39 -08:00