-
Notifications
You must be signed in to change notification settings - Fork 337
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
FR: make fetch
automatic rebase behavior optional
#2504
Comments
There's #1039 about adding a Fun fact: |
I'd rather see #1039 completed and the command being promoted into Making it configurable seems to me a promise of stability, which I rather would avoid. |
fetch
automatic rebase behavior configurablefetch
automatic rebase behavior optional
That's interesting, but the very first thing I discovered about @PhilipMetzger when you say you'd rather see "the command being promoted into I've changed the title from "configurable" to "optional"; a configuration option is only one of the possible solutions I mentioned. |
@BatmanAoD Sorry for being unclear, quoting myself from the past: (#1039 (comment))
If we promote
This sentence implies that we'd alias
👍 I hope this explains my thoughts a bit better. |
By the way, |
It might be the option to not merge remote branches in to locals. |
@martinvonz Just discovered that myself. This means, as far as I can tell, that it is impossible to perform any kind of sync without getting this automatic-rebase behavior. I used ...and, as far as I can tell, |
Just a quick note for now:
Just to be sure, you might be able to get rid of the conflicts by simply rebasing the commits onto |
That makes sense; thanks. Though I do occasionally have multiple branches with intermingled history, and then I delete one of them; e.g. I'll do this even just to ensure that when I open an MR, the branch name is relevant. Will |
@PhilipMetzger Sorry, I'm actually still not clear: are you suggesting that any of those commands would skip the automatic-commit-deletion that I'm asking about, or not? |
No (IIUC your question), any commits that were shared between two branches are still reachable when one branch gets deleted, so they will not be considered abandoned by the remote. |
@BatmanAoD Yes, that's correct. |
This worked for all but one branch, and, eventually, I figured out that that's because that branch had commits from not one but two branches I had squash-merged into I squash-merge nearly all my MRs, so I'm concerned that this makes |
For what it's worth the branch that got screwed up still had a remote tracking branch. So I don't know if the fact that a rebase was attempted is a bug, or if this is the desired behavior and I still just don't grok what's happening or why. ...but to be honest, getting a pageful of conflicted commits because I ran |
Which of these cases do you mean that you had before branch 1 and branch 2 were merged? 1:
2:
3:
I'm still not convinced that leaving the commits that were deleted on the remote around is going to help you. Sometimes it might just look like a mess with commits that have conflicts, but if you just rebase them to the right place, the conflicts often go away. One of the reasons I'd like to get a Let's look at a simple case where your repo looks like this before fetching:
If you now
If you then
Is your project such that you are able to share the |
Using this simple example is probably also a good way to illustrate what this FR is asking for. You're asking to instead be left in this state after
Here, there is no conflict in Let me know if I misunderstood. |
I'd rather not share it directly, but I'm not even sure a redacted version would help much; the log I captured is 359 lines long. For now let's try looking at a toy repo. Here's a scenario where I expected some commits (
...but they actually weren't:
Why is that? |
In any case, yes, that last code-block you showed is indeed the state I'd prefer the repo to be left in:
|
That's working as intended. JJ supports "anonymous heads", just like mercurial does. That means we keep track of visibility separately from keeping track of branches. As you probably know, you don't need a branch to keep a commit visible. In your example, you just deleted a branch. We could have an option for deleting a branch and commits reachable from only that branch, if we think that's a common thing to want (I basically never use branches myself, so I don't want it). Or we could make it an option to
Okay, that should be easy to support, but I haven't attempted it yet. Seems like we would just need a config option and have the passes into function that imports refs from the git repo. |
Sorry, what I'm trying to get at is that I still don't actually understand the rules of the So why are |
Oh, that was my fault for misreading your example. I didn't realize before that you deleted the branch using
The rule is that if a commit used to be reachable by git from branches, tags, or HEAD and no longer is, then we consider it abandoned, and we auto-rebased descendants off of those commits.
It looks like they're both still reachable from |
In that case, I'm still not sure why a rebase would ever occur, except in the special case of the working-copy commit not being pushed back to the remote in any way. When I did the |
Or, to look at your example:
Then squash-merge
Why are |
Exactly. In the case where there are several stacked branches in git or on the remote and a branch gets deleted from a non-leaf/head commit in git, then we don't consider that as abandoning the commits (because they're still reachable). For me (who is of course used to the propagation of deleted commits and the associated auto-rebasing), that's actually annoying sometimes. It's a bit of the reverse problem that you're having. A few days ago, I had two stacked PRs and the bottom one got merged. I wish those commits had been abandoned then so I could just I'm working on the config option, btw. Looks promisingly simple so far. |
Existing remote branches aren't preserved because there may be multiple remotes having the same branch, and deletion in one remote should be propagated to the local commits. FWIW, if you've set |
This motivation for this is so we can easily skip calling the function if the user has opted out of the propagation of abandoned commits we usually do (#2504). However, it seems like a good piece of code to extract regardless of that feature.
Some users prefer to have commits not get abandoned when importing refs. This adds a config option for that. Closes #2504.
This motivation for this is so we can easily skip calling the function if the user has opted out of the propagation of abandoned commits we usually do (#2504). However, it seems like a good piece of code to extract regardless of that feature.
Some users prefer to have commits not get abandoned when importing refs. This adds a config option for that. Closes #2504.
This motivation for this is so we can easily skip calling the function if the user has opted out of the propagation of abandoned commits we usually do (#2504). However, it seems like a good piece of code to extract regardless of that feature.
## [0.12.0] - 2023-12-05 ### Breaking changes * The `remote_branches()` revset no longer includes branches exported to the Git repository (so called Git-tracking branches.) * `jj branch set` no longer creates a new branch. Use `jj branch create` instead. * `jj init --git` in an existing Git repository now errors and exits rather than creating a second Git store. ### New features * `jj workspace add` can now take _multiple_ `--revision` arguments, which will create a new workspace with its working-copy commit on top of all the parents, as if you had run `jj new r1 r2 r3 ...`. * You can now set `git.abandon-unreachable-commits = false` to disable the usual behavior where commits that became unreachable in the Git repo are abandoned ([#2504](martinvonz/jj#2504)). * `jj new` gained a `--no-edit` option to prevent editing the newly created commit. For example, `jj new a b --no-edit -m Merge` creates a merge commit without affecting the working copy. * `jj rebase` now takes the flag `--skip-empty`, which doesn't copy over commits that would become empty after a rebase. * There is a new `jj util gc` command for cleaning up the repository storage. For now, it simply runs `git gc` on the backing Git repo (when using the Git backend). ### Fixed bugs * Fixed another file conflict resolution issue where `jj status` would disagree with the actual file content. [#2654](martinvonz/jj#2654)
Is your feature request related to a problem? Please describe.
Users accustomed to
git
do not expectfetch
to make any changes to the working state or to perform any rebasing work. Even with--prune
,fetch
will leave some commits unreachable, but it will never cause anything like the automatic-abandoning behavior injj
.However,
jj fetch
automatically abandons commits if the only branch pointing to those commits is deleted in the remote. This is true even for commits that are still reachable from the working copy. Subsequent commits are rebased to account for the deletion, so the final state of the working copy is akin to applyinggit revert <deleted branch>
.Describe the solution you'd like
I think that ideally this behavior wouldn't even be part of
fetch
; it should be part of a command that implies modification to the working copy, such aspull
.Describe alternatives you've considered
This behavior should at least be avoidable. Options:
fetch
behavior, and put this behavior behind a command-line flagfetch
behavior, and put a non-destructive update behind a command-line flagAdditional context
Original discussion here: #2481 (reply in thread)
The text was updated successfully, but these errors were encountered: