Re: Should --update-refs exclude refs pointing to the current HEAD?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[Restoring part of Stefan's earlier message so I can respond to both
that piece, as well as add to the ideas Junio presents.]

Hi,

On Tue, Mar 5, 2024 at 8:22 AM Junio C Hamano <gitster@xxxxxxxxx> wrote:
>
> Stefan Haller <lists@xxxxxxxxxxxxxxxx> writes:
>
> >> And I now see that "git replay --contained --onto" has the same problem,
> >> which I find very unfortunate. In my opinion, "contained" should only
> >> include refs that form a stack, but not copies of the current branch.

I wouldn't want to change the default.  Even if we were to add an
option, I'm not entirely sure what it should even implement.  In
addition to Phillip's previous response in the thread, and part of
Junio's response below (which I'll add to):

1) What if there is a branch that is "just a copy" of one of the
branches earlier in the "stack"?  Since it's "just a copy", shouldn't
it be excluded for similar reasons to what you are arguing?  And, if
so, which branch is the copy?

2) Further, a "stack", to me at least, suggests a linear history
without branching (i.e. each commit has at most one parent _and_ at
most one child among the commits in the stack).  I designed `git
replay` to handle diverging histories (i.e. rebasing multiple branches
that _might_ share a subset of common history but none necessarily
need to fully contain the others, though perhaps the branches do share
some other contained branches), and I want it to handle replaying
merges as well.  While `git rebase --update-refs` is absolutely
limited to "stacks", and thus your argument might make sense in the
context of `git rebase`, since you are bringing `git replay` into the
mix, it needs to apply beyond a stack of commits.  It's not clear to
me how to genericize your suggestions to handle cases other than a
simple stack of commits, though.

3) This is mostly covered in (1) and (2), but to be explicit: `git
replay` is completely against the HEAD-is-special assumptions that are
pervasive within `git rebase`, and your problem is entirely phrased as
HEAD-is-special due to your call out of "the current branch".  Is your
argument limited to such special cases?  (If so, it might still be
valid for `git rebase`, of course.)

4) Aren't there easier ways to handle this -- for both rebase and
replay?  I'll suggest some alternatives below...

> >> Both of these cases could be fixed by --update-refs not touching any
> >> refs that point to the current HEAD. I'm having a hard time coming up
> >> with cases where you would ever want those to be updated, in fact.
>
> The point of "update-refs", as I understand it, is that in addition
> to the end point of the history (E in "git rebase --onto N O E"),
> any branch tips that are between O..E can be migrated to point at
> their rewritten counterparts.  So I am not sure how it fundamentally
> solves much by protecting only refs that point at a single commit
> ("the current HEAD" in your statement).
>
> When I want to see how the rebased history would look like without
> touching the original, I often rebase a detached HEAD (i.e. instead
> of the earlier one, use "git rebase --onto N O E^0", or when
> rebasing the current branch, "git rebase [--onto N] O HEAD^0") and
> that would protect the current branch well, but --update-refs of
> course would not work well.  There is no handy place like detached
> HEAD that can be used to save rewritten version of these extra
> branch tips.
>
> If branch tips A, B, and C are involved in the range of commits
> being rewritten, one way to help us in such a situation may be to
> teach "git rebase" to (1) somehow create a new set of proposed-A,
> proposed-B, and proposed-C refs (they do not have to be branches),
> while keeping the original A, B, and C intact, (2) allow us to
> inspect the resulting refs, compare the corresponding ones from
> these two sets, and (3) allow us to promote (possibly a subset of)
> proposed- ones to their counterpart real branches after we inspect
> them.  The latter two do not have to be subcommands of "git rebase"
> but can be separate and new commands.

Here, Junio is suggesting one alternative, and it's already
implemented in `git replay`.  Let me extend upon it and add two other
alternatives as well:

4a) `git replay` does what Junio suggests naturally, since it doesn't
update the refs but instead gives commands which can be fed to `git
update-ref --stdin`.  Thus, users can inspect the output of `git
replay` and only perform the updates they want (by feeding a subset of
the lines to update-ref --stdin).

4b) For `git replay`, --contained is just syntactic sugar -- it isn't
necessary.  git replay will allow you to list multiple branches that
you want replayed, so you can specify which branches are relevant to
you.  (This doesn't help with `git rebase`, because `--update-refs` is
the only way to get additional branches replayed.)

4c) For `git rebase --update-refs`, you can add `--interactive` and
then delete the `update-ref` line(s) corresponding to the refs you
don't want updated.





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux