Sergey Organov wrote: > Felipe Contreras <felipe.contreras@xxxxxxxxx> writes: > > > Since this is not strictly related to the topic of `git switch` I > > renamed the thread. > > > > Sergey Organov wrote: > >> Felipe Contreras <felipe.contreras@xxxxxxxxx> writes: > >> > Sergey Organov wrote: > > > >> >> Overall, if we aim at clear documentation, we need to define our > >> >> documentation terms as precise as possible, and then use them > >> >> consistently. > >> >> > >> >> For example: > >> >> > >> >> "branch": a chain of commits > >> >> > >> >> "branch tip": the most recent commit in a branch > >> >> > >> >> "branch name": specific type of symbolic reference pointing to a > >> >> branch tip > >> > > >> > Completely agree on all three (although I would call it "branch head", > >> > not "branch tip"). > >> > >> I see why "branch head", as you later introduce "branch tail", but a > >> branch (of a plant) has no "head" (nor "tail"), right? BTW, how the base > >> of a plant branch is called in English, and how one finds "branch tail" > >> on a real tree anyway? I mean, there are probably a few of them, at > >> every fork. In Git it's even more vague, as a branch could logically > >> begin at any place, not necessarily at a fork point. > > > > We don't necessarily need a 1-to-1 mapping with common English (although > > that would be nice). Anoher option could be "base" and "tip". > > > >> OTOH, "head" and "tail" are obviously taken from CS "list" concept, and, > >> provided "chain" == "list", it does make sense. > > > > I took it from Mercurial, where the tip of a branch is called "head", > > and in fact a branch can have multiple heads. > > > >> And then we have 'HEAD' that points to the current branch tip anyway. > > > > It actually points to a branch, or rather references a branch, since it > > uses the branch name. > > Yes, but it still points to the branch tip, indirectly, or even > directly, when in "detached head" state, that, by the way, I'd vote to > abandon, replacing it with more user-friendly "unnamed branch" or > something like that. Yes, but most of the time it's indirectly. > >> Dunno, in fact I don't have any preference among "tip" and "head". > > > > I don't either, but from different sources (non-git-specific) I've heard > > "head" more often. > > > >> As for branch tail, I do have convention of marking start of a > >> long-standing branch with corresponding tag, where branch "foo" has > >> corresponding "foo-bp" tag marking its "branch point". Recently I > >> started to mark start of feature branch with yet another branch "foo-bp" > >> rather than tag, "foo" being set to track "foo-bp", that allows to > >> automate rebasing of "foo" against correct base. > > > > So foo-bp is the upstream of foo, and you do basically: > > > > git rebase foo@{upstream} > > Yep, but essential feature to me is that I in fact use tools that simply > run bare > > git rebase > > and that "just works" (tm). I typed the revision explicitly, but `git rebase` would work just fine. > > This is works if your base (or tail, or whatever) is static, but many > > branches jump around, and that's where @{tail} comes in handy. > > Yeah, I see. When I need to make a branch jump around, I do need to > manually move my references, but that's fortunately very rare use-case > for me. Having direct support for that is still a win. > > > > > You can do this: > > > > git rebase --onto foo@{upstream} foo@{tail} > > > > This will always rebase the right commits (no need to look into the > > reflog). So you can say that the branch is foo@{tail}..foo. > > I see where and when it's useful, but for a feature branch 99% of times > I don't want to rebase it onto some true upstream. I rather want to just > fiddle with the branch in place, and I prefer to setup things the way > that ensures that bare "git rebase" does "the right thing". But that's precisely the point: when you do `git rebase` you don't have to type the base or --onto anymore. It's done automatically. Not just for your long-standing branches, but for *any* branch. > Probably that could be solved by a branch-local configuration that makes > "git rebase" become "git rebase @{tail}" for the branch instead of "git > rebase @{upstream}" No. @{upstream} is where you want to rebase *to*, @{tail} is where you want to rebase *from*. When you do: git rebase foo@{upstream} This is basically the same as: git checkout foo@{upstream}^0 git cherry-pick --right-only foo@{upstream}...foo git is smart enough to figure out what commits are already part of foo@{upstream}, and those are skipped, but at no point was any "base" calculated (at least not from `git rebase`). Most of the time `git rebase` works fine, because there aren't too many commits to figure out where they should go, but it's definitely not efficient, and there's many corner-cases (see a Linux kernel maintaner baffled by what the hell `git rebase` is doing [1]). > > Another advantage of having this notion is that `git rebase` > > automatically updates the tail (in this case to foo@{upstream}). > > Yep, looks useful. Is it all local to given repo, or else? I implented it as 'refs/tails' (as opposed to 'refs/heads'), so it's local to a given repo, but could easily be exported. [1] https://lore.kernel.org/git/60b272ff6bfa4_265861208d6@natae.notmuch/ -- Felipe Contreras