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
docs: document safety checks
#3473
base: main
Are you sure you want to change the base?
Conversation
f9bd67a
to
7525a1c
Compare
b96f57a
to
6db66d2
Compare
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 for adding this!
/// do not match, `jj` will refuse to push the branch. In this case, you need | ||
/// to `jj git fetch --remote <remote name>`. This may create some branch | ||
/// conflicts, which you'll need to resolve before trying `jj git push` | ||
/// again. |
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 remember the exact implementation, but the first statement seems inaccurate.
What we do is basically checking if local branch is diverged from the (local) remote-tracking branch, and enable force
push only when needed. There's a TODO to make force
push safer by using force-with-lease, but it's not implemented yet.
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 a bit confused and unsure what precisely you mean. I might un-confuse myself after I do some research, but if you could remind me what you are worried about, it might help. My memory of what happens exactly is hazy; here are a few possibilities of what might be the problem that came to my mind.
Let's say the local branch moved sideways and the remote branch moved somewhere else. I'm pretty sure (or at least I very much hope) jj git push
would fail in this case. However, if "force push" was enabled, though, because the local branch moved sideways, it would succeed. Do you think that's a possibility? (I might look at the code tomorrow, if I do this will be the first thing I'll think about).
I'm also realizing that what I wrote doesn't take into account the difference between jj's remote-tracking branches and the git repo's remote-tracking branch refs. I hope this difference is not very material, but I could be forgetting something important.
If what I wrote is correct, and the difference between git's and jj's remote tracking branches is immaterial, I'm not sure whether using Git's "force-with-lease" would gain us anything.
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.
Let's say the local branch moved sideways and the remote branch moved somewhere else. I'm pretty sure (or at least I very much hope)
jj git push
would fail in this case. However, if "force push" was enabled, though, because the local branch moved sideways, it would succeed. Do you think that's a possibility? (I might look at the code tomorrow, if I do this will be the first thing I'll think about).
Yes, I'm pretty sure that's a possibility. That's why we want to switch to force-with-lease.
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.
Let's say the local branch moved sideways and the remote branch moved somewhere else. I'm pretty sure (or at least I very much hope)
jj git push
would fail in this case.
jj git push
will do force push in that situation, which will probably succeed. "force-with-lease" will fix the problem, but it's not implemented yet iirc.
I'm also realizing that what I wrote doesn't take into account the difference between jj's remote-tracking branches and the git repo's remote-tracking branch refs. I hope this difference is not very material, but I could be forgetting something important.
I think jj git push
will use the jj's knowledge about the remote-tracking branches.
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 see, thanks. I'll hopefully look into it.
I guess the problem is that we need the Git library's support for the push to both be atomic and to do force-with-lease. Grr.
This might also mean that the answer I gave in https://discord.com/channels/968932220549103686/1226363798483636265 was incorrect.
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 also found libgit2/libgit2#3947 (comment) and libgit2/libgit2#4286 (comment). Not sure about gix
.
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.
This seems totally doable now 🎉 . See https://github.com/rust-lang/git2-rs/pull/926/files#diff-a9e4250104d90130c09939fc70ad76c0d3db800fc0e42a990b1d73d98009e9cb. I'll try to implement it.
dcb500e
to
77caf04
Compare
3c98d68
to
b360222
Compare
e43de26
to
d59bf11
Compare
cd1c194
to
ef7185e
Compare
440e399
to
31a83d4
Compare
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...".
As discussed in
https://discord.com/channels/968932220549103686/1226363798483636265/1226415448615288864