New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
jj git push
: safety checks when pushing branch sideways, similar to git push --force-with-lease
#3522
base: main
Are you sure you want to change the base?
Conversation
64c74f3
to
2d13e97
Compare
81b11aa
to
f7cec4f
Compare
8b7e930
to
bb9547c
Compare
Thanks, there is no rush at all. |
// information. See https://github.com/rust-lang/git2-rs/issues/1042. | ||
assert!(push_result.is_err()); | ||
Err(GitPushError::RefInUnexpectedLocation( | ||
failed_push_negotiations, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: sort here to stabilize error representation?
lib/tests/test_git.rs
Outdated
@@ -19,6 +19,7 @@ use std::{fs, iter, thread}; | |||
|
|||
use assert_matches::assert_matches; | |||
use git2::Oid; | |||
use insta::{assert_debug_snapshot, assert_snapshot}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we usually spell insta::assert_*()
at call sites (I don't know why, though.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I wouldn't mind a PR that consistently imports the symbols.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm OK with either convention. Explicit insta::
might remind new people this is related to cargo insta
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind either, but I think most of the insta assertions in test_git.rs
can be removed.
lib/tests/test_git.rs
Outdated
), | ||
], | ||
) | ||
"### |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suppose these assertions are sanity checks, it's probably better to just assert!(...has_conflicts())
. Insta snapshots are verbose.
"### | ||
); | ||
let result = attempt_push_expecting_sideways(None); | ||
assert_snapshot!(format!("{result:?}"), @r###"Err(RefInUnexpectedLocation(["refs/heads/main"]))"###); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it can be insta::assert_debug_snapshot!()
, but I would probably use assert_matches!(.., Err(RefInUnexpectedLocation(_)))
since the failed ref names aren't important.
8cd786a
to
bb9739c
Compare
181bd7d
to
af5b193
Compare
lib/src/git.rs
Outdated
// Conveniently, this also means that the push will be | ||
// successful **if and only if** `jj git fetch` is a no-op | ||
// for this branch (and, in particular, would not create a | ||
// conflict). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. The allow_push()
function looks unnecessarily verbose, but I think it'll be cleaned up. Overall, I like it.
Adds two tests where pushing should fail, but currently succeeds.
This tests `git push` attempting to create a branch when the branch already unexpectedly exists on the remote. This should (and does) fail. Also changes another test to use `jj_cmd_failure`.
The new names are a bit clearer. Soem tests already use a `sideways_commit`, `parent_of_main_commit` will be needed in an upcoming test.
Hopefully, splitting the no-op portion will make the following commits easier to review.
As explained in the commit, our logic is a bit more complicated than that of `git push --force-with-lease`. This is to match the behavior of `jj git fetch` and branch conflict resolution rules.
This should be a no-op, though that is not necessarily obvious in corner cases. Note that libgit2 already performs the push negotiation even when pushing without force (without `+` in the refspec).
Now that we always force push, it should not occur in practice.
"Move forward" instead of "Move", "Move sideways" or "Move backward" instead of (now misleading) "Force...".
Previously,
jj git push
only made sure that the branch is in the expectedlocation on the remote server when pushing a branch forward (as opposed to
sideways or backwards). Now,
jj git push
makes a safety check in all casesand fails whenever
jj git fetch
would have introduced a conflict.In other words, previously branches that moved sideways or backward were
pushed similarly to Git's
git push --force
; now they have protectionssimilar to
git push --force-with-lease
(though not identical to it, to matchthe behavior of
jj git fetch
). Note also that because of the wayjj git fetch
works,jj
does not suffer from the same problems as Git'sgit push --force-with-lease
in situations whengit fetch
is run in the background.There are a few TODOs that may be added later (in this or separate PRs):
jj help git push
, possibly elsewhere.See TODOs in the code for more details. It's possible I forgot some, but it's probably time for others to look at the general form of this PR in any case.
Checklist
If applicable:
CHANGELOG.md