{"thread":{"id":"47332","subject":"bug deleting \"unmerged\" branch (2.12.3)","startedAt":"2017-11-28T14:31:47Z","lastAt":"2017-12-12T16:57:47Z","messageCount":14,"participants":["Ulrich Windl","Johannes Schindelin","Junio C Hamano","Philip Oakley"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"333690","messageId":"5A1D70FD020000A100029137@gwsmtp1.uni-regensburg.de","threadId":"47332","inReplyTo":null,"subject":"bug deleting \"unmerged\" branch (2.12.3)","fromName":"Ulrich Windl","fromEmail":"ulrich.windl@rz.uni-regensburg.de","sentAt":"2017-11-28T14:21:49Z","receivedAt":"2017-11-28T14:31:47Z","isPatch":false,"sender":{"key":"ulrich.windl@rz.uni-regensburg.de","avatar":null},"body":"Hi!\n\nDuring a rebase that turned out to be heavier than expected 8-( I decided to keep the old branch by creating a temporary branch name to the commit of the branch to rebase (which was still the old commit ID at that time).\nWhen done rebasing, I attached a new name to the new (rebased) branch, deleted the old name (pointing at the same rebase commit), then recreated the old branch from the temporary branch name (created to remember the commit id).\nWhen I wanted to delete the temporary branch (which is of no use now), I got a message that the branch is unmerged.\nI think if more than one branches are pointing to the same commit, one should be allowed to delete all but the last one without warning. Do you agree?\n\nRegards,\nUlrich\n\n\n"},{"id":"333695","messageId":"alpine.DEB.2.21.1.1711281542400.6482@virtualbox","threadId":"47332","inReplyTo":"5A1D70FD020000A100029137@gwsmtp1.uni-regensburg.de","subject":"Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-11-28T15:32:21Z","receivedAt":"2017-11-28T15:32:30Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ulrich,\n\nOn Tue, 28 Nov 2017, Ulrich Windl wrote:\n\n> During a rebase that turned out to be heavier than expected 8-( I\n> decided to keep the old branch by creating a temporary branch name to\n> the commit of the branch to rebase (which was still the old commit ID at\n> that time).\n>\n> When done rebasing, I attached a new name to the new (rebased) branch,\n> deleted the old name (pointing at the same rebase commit), then\n> recreated the old branch from the temporary branch name (created to\n> remember the commit id).\n>\n> When I wanted to delete the temporary branch (which is of no use now), I\n> got a message that the branch is unmerged.\n\nThis is actually as designed, at least for performance reasons (it is not\nexactly cheap to figure out whether a given commit is contained in any\nother branch).\n\n> I think if more than one branches are pointing to the same commit, one\n> should be allowed to delete all but the last one without warning. Do you\n> agree?\n\nNo, respectfully disagree, because I have found myself with branches\npointing to the same commit, even if the branches served different\npurposes. I really like the current behavior where you can delete a\nbranch with `git branch -d` as long as it is contained in its upstream\nbranch.\n\nCiao,\nJohannes\n"},{"id":"333715","messageId":"xmqqtvxd6gu9.fsf@gitster.mtv.corp.google.com","threadId":"47332","inReplyTo":"5A1D70FD020000A100029137@gwsmtp1.uni-regensburg.de","subject":"Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-11-29T00:58:38Z","receivedAt":"2017-11-29T00:58:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de> writes:\n\n> I think if more than one branches are pointing to the same commit,\n> one should be allowed to delete all but the last one without\n> warning. Do you agree?\n\nThat comes from a viewpoint that the only purpose \"branch -d\" exists\nin addition to \"branch -D\" is to protect objects from \"gc\".  Those\nwho added the safety feature may have shared that view originally,\nbut it turns out that it protects another important thing you are\nforgetting.\n\nImagine that two topics, 'topicA' and 'topicB', were independently\nforked from 'master', and then later we wanted to add a feature that\ndepends on these two topics.  Since the 'feature' forked, there may\nhave been other developments, and we ended up in this topology:\n\n    ---o---o---o---o---o---M\n        \\   \\          \n         \\   o---A---o---F\n          \\         /  \n           o---o---o---o---B\n\nwhere A, B and F are the tips of 'topicA', 'topicB' and 'feature'\nbranches right now [*1*].\n\nNow imagine we are on 'master' and just made 'topicB' graduate.  We\nwould have this topology.\n\n    ---o---o---o---o---o---o---M\n        \\   \\                 /\n         \\   o---A---o---F   /\n          \\         /       /\n           o---o---o---o---B\n\nWhile we do have 'topicA' and 'feature' branches still in flight,\nwe are done with 'topicB'.  Even though the tip of 'topicA' is\nreachable from the tip of 'feature', the fact that the branch points\nat 'A' is still relevant.  If we lose that information right now,\nwe'd have to go find it when we (1) want to further enhance the\ntopic by checking out and building on 'topicA', and (2) want to\nfinally get 'topicA' graduate to 'master'.\n\nBecause removal of a topic (in this case 'topicB') is often done\nafter a merge of that topic is made into an integration branch,\n\"branch -d\" that protects branches that are yet to be merged to the\ncurrent branch catches you if you said \"branch -d topic{A,B}\" (or\nother equivalent forms, most likely you'd have a script that spits\nout list of branches and feed it to \"xargs branch -d\").\n\nSo, no, I do not agree.\n\n\n[Footnotes]\n\n*1* Since the 'feature' started developing, there were a few commits\n    added to 'topicB' but because the feature does not depend on\n    these enhancements to that topic, B is ahead of the commit that\n    was originally merged with the tip of 'topicA' to form the\n    'feature' branch.\n"},{"id":"333774","messageId":"5A1E6B27020000A10002916B@gwsmtp1.uni-regensburg.de","threadId":"47332","inReplyTo":"alpine.DEB.2.21.1.1711281542400.6482@virtualbox","subject":"Antw: Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Ulrich Windl","fromEmail":"ulrich.windl@rz.uni-regensburg.de","sentAt":"2017-11-29T08:09:11Z","receivedAt":"2017-11-29T08:09:17Z","isPatch":false,"sender":{"key":"ulrich.windl@rz.uni-regensburg.de","avatar":null},"body":"\n\n\n\n> Hi Ulrich,\n> \n> On Tue, 28 Nov 2017, Ulrich Windl wrote:\n> \n>> During a rebase that turned out to be heavier than expected 8-( I\n>> decided to keep the old branch by creating a temporary branch name to\n>> the commit of the branch to rebase (which was still the old commit ID at\n>> that time).\n>>\n>> When done rebasing, I attached a new name to the new (rebased) branch,\n>> deleted the old name (pointing at the same rebase commit), then\n>> recreated the old branch from the temporary branch name (created to\n>> remember the commit id).\n>>\n>> When I wanted to delete the temporary branch (which is of no use now), I\n>> got a message that the branch is unmerged.\n> \n> This is actually as designed, at least for performance reasons (it is not\n> exactly cheap to figure out whether a given commit is contained in any\n> other branch).\n> \n>> I think if more than one branches are pointing to the same commit, one\n>> should be allowed to delete all but the last one without warning. Do you\n>> agree?\n> \n> No, respectfully disagree, because I have found myself with branches\n> pointing to the same commit, even if the branches served different\n> purposes. I really like the current behavior where you can delete a\n> branch with `git branch -d` as long as it is contained in its upstream\n> branch.\n\nHi!\n\nI'm not talking about the intention of a branch, but of the state of a branch: If multiple branches point (not \"contain\") the same commit, they are equivalent (besides the name) at that moment. As no program can predict the future or the intentions of the user, it should be safe to delete the branch, because it can easily be recreated (from the remaining branches pointing to the same commit).\n\nIt shouldn't need a lot of computational power to find out when multiple branches point to the same commit.\n\nRegards,\nUlrich\n\n\n"},{"id":"333775","messageId":"5A1E70AA020000A100029175@gwsmtp1.uni-regensburg.de","threadId":"47332","inReplyTo":"xmqqtvxd6gu9.fsf@gitster.mtv.corp.google.com","subject":"Antw: Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Ulrich Windl","fromEmail":"ulrich.windl@rz.uni-regensburg.de","sentAt":"2017-11-29T08:32:42Z","receivedAt":"2017-11-29T08:32:50Z","isPatch":false,"sender":{"key":"ulrich.windl@rz.uni-regensburg.de","avatar":null},"body":"\n> \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de> writes:\n> \n>> I think if more than one branches are pointing to the same commit,\n>> one should be allowed to delete all but the last one without\n>> warning. Do you agree?\n> \n> That comes from a viewpoint that the only purpose \"branch -d\" exists\n> in addition to \"branch -D\" is to protect objects from \"gc\".  Those\n> who added the safety feature may have shared that view originally,\n> but it turns out that it protects another important thing you are\n> forgetting.\n> \n> Imagine that two topics, 'topicA' and 'topicB', were independently\n> forked from 'master', and then later we wanted to add a feature that\n> depends on these two topics.  Since the 'feature' forked, there may\n> have been other developments, and we ended up in this topology:\n> \n>     ---o---o---o---o---o---M\n>         \\   \\          \n>          \\   o---A---o---F\n>           \\         /  \n>            o---o---o---o---B\n> \n> where A, B and F are the tips of 'topicA', 'topicB' and 'feature'\n> branches right now [*1*].\n> \n> Now imagine we are on 'master' and just made 'topicB' graduate.  We\n> would have this topology.\n> \n>     ---o---o---o---o---o---o---M\n>         \\   \\                 /\n>          \\   o---A---o---F   /\n>           \\         /       /\n>            o---o---o---o---B\n> \n> While we do have 'topicA' and 'feature' branches still in flight,\n> we are done with 'topicB'.  Even though the tip of 'topicA' is\n> reachable from the tip of 'feature', the fact that the branch points\n> at 'A' is still relevant.  If we lose that information right now,\n> we'd have to go find it when we (1) want to further enhance the\n> topic by checking out and building on 'topicA', and (2) want to\n> finally get 'topicA' graduate to 'master'.\n> \n> Because removal of a topic (in this case 'topicB') is often done\n> after a merge of that topic is made into an integration branch,\n> \"branch -d\" that protects branches that are yet to be merged to the\n> current branch catches you if you said \"branch -d topic{A,B}\" (or\n> other equivalent forms, most likely you'd have a script that spits\n> out list of branches and feed it to \"xargs branch -d\").\n> \n> So, no, I do not agree.\n\nHi!\n\nI can follow your argumentation, but I fail to see that your branches A and B point to the same commit (which is what I was talking about). So my situation would be:\n\no---oA,B\n\nI still think I could safely remove either A or B, even when the branch (identified by the commit, not by the name) is unmerged. What did I miss?\n\nRegards,\nUlrich\n\n> \n> \n> [Footnotes]\n> \n> *1* Since the 'feature' started developing, there were a few commits\n>     added to 'topicB' but because the feature does not depend on\n>     these enhancements to that topic, B is ahead of the commit that\n>     was originally merged with the tip of 'topicA' to form the\n>     'feature' branch.\n\n"},{"id":"333777","messageId":"alpine.DEB.2.21.1.1711291302370.6482@virtualbox","threadId":"47332","inReplyTo":"5A1E6B27020000A10002916B@gwsmtp1.uni-regensburg.de","subject":"Re: Antw: Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-11-29T12:27:59Z","receivedAt":"2017-11-29T12:28:08Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Ulrich,\n\nOn Wed, 29 Nov 2017, Ulrich Windl wrote:\n\n> > On Tue, 28 Nov 2017, Ulrich Windl wrote:\n> > \n> >> During a rebase that turned out to be heavier than expected 8-( I\n> >> decided to keep the old branch by creating a temporary branch name to\n> >> the commit of the branch to rebase (which was still the old commit ID\n> >> at that time).\n> >>\n> >> When done rebasing, I attached a new name to the new (rebased)\n> >> branch, deleted the old name (pointing at the same rebase commit),\n> >> then recreated the old branch from the temporary branch name (created\n> >> to remember the commit id).\n> >>\n> >> When I wanted to delete the temporary branch (which is of no use\n> >> now), I got a message that the branch is unmerged.\n> > \n> > This is actually as designed, at least for performance reasons (it is\n> > not exactly cheap to figure out whether a given commit is contained in\n> > any other branch).\n> > \n> >> I think if more than one branches are pointing to the same commit,\n> >> one should be allowed to delete all but the last one without warning.\n> >> Do you agree?\n> > \n> > No, respectfully disagree, because I have found myself with branches\n> > pointing to the same commit, even if the branches served different\n> > purposes. I really like the current behavior where you can delete a\n> > branch with `git branch -d` as long as it is contained in its upstream\n> > branch.\n> \n> I'm not talking about the intention of a branch, but of the state of a\n> branch: If multiple branches point (not \"contain\") the same commit, they\n> are equivalent (besides the name) at that moment.\n\nI did a poor job of explaining myself, please let me try again. I'll give\nyou one concrete example:\n\nRecently, while working on some topic, I stumbled over a bug and committed\na bug fix, then committed that and branched off a new branch to remind\nmyself to rebase the bug fix and contribute it.\n\nAt that point, those branches were at the same revision, but distinctly\nnot equivalent (except in just one, very narrow sense of the word, which I\nwould argue is the wrong interpretation in this context).\n\nSadly, I was called away at that moment to take care of something\ncompletely different. Even if I had not been, the worktree with the first\nbranch would still have been at that revision for a longer time, as I had\nto try out a couple of changes before I could commit.\n\nThis is just one example where the idea backfires that you can safely\ndelete one of two branches that happen to point at the same commit at the\nsame time.\n\nI am sure that you possess vivid enough of an imagination to come up with\nplenty more examples where that is the case.\n\n> As no program can predict the future or the intentions of the user, it\n> should be safe to delete the branch, because it can easily be recreated\n> (from the remaining branches pointing to the same commit).\n\nYes, no program can predict the future (at least *accurately*).\n\nNo, it is not safe to delete that branch. Especially if you take the\ncurrent paradigm of \"it is safe to delete a branch if it is up-to-date\nwith, or at least fast-forwardable to, its upstream branch\" into account.\n\nAnd no, a branch cannot easily be recreated from the remaining branches in\nthe future, as branches can have different reflogs (and they are lost when\ndeleting the branch).\n\n> It shouldn't need a lot of computational power to find out when multiple\n> branches point to the same commit.\n\nSure, that test can even be scripted easily by using the `git for-each-ref\n--points-at=<revision>` command.\n\nBy the way, if you are still convinced that my argument is flawed and that\nit should be considered safe to delete a branch if any other branch points\nto the same revision, I encourage you to work on a patch to make it so.\n\nFor maximum chance of getting included, you would want to guard this\nbehind a new config setting, say, branch.deleteRedundantIsSafe, parse it\nhere:\n\nhttps://github.com/git/git/blob/v2.15.1/config.c#L1260-L1288\n\nor here:\n\nhttps://github.com/git/git/blob/v2.15.1/builtin/branch.c#L78-L97\n\ndocument it here:\n\nhttps://github.com/git/git/blob/v2.15.1/Documentation/git-branch.txt\n\nand here:\n\nhttps://github.com/git/git/blob/v2.15.1/Documentation/config.txt#L969\n\nand handle it here:\n\nhttps://github.com/git/git/blob/v2.15.1/builtin/branch.c#L185-L288\n\n(look for the places where `force` is used, likely just before the call to\n`check_branch_commit()`).\n\nThe way you'd want it to handle is most lilkely by imitating the\n`--points-at` code here:\nhttps://github.com/git/git/blob/v2.15.1/builtin/for-each-ref.c#L42\n\nCiao,\nJohannes\n"},{"id":"333969","messageId":"C75A5523697E4772A984765E8535FDE2@PhilipOakley","threadId":"47332","inReplyTo":"alpine.DEB.2.21.1.1711291302370.6482@virtualbox","subject":"Re: Antw: Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2017-12-02T20:52:10Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"Hi Ulrich\n\nFrom: \"Johannes Schindelin\" <Johannes.Schindelin@gmx.de>\nTo: \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de>\nCc: <git@vger.kernel.org>\nSent: Wednesday, November 29, 2017 12:27 PM\nSubject: Re: Antw: Re: bug deleting \"unmerged\" branch (2.12.3)\n\n\n> Hi Ulrich,\n>\n> On Wed, 29 Nov 2017, Ulrich Windl wrote:\n>\n>> > On Tue, 28 Nov 2017, Ulrich Windl wrote:\n>> >\n>> >> During a rebase that turned out to be heavier than expected 8-( I\n>> >> decided to keep the old branch by creating a temporary branch name to\n>> >> the commit of the branch to rebase (which was still the old commit ID\n>> >> at that time).\n>> >>\n>> >> When done rebasing, I attached a new name to the new (rebased)\n>> >> branch, deleted the old name (pointing at the same rebase commit),\n>> >> then recreated the old branch from the temporary branch name (created\n>> >> to remember the commit id).\n>> >>\n>> >> When I wanted to delete the temporary branch (which is of no use\n>> >> now), I got a message that the branch is unmerged.\n>> >\n>> > This is actually as designed, at least for performance reasons (it is\n>> > not exactly cheap to figure out whether a given commit is contained in\n>> > any other branch).\n>> >\n>> >> I think if more than one branches are pointing to the same commit,\n>> >> one should be allowed to delete all but the last one without warning.\n>> >> Do you agree?\n>> >\n>> > No, respectfully disagree, because I have found myself with branches\n>> > pointing to the same commit, even if the branches served different\n>> > purposes. I really like the current behavior where you can delete a\n>> > branch with `git branch -d` as long as it is contained in its upstream\n>> > branch.\n>>\n>> I'm not talking about the intention of a branch, but of the state of a\n>> branch: If multiple branches point (not \"contain\") the same commit, they\n>> are equivalent (besides the name) at that moment.\n>\n> I did a poor job of explaining myself, please let me try again. I'll give\n> you one concrete example:\n>\n> Recently, while working on some topic, I stumbled over a bug and committed\n> a bug fix, then committed that and branched off a new branch to remind\n> myself to rebase the bug fix and contribute it.\n>\n> At that point, those branches were at the same revision, but distinctly\n> not equivalent (except in just one, very narrow sense of the word, which I\n> would argue is the wrong interpretation in this context).\n>\n> Sadly, I was called away at that moment to take care of something\n> completely different. Even if I had not been, the worktree with the first\n> branch would still have been at that revision for a longer time, as I had\n> to try out a couple of changes before I could commit.\n>\n> This is just one example where the idea backfires that you can safely\n> delete one of two branches that happen to point at the same commit at the\n> same time.\n>\n> I am sure that you possess vivid enough of an imagination to come up with\n> plenty more examples where that is the case.\n>\n>> As no program can predict the future or the intentions of the user, it\n>> should be safe to delete the branch, because it can easily be recreated\n>> (from the remaining branches pointing to the same commit).\n>\n> Yes, no program can predict the future (at least *accurately*).\n>\n> No, it is not safe to delete that branch. Especially if you take the\n> current paradigm of \"it is safe to delete a branch if it is up-to-date\n> with, or at least fast-forwardable to, its upstream branch\" into account.\n>\n> And no, a branch cannot easily be recreated from the remaining branches in\n> the future, as branches can have different reflogs (and they are lost when\n> deleting the branch).\n>\n>> It shouldn't need a lot of computational power to find out when multiple\n>> branches point to the same commit.\n>\n> Sure, that test can even be scripted easily by using the `git for-each-ref\n> --points-at=<revision>` command.\n>\n> By the way, if you are still convinced that my argument is flawed and that\n> it should be considered safe to delete a branch if any other branch points\n> to the same revision, I encourage you to work on a patch to make it so.\n>\n> For maximum chance of getting included, you would want to guard this\n> behind a new config setting, say, branch.deleteRedundantIsSafe, parse it\n> here:\n>\n> https://github.com/git/git/blob/v2.15.1/config.c#L1260-L1288\n>\n> or here:\n>\n> https://github.com/git/git/blob/v2.15.1/builtin/branch.c#L78-L97\n>\n\nI'd agree that it is easy to misinterpret the message. After close reading \nof the thread, Junio put his finger on the scenario with:\n\n-      \"branch -d\" protects branches that are yet to be merged to the \n**current** branch.   (my emphasis)\n\nMaybe the error message could say that (what exactly was the error \nmessage?),\nor the documenation be improved to clarify.\n\n\n> document it here:\n>\n> https://github.com/git/git/blob/v2.15.1/Documentation/git-branch.txt\n>\n> and here:\n>\n> https://github.com/git/git/blob/v2.15.1/Documentation/config.txt#L969\n>\n> and handle it here:\n>\n> https://github.com/git/git/blob/v2.15.1/builtin/branch.c#L185-L288\n>\n> (look for the places where `force` is used, likely just before the call to\n> `check_branch_commit()`).\n>\n> The way you'd want it to handle is most lilkely by imitating the\n> `--points-at` code here:\n> https://github.com/git/git/blob/v2.15.1/builtin/for-each-ref.c#L42\n>\n> Ciao,\n> Johannes \n\n"},{"id":"333970","messageId":"7973FF5C21C64E6492828DD0B91F5AF7@PhilipOakley","threadId":"47332","inReplyTo":"5A1E70AA020000A100029175@gwsmtp1.uni-regensburg.de","subject":"Re: Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2017-12-02T20:56:51Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de>\nTo: <gitster@pobox.com>\nCc: <git@vger.kernel.org>\nSent: Wednesday, November 29, 2017 8:32 AM\nSubject: Antw: Re: bug deleting \"unmerged\" branch (2.12.3)\n\n\n>\n>> \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de> writes:\n>>\n>>> I think if more than one branches are pointing to the same commit,\n>>> one should be allowed to delete all but the last one without\n>>> warning. Do you agree?\n>>\n>> That comes from a viewpoint that the only purpose \"branch -d\" exists\n>> in addition to \"branch -D\" is to protect objects from \"gc\".  Those\n>> who added the safety feature may have shared that view originally,\n>> but it turns out that it protects another important thing you are\n>> forgetting.\n>>\n>> Imagine that two topics, 'topicA' and 'topicB', were independently\n>> forked from 'master', and then later we wanted to add a feature that\n>> depends on these two topics.  Since the 'feature' forked, there may\n>> have been other developments, and we ended up in this topology:\n>>\n>>     ---o---o---o---o---o---M\n>>         \\   \\\n>>          \\   o---A---o---F\n>>           \\         /\n>>            o---o---o---o---B\n>>\n>> where A, B and F are the tips of 'topicA', 'topicB' and 'feature'\n>> branches right now [*1*].\n>>\n>> Now imagine we are on 'master' and just made 'topicB' graduate.  We\n>> would have this topology.\n>>\n>>     ---o---o---o---o---o---o---M\n>>         \\   \\                 /\n>>          \\   o---A---o---F   /\n>>           \\         /       /\n>>            o---o---o---o---B\n>>\n>> While we do have 'topicA' and 'feature' branches still in flight,\n>> we are done with 'topicB'.  Even though the tip of 'topicA' is\n>> reachable from the tip of 'feature', the fact that the branch points\n>> at 'A' is still relevant.  If we lose that information right now,\n>> we'd have to go find it when we (1) want to further enhance the\n>> topic by checking out and building on 'topicA', and (2) want to\n>> finally get 'topicA' graduate to 'master'.\n>>\n>> Because removal of a topic (in this case 'topicB') is often done\n>> after a merge of that topic is made into an integration branch,\n>> \"branch -d\" that protects branches that are yet to be merged to the\n>> current branch catches you if you said \"branch -d topic{A,B}\" (or\n>> other equivalent forms, most likely you'd have a script that spits\n>> out list of branches and feed it to \"xargs branch -d\").\n>>\n>> So, no, I do not agree.\n>\n> Hi!\n>\n> I can follow your argumentation, but I fail to see that your branches A \n> and B point to the same commit (which is what I was talking about). So my \n> situation would be:\n>\n> o---oA,B\n>\n> I still think I could safely remove either A or B, even when the branch \n> (identified by the commit, not by the name) is unmerged. What did I miss?\n\nI think it was that currently you are on M, and neither A nor B are \nancestors (i.e. merged) of M.\n\nAs Junio said:- \"branch -d\" protects branches that are yet to be merged to \nthe **current branch**.\n\n[I said the same in another part of the thread. The question now would be \nwhat needs changing? the error/warning message, the docs, something else?]\n\n>\n> Regards,\n> Ulrich\n>\n>>\n>>\n>> [Footnotes]\n>>\n>> *1* Since the 'feature' started developing, there were a few commits\n>>     added to 'topicB' but because the feature does not depend on\n>>     these enhancements to that topic, B is ahead of the commit that\n>>     was originally merged with the tip of 'topicA' to form the\n>>     'feature' branch.\n> \n\n"},{"id":"333982","messageId":"xmqq1skcleo7.fsf@gitster.mtv.corp.google.com","threadId":"47332","inReplyTo":"7973FF5C21C64E6492828DD0B91F5AF7@PhilipOakley","subject":"Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-12-03T02:37:44Z","receivedAt":"2017-12-03T02:37:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Philip Oakley\" <philipoakley@iee.org> writes:\n\n> I think it was that currently you are on M, and neither A nor B are\n> ancestors (i.e. merged) of M.\n>\n> As Junio said:- \"branch -d\" protects branches that are yet to be\n> merged to the **current branch**.\n\nActually, I think people loosened this over time and removal of\nbranch X is not rejected even if the range HEAD..X is not empty, as\nlong as X is marked to integrate with/build on something else with\nbranch.X.{remote,merge} and the range X@{upstream}..X is empty.\n\nSo the stress of \"current branch\" above you added is a bit of a\nwhite lie.\n"},{"id":"334027","messageId":"AB9C836772CD4391A8866DC71103CCFE@PhilipOakley","threadId":"47332","inReplyTo":"xmqq1skcleo7.fsf@gitster.mtv.corp.google.com","subject":"Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2017-12-03T23:30:26Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Junio C Hamano\" <gitster@pobox.com>\n> \"Philip Oakley\" <philipoakley@iee.org> writes:\n>\n>> I think it was that currently you are on M, and neither A nor B are\n>> ancestors (i.e. merged) of M.\n>>\n>> As Junio said:- \"branch -d\" protects branches that are yet to be\n>> merged to the **current branch**.\n>\n> Actually, I think people loosened this over time and removal of\n> branch X is not rejected even if the range HEAD..X is not empty, as\n> long as X is marked to integrate with/build on something else with\n> branch.X.{remote,merge} and the range X@{upstream}..X is empty.\n>\n> So the stress of \"current branch\" above you added is a bit of a\n> white lie.\n\nAh, thanks. [I haven't had chance to check the code]\n\nThe man page does say:\n.    -d\n.    Delete a branch. The branch must be fully merged in its upstream\n.    branch, or in HEAD if no upstream was set with --track \n.    or --set-upstream.\n\nIt's whether or not Ulrich had joined the two aspects together, and if the\ndoc was sufficient to help recognise the 'unmerged' issue. Ulrich?\n--\nPhilip\n\n"},{"id":"334057","messageId":"5A25705C020000A1000292B0@gwsmtp1.uni-regensburg.de","threadId":"47332","inReplyTo":"AB9C836772CD4391A8866DC71103CCFE@PhilipOakley","subject":"Antw: Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Ulrich Windl","fromEmail":"ulrich.windl@rz.uni-regensburg.de","sentAt":"2017-12-04T15:57:16Z","receivedAt":"2017-12-04T15:57:40Z","isPatch":false,"sender":{"key":"ulrich.windl@rz.uni-regensburg.de","avatar":null},"body":"\nHi Philip!\n\nI'm unsure what you are asking for...\n\nUlrich\n>>> \"Philip Oakley\" <philipoakley@iee.org> 04.12.17 0.30 Uhr >>>\nFrom: \"Junio C Hamano\" <gitster@pobox.com>\n> \"Philip Oakley\" <philipoakley@iee.org> writes:\n>\n>> I think it was that currently you are on M, and neither A nor B are\n>> ancestors (i.e. merged) of M.\n>>\n>> As Junio said:- \"branch -d\" protects branches that are yet to be\n>> merged to the **current branch**.\n>\n> Actually, I think people loosened this over time and removal of\n> branch X is not rejected even if the range HEAD..X is not empty, as\n> long as X is marked to integrate with/build on something else with\n> branch.X.{remote,merge} and the range X@{upstream}..X is empty.\n>\n> So the stress of \"current branch\" above you added is a bit of a\n> white lie.\n\nAh, thanks. [I haven't had chance to check the code]\n\nThe man page does say:\n.    -d\n.    Delete a branch. The branch must be fully merged in its upstream\n.    branch, or in HEAD if no upstream was set with --track \n.    or --set-upstream.\n\nIt's whether or not Ulrich had joined the two aspects together, and if the\ndoc was sufficient to help recognise the 'unmerged' issue. Ulrich?\n--\nPhilip\n\n\n"},{"id":"334493","messageId":"582105F8768F4DA6AF4EC82888F0BFBE@PhilipOakley","threadId":"47332","inReplyTo":"5A25705C020000A1000292B0@gwsmtp1.uni-regensburg.de","subject":"Re: Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2017-12-08T20:26:36Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de>\n> Hi Philip!\n>\n> I'm unsure what you are asking for...\n>\n> Ulrich\n\nHi Ulrich,\n\nI was doing a retrospective follow up (of the second kind [1]).\n\nIn your initial email\nhttps://public-inbox.org/git/5A1D70FD020000A100029137@gwsmtp1.uni-regensburg.de/\nyou said\n\n\"I wanted to delete the temporary branch (which is of no use now), I got a\nmessage that the branch is unmerged.\nI think if more than one branches are pointing to the same commit, one\nshould be allowed to delete all but the last one without warning.\"\n\nMy retrospectives question was to find what what part of the documentation\ncould be improved to assist fellow coders and Git users in gaining a better\nunderstanding here. I think it's an easy mistake [2] to make and that we\nshould try to make the man pages more assistive.\n\nI suspect that the description for the `git branch -d` needs a few more\nwords to clarify the 'merged/unmerged' issue for those who recieve the\nwarning message. Or maybe the git-glossary, etc. I tend to believe that most\nusers will read some of the man pages, and would continue to do so if they\nare useful.\n\nI'd welcome any feedback or suggestions you could provide.\n--\nPhilip\n\n> >>> \"Philip Oakley\" <philipoakley@iee.org> 04.12.17 0.30 Uhr >>>\n> From: \"Junio C Hamano\" <gitster@pobox.com>\n> > \"Philip Oakley\" <philipoakley@iee.org> writes:\n> >\n> >> I think it was that currently you are on M, and neither A nor B are\n> >> ancestors (i.e. merged) of M.\n> >>\n> >> As Junio said:- \"branch -d\" protects branches that are yet to be\n> >> merged to the **current branch**.\n> >\n> > Actually, I think people loosened this over time and removal of\n> > branch X is not rejected even if the range HEAD..X is not empty, as\n> > long as X is marked to integrate with/build on something else with\n> > branch.X.{remote,merge} and the range X@{upstream}..X is empty.\n> >\n> > So the stress of \"current branch\" above you added is a bit of a\n> > white lie.\n>\n> Ah, thanks. [I haven't had chance to check the code]\n>\n> The man page does say:\n> .    -d\n> .    Delete a branch. The branch must be fully merged in its upstream\n> .    branch, or in HEAD if no upstream was set with --track\n> .    or --set-upstream.\n>\n> It's whether or not Ulrich had joined the two aspects together, and if the\n> doc was sufficient to help recognise the 'unmerged' issue. Ulrich?\n> --\n> Philip\n>\n>\n\n[1] Retrospective Second Directive, section 3.4.2 of (15th Ed) Agile\nProcesses in software engineering and extreme programming. ISBN 1628251042\n(for the perspective of the retrospective..)\n[2] 'mistake' colloquial part of the error categories of slips lapses and\nmistakes : Human Error, by Reason (James, prof) ISBN 0521314194 (worthwhile)\n\n"},{"id":"334591","messageId":"5A2E4480020000A1000293D8@gwsmtp1.uni-regensburg.de","threadId":"47332","inReplyTo":"582105F8768F4DA6AF4EC82888F0BFBE@PhilipOakley","subject":"Antw: Re: Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Ulrich Windl","fromEmail":"ulrich.windl@rz.uni-regensburg.de","sentAt":"2017-12-11T08:40:32Z","receivedAt":"2017-12-11T08:40:43Z","isPatch":false,"sender":{"key":"ulrich.windl@rz.uni-regensburg.de","avatar":null},"body":"Hi!\n\nSorry for the late response:\nOn a somewhat not-up-to date manual:\n\n       -d, --delete\n           Delete a branch. The branch must be fully merged in its upstream\n           branch, or in HEAD if no upstream was set with --track or\n           --set-upstream.\n\n\nMaybe the topic of multiple branches pointing to the same commit could be mentioned (regarding the status of each such branch being considered to be merged or not). Also \"fully merged\" could be made a bit more precise, maybe.\n\nMaybe gitglossary could have definitions for \"merged\" and \"fully merged\" with manual pages referring to it.\n\nRegards,\nUlrich\n\n\n>>> \"Philip Oakley\" <philipoakley@iee.org> schrieb am 08.12.2017 um 21:26 in\nNachricht <582105F8768F4DA6AF4EC82888F0BFBE@PhilipOakley>:\n> From: \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de>\n>> Hi Philip!\n>>\n>> I'm unsure what you are asking for...\n>>\n>> Ulrich\n> \n> Hi Ulrich,\n> \n> I was doing a retrospective follow up (of the second kind [1]).\n> \n> In your initial email\n> https://public-inbox.org/git/5A1D70FD020000A100029137@gwsmtp1.uni-regensburg.d \n> e/\n> you said\n> \n> \"I wanted to delete the temporary branch (which is of no use now), I got a\n> message that the branch is unmerged.\n> I think if more than one branches are pointing to the same commit, one\n> should be allowed to delete all but the last one without warning.\"\n> \n> My retrospectives question was to find what what part of the documentation\n> could be improved to assist fellow coders and Git users in gaining a better\n> understanding here. I think it's an easy mistake [2] to make and that we\n> should try to make the man pages more assistive.\n> \n> I suspect that the description for the `git branch -d` needs a few more\n> words to clarify the 'merged/unmerged' issue for those who recieve the\n> warning message. Or maybe the git-glossary, etc. I tend to believe that most\n> users will read some of the man pages, and would continue to do so if they\n> are useful.\n> \n> I'd welcome any feedback or suggestions you could provide.\n> --\n> Philip\n> \n>> >>> \"Philip Oakley\" <philipoakley@iee.org> 04.12.17 0.30 Uhr >>>\n>> From: \"Junio C Hamano\" <gitster@pobox.com>\n>> > \"Philip Oakley\" <philipoakley@iee.org> writes:\n>> >\n>> >> I think it was that currently you are on M, and neither A nor B are\n>> >> ancestors (i.e. merged) of M.\n>> >>\n>> >> As Junio said:- \"branch -d\" protects branches that are yet to be\n>> >> merged to the **current branch**.\n>> >\n>> > Actually, I think people loosened this over time and removal of\n>> > branch X is not rejected even if the range HEAD..X is not empty, as\n>> > long as X is marked to integrate with/build on something else with\n>> > branch.X.{remote,merge} and the range X@{upstream}..X is empty.\n>> >\n>> > So the stress of \"current branch\" above you added is a bit of a\n>> > white lie.\n>>\n>> Ah, thanks. [I haven't had chance to check the code]\n>>\n>> The man page does say:\n>> .    -d\n>> .    Delete a branch. The branch must be fully merged in its upstream\n>> .    branch, or in HEAD if no upstream was set with --track\n>> .    or --set-upstream.\n>>\n>> It's whether or not Ulrich had joined the two aspects together, and if the\n>> doc was sufficient to help recognise the 'unmerged' issue. Ulrich?\n>> --\n>> Philip\n>>\n>>\n> \n> [1] Retrospective Second Directive, section 3.4.2 of (15th Ed) Agile\n> Processes in software engineering and extreme programming. ISBN 1628251042\n> (for the perspective of the retrospective..)\n> [2] 'mistake' colloquial part of the error categories of slips lapses and\n> mistakes : Human Error, by Reason (James, prof) ISBN 0521314194 (worthwhile)\n\n"},{"id":"334685","messageId":"FC22650D36BD4035925DCA978D52A912@PhilipOakley","threadId":"47332","inReplyTo":"5A2E4480020000A1000293D8@gwsmtp1.uni-regensburg.de","subject":"Re: Re: Re: bug deleting \"unmerged\" branch (2.12.3)","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":null,"receivedAt":"2017-12-12T16:57:47Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de>\n> Hi!\n>\n> Sorry for the late response:\n> On a somewhat not-up-to date manual:\n>\n>       -d, --delete\n>           Delete a branch. The branch must be fully merged in its upstream\n>           branch, or in HEAD if no upstream was set with --track or\n>           --set-upstream.\n>\n>\n> Maybe the topic of multiple branches pointing to the same commit could be \n> mentioned (regarding the status of each such branch being considered to be \n> merged or not). Also \"fully merged\" could be made a bit more precise, \n> maybe.\n>\n> Maybe gitglossary could have definitions for \"merged\" and \"fully merged\" \n> with manual pages referring to it.\n\nThanks, I'll add your note to my list of clarifications.\n\nPhilip\n\n>\n> Regards,\n> Ulrich\n>\n>\n>>>> \"Philip Oakley\" <philipoakley@iee.org> schrieb am 08.12.2017 um 21:26 \n>>>> in\n> Nachricht <582105F8768F4DA6AF4EC82888F0BFBE@PhilipOakley>:\n>> From: \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de>\n>>> Hi Philip!\n>>>\n>>> I'm unsure what you are asking for...\n>>>\n>>> Ulrich\n>>\n>> Hi Ulrich,\n>>\n>> I was doing a retrospective follow up (of the second kind [1]).\n>>\n>> In your initial email\n>> https://public-inbox.org/git/5A1D70FD020000A100029137@gwsmtp1.uni-regensburg.d\n>> e/\n>> you said\n>>\n>> \"I wanted to delete the temporary branch (which is of no use now), I got \n>> a\n>> message that the branch is unmerged.\n>> I think if more than one branches are pointing to the same commit, one\n>> should be allowed to delete all but the last one without warning.\"\n>>\n>> My retrospectives question was to find what what part of the \n>> documentation\n>> could be improved to assist fellow coders and Git users in gaining a \n>> better\n>> understanding here. I think it's an easy mistake [2] to make and that we\n>> should try to make the man pages more assistive.\n>>\n>> I suspect that the description for the `git branch -d` needs a few more\n>> words to clarify the 'merged/unmerged' issue for those who recieve the\n>> warning message. Or maybe the git-glossary, etc. I tend to believe that \n>> most\n>> users will read some of the man pages, and would continue to do so if \n>> they\n>> are useful.\n>>\n>> I'd welcome any feedback or suggestions you could provide.\n>> --\n>> Philip\n>>\n>>> >>> \"Philip Oakley\" <philipoakley@iee.org> 04.12.17 0.30 Uhr >>>\n>>> From: \"Junio C Hamano\" <gitster@pobox.com>\n>>> > \"Philip Oakley\" <philipoakley@iee.org> writes:\n>>> >\n>>> >> I think it was that currently you are on M, and neither A nor B are\n>>> >> ancestors (i.e. merged) of M.\n>>> >>\n>>> >> As Junio said:- \"branch -d\" protects branches that are yet to be\n>>> >> merged to the **current branch**.\n>>> >\n>>> > Actually, I think people loosened this over time and removal of\n>>> > branch X is not rejected even if the range HEAD..X is not empty, as\n>>> > long as X is marked to integrate with/build on something else with\n>>> > branch.X.{remote,merge} and the range X@{upstream}..X is empty.\n>>> >\n>>> > So the stress of \"current branch\" above you added is a bit of a\n>>> > white lie.\n>>>\n>>> Ah, thanks. [I haven't had chance to check the code]\n>>>\n>>> The man page does say:\n>>> .    -d\n>>> .    Delete a branch. The branch must be fully merged in its upstream\n>>> .    branch, or in HEAD if no upstream was set with --track\n>>> .    or --set-upstream.\n>>>\n>>> It's whether or not Ulrich had joined the two aspects together, and if \n>>> the\n>>> doc was sufficient to help recognise the 'unmerged' issue. Ulrich?\n>>> --\n>>> Philip\n>>>\n>>>\n>>\n>> [1] Retrospective Second Directive, section 3.4.2 of (15th Ed) Agile\n>> Processes in software engineering and extreme programming. ISBN \n>> 1628251042\n>> (for the perspective of the retrospective..)\n>> [2] 'mistake' colloquial part of the error categories of slips lapses and\n>> mistakes : Human Error, by Reason (James, prof) ISBN 0521314194 \n>> (worthwhile)\n> \n\n"}]}