{"thread":{"id":"41453","subject":"interactive rebase results across shared histories","startedAt":"2016-02-20T22:58:44Z","lastAt":"2016-02-26T22:56:50Z","messageCount":13,"participants":["Seb","Moritz Neeb","Eric Sunshine","David","Kevin Daudt","Stepan Kasal"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"278743","messageId":"87io1j6laz.fsf@gmail.com","threadId":"41453","inReplyTo":null,"subject":"interactive rebase results across shared histories","fromName":"Seb","fromEmail":"spluque@gmail.com","sentAt":"2016-02-20T22:58:44Z","receivedAt":"2016-02-20T22:58:44Z","isPatch":false,"sender":{"key":"spluque@gmail.com","avatar":null},"body":"Hello,\n\nI've recently learnt how to consolidate and clean up the master branch's\ncommit history.  I've squashed/fixuped many commits thinking these would\npropagate to the children branches with whom it shares the earlier parts\nof the its history.  However, this is not the case; switching to the\nchild branch still shows the non-rebased (dirty) commit history from\nmaster.  Am I misunderstanding something with this?\n\nThanks,\n\n-- \nSeb\n"},{"id":"278746","messageId":"56C91D21.90306@moritzneeb.de","threadId":"41453","inReplyTo":"87io1j6laz.fsf@gmail.com","subject":"Re: interactive rebase results across shared histories","fromName":"Moritz Neeb","fromEmail":"lists@moritzneeb.de","sentAt":"2016-02-21T02:12:49Z","receivedAt":"2016-02-21T02:12:49Z","isPatch":false,"sender":{"key":"lists@moritzneeb.de","avatar":null},"body":"Hi Seb,\n\nOn 02/20/2016 11:58 PM, Seb wrote:\n> Hello,\n> \n> I've recently learnt how to consolidate and clean up the master branch's\n> commit history.  I've squashed/fixuped many commits thinking these would\n> propagate to the children branches with whom it shares the earlier parts\n> of the its history.  However, this is not the case; switching to the\n> child branch still shows the non-rebased (dirty) commit history from\n> master.  Am I misunderstanding something with this?\n\nI am not sure what you meand by \"child branch\". If I understand\ncorretly, you have something like:\n\n            A---B---C topic\n           /\n      D---E---F---G master\n\nthen you merge the topic:\n\n            A---B---C topic\n           /         \\\n      D---E---F---G---H master\n\nand then you do something like \"git rebase -i E\" to linearize history\nand maybe squash some commits, to result in something like:\n\n      D---E---F---G---AB'---C' master\n\nWhere AB' is a squashed commit containing the changes from A and B.\n\nNow, your misunderstanding may be in the fact of \"what happened to the\ntopic branch?\". Because looking at the whole graph, you have something\nlike this:\n\n          A---B---C topic\n         /\n    D---E---F---G---AB'---C' master\n\nwhere it is important to note, that the topic still points to C. Which\nis totally correct, because you did not say anything about topic after\nthe merge. If you wanted to continue working on the topic branch, then\nmaybe a non-interactive rebasing, like described in the rebase manpage\nwould be something you might want to do before rebasing. E.g., from the\nstart doing \"git rebase master topic\" leads to:\n\n                     A'--B'--C' topic\n                    /\n       D---E---F---G master\n\nand then you could squash your commits as you like with \"git rebase -i G\":\n\n\t      AB'--C' topic\n             /\nD---E---F---G master\n\nand maybe fast-forward merging master with \"git merge master\", then you\nhave both branches pointing to C':\n\n    D---E---F---G---AB'--C' topic,master\n\nThe same could've been reached in one step via \"git rebase -i master topic\".\n\nMaybe, to get a better understanding, you could use visualization tool\nlike \"tig\" or \"gitk\" to observe what happens to your commits (hashes)\nand branches (labels) and just play around with some of these operations.\n"},{"id":"278753","messageId":"8737sm6kmk.fsf@gmail.com","threadId":"41453","inReplyTo":"56C91D21.90306@moritzneeb.de","subject":"Re: interactive rebase results across shared histories","fromName":"Seb","fromEmail":"spluque@gmail.com","sentAt":"2016-02-21T17:25:39Z","receivedAt":"2016-02-21T17:25:39Z","isPatch":false,"sender":{"key":"spluque@gmail.com","avatar":null},"body":"On Sun, 21 Feb 2016 03:12:49 +0100,\nMoritz Neeb <lists@moritzneeb.de> wrote:\n\n> Hi Seb,\n> On 02/20/2016 11:58 PM, Seb wrote:\n>> Hello,\n\n>> I've recently learnt how to consolidate and clean up the master\n>> branch's commit history.  I've squashed/fixuped many commits thinking\n>> these would propagate to the children branches with whom it shares\n>> the earlier parts of the its history.  However, this is not the case;\n>> switching to the child branch still shows the non-rebased (dirty)\n>> commit history from master.  Am I misunderstanding something with\n>> this?\n\n> I am not sure what you meand by \"child branch\". If I understand\n> corretly, you have something like:\n\n>             A---B---C topic\n>            /\n>       D---E---F---G master\n\nThanks Moritz and sorry for not adequately describing the situation.\nThe scenario is much simpler; imagine master has a longer history behind\nthe point where the topic branch started:\n\n                A---B---C topic\n               /\n  *---D---E---F---G master\n\nAnd we want to keep both branches separate (no desire to merge them for\nnow), but we realize that, say, commits D and E should be\nsquashed/fixup, so we do an interactive rebase.  Now, the problem is\nthat if I do that from the topic branch, the results are not reflected\nin the master branch, even though these commits are certainly shared\nwith master.  It seems counterintuitive that a part of history that is\nshared among branches can be independently manipulated/rewritten with\nrebase.  I must be missing something...\n\n\n-- \nSeb\n"},{"id":"278777","messageId":"CAPig+cSxmWc_Guab0UoQbRMEkVLr-qhF=LCiVk10G5AdnTqnGA@mail.gmail.com","threadId":"41453","inReplyTo":"8737sm6kmk.fsf@gmail.com","subject":"Re: interactive rebase results across shared histories","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-02-21T19:08:44Z","receivedAt":"2016-02-21T19:08:44Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sun, Feb 21, 2016 at 12:25 PM, Seb <spluque@gmail.com> wrote:\n> The scenario is much simpler; imagine master has a longer history behind\n> the point where the topic branch started:\n>\n>                 A---B---C topic\n>                /\n>   *---D---E---F---G master\n>\n> And we want to keep both branches separate (no desire to merge them for\n> now), but we realize that, say, commits D and E should be\n> squashed/fixup, so we do an interactive rebase.  Now, the problem is\n> that if I do that from the topic branch, the results are not reflected\n> in the master branch, even though these commits are certainly shared\n> with master.  It seems counterintuitive that a part of history that is\n> shared among branches can be independently manipulated/rewritten with\n> rebase.  I must be missing something...\n\nWhat you're probably missing is that you can't actually edit commits\nin Git. Instead, what you think of as \"editing\" actually creates a new\ncommit with its own commit-ID, and the original commit still exists\nwith its own commit-ID. Since Git commits are chained together by\ntheir commit-ID's, any commits pointing at the original commit-ID\ncontinue to point to that commit, and only commits rebased atop the\nnew commit-ID of the \"edited\" commit point at it.\n\nIn your example, you're \"editing\" D and E, which creates new commits\nD' and E', so your resulting graph looks like this:\n\n    D'---E'---A---B---C topic\n   /\n  *---D---E---F---G master\n\nSo, \"master\" and \"topic\" really are not sharing D and E (or D' and\nE'). You could \"fix\" this to match your intuition by rebasing F...G\nonto E' (see git-rebase --onto, for instance), which would give you\nthis:\n\n                  A---B---C topic\n                 /\n  *---D'---E'---F---G master\n\nand then \"master\" and \"topic\" would really be sharing D' and E' as\ncommon history. (Of course, rebasing \"master\" or any branch may not be\ndesirable if you've published it, so applicable warnings about\nrebasing apply.)\n\nBy the way, the problem isn't restricted to when you rebase \"topic\"\n(as your problem description implies). You'd see the same behavior if\nyou'd rebased D and E in \"master\" to become D' and E'. \"topic\" would\nstill have old D and E in its history, and not D' and E'.\n"},{"id":"278827","messageId":"87y4ad5sis.fsf@gmail.com","threadId":"41453","inReplyTo":"CAPig+cSxmWc_Guab0UoQbRMEkVLr-qhF=LCiVk10G5AdnTqnGA@mail.gmail.com","subject":"Re: interactive rebase results across shared histories","fromName":"Seb","fromEmail":"spluque@gmail.com","sentAt":"2016-02-22T03:32:43Z","receivedAt":"2016-02-22T03:32:43Z","isPatch":false,"sender":{"key":"spluque@gmail.com","avatar":null},"body":"On Sun, 21 Feb 2016 14:08:44 -0500,\nEric Sunshine <sunshine@sunshineco.com> wrote:\n\n[...]\n\n> What you're probably missing is that you can't actually edit commits\n> in Git. Instead, what you think of as \"editing\" actually creates a new\n> commit with its own commit-ID, and the original commit still exists\n> with its own commit-ID. Since Git commits are chained together by\n> their commit-ID's, any commits pointing at the original commit-ID\n> continue to point to that commit, and only commits rebased atop the\n> new commit-ID of the \"edited\" commit point at it.\n\n> In your example, you're \"editing\" D and E, which creates new commits\n> D' and E', so your resulting graph looks like this:\n\n>     D'---E'---A---B---C topic / *---D---E---F---G master\n\n> So, \"master\" and \"topic\" really are not sharing D and E (or D' and\n> E'). You could \"fix\" this to match your intuition by rebasing F...G\n> onto E' (see git-rebase --onto, for instance), which would give you\n> this:\n\n>                   A---B---C topic / *---D'---E'---F---G master\n\n> and then \"master\" and \"topic\" would really be sharing D' and E' as\n> common history. (Of course, rebasing \"master\" or any branch may not be\n> desirable if you've published it, so applicable warnings about\n> rebasing apply.)\n\n> By the way, the problem isn't restricted to when you rebase \"topic\"\n> (as your problem description implies). You'd see the same behavior if\n> you'd rebased D and E in \"master\" to become D' and E'. \"topic\" would\n> still have old D and E in its history, and not D' and E'.\n\nThank you for this excellent explanation.  I will look into git rebase\n--onto to have both branches share the history that should be shared\nafter the interactive rebase.  Fortunately, this is a private repository\nfor now.\n\n-- \nSeb\n"},{"id":"278841","messageId":"CAMPXz=r23aor3P4XQ3bb1iNsmO9idAUWhGrLhKpMdGa4P_Or8w@mail.gmail.com","threadId":"41453","inReplyTo":"56C91D21.90306@moritzneeb.de","subject":"Re: interactive rebase results across shared histories","fromName":"David","fromEmail":"bouncingcats@gmail.com","sentAt":"2016-02-22T07:41:35Z","receivedAt":"2016-02-22T07:41:35Z","isPatch":false,"sender":{"key":"bouncingcats@gmail.com","avatar":null},"body":"On 21 February 2016 at 13:12, Moritz Neeb <lists@moritzneeb.de> wrote:\n>\n> On 02/20/2016 11:58 PM, Seb wrote:\n>>\n>> I've recently learnt how to consolidate and clean up the master branch's\n>> commit history.  I've squashed/fixuped many commits thinking these would\n>> propagate to the children branches with whom it shares the earlier parts\n>> of the its history.  However, this is not the case; switching to the\n>> child branch still shows the non-rebased (dirty) commit history from\n>> master.  Am I misunderstanding something with this?\n>\n> [snip]\n>\n> Maybe, to get a better understanding, you could use visualization tool\n> like \"tig\" or \"gitk\" to observe what happens to your commits (hashes)\n> and branches (labels) and just play around with some of these operations.\n\n Seb,\n\nIf you have a gui environment, the command\n  gitk --all\nwill show you diagrams that will complement the explanations\nothers have given you here. You must specify --all to see more\nthan one branch.\n\nAnd if you give a branch two names before rebasing one of those\nnames, then you will easily be able to compare before and after.\n"},{"id":"279035","messageId":"87io1f5nsi.fsf@gmail.com","threadId":"41453","inReplyTo":"56C91D21.90306@moritzneeb.de","subject":"Re: interactive rebase results across shared histories","fromName":"Seb","fromEmail":"spluque@gmail.com","sentAt":"2016-02-23T17:39:25Z","receivedAt":"2016-02-23T17:39:25Z","isPatch":false,"sender":{"key":"spluque@gmail.com","avatar":null},"body":"On Sun, 21 Feb 2016 03:12:49 +0100,\nMoritz Neeb <lists@moritzneeb.de> wrote:\n\n> Hi Seb,\n> On 02/20/2016 11:58 PM, Seb wrote:\n>> Hello,\n\n>> I've recently learnt how to consolidate and clean up the master\n>> branch's commit history.  I've squashed/fixuped many commits thinking\n>> these would propagate to the children branches with whom it shares\n>> the earlier parts of the its history.  However, this is not the case;\n>> switching to the child branch still shows the non-rebased (dirty)\n>> commit history from master.  Am I misunderstanding something with\n>> this?\n\n> I am not sure what you meand by \"child branch\". If I understand\n> corretly, you have something like:\n\n[...]\n\n> Maybe, to get a better understanding, you could use visualization tool\n> like \"tig\" or \"gitk\" to observe what happens to your commits (hashes)\n> and branches (labels) and just play around with some of these\n> operations.\n\nOK, I've followed this advice and looked at the dependency graphs in\ngitk before and after rebasing, I've managed to obtain what I was\nafter.  The repository now has two branches: master and topic.  However,\nGitk reveals a problem with a string of commits that are not part of any\nbranch:\n\nA---B---H---I                   (master)\n     \\\n      C---D---E                 (loose string of commits)\n       \\\n        D'---E'---F---G         (topic)\n\nHow do I remove these loose commits (C, D, E)?\n\nThanks for your feedback,\n\n-- \nSeb\n"},{"id":"279087","messageId":"56CCE3C2.1050608@moritzneeb.de","threadId":"41453","inReplyTo":"87io1f5nsi.fsf@gmail.com","subject":"Re: interactive rebase results across shared histories","fromName":"Moritz Neeb","fromEmail":"lists@moritzneeb.de","sentAt":"2016-02-23T22:57:06Z","receivedAt":"2016-02-23T22:57:06Z","isPatch":false,"sender":{"key":"lists@moritzneeb.de","avatar":null},"body":"On 02/23/2016 06:39 PM, Seb wrote:\n> On Sun, 21 Feb 2016 03:12:49 +0100,\n> Moritz Neeb <lists@moritzneeb.de> wrote:\n> \n>> Hi Seb,\n>> On 02/20/2016 11:58 PM, Seb wrote:\n>>> Hello,\n> \n>>> I've recently learnt how to consolidate and clean up the master\n>>> branch's commit history.  I've squashed/fixuped many commits thinking\n>>> these would propagate to the children branches with whom it shares\n>>> the earlier parts of the its history.  However, this is not the case;\n>>> switching to the child branch still shows the non-rebased (dirty)\n>>> commit history from master.  Am I misunderstanding something with\n>>> this?\n> \n>> I am not sure what you meand by \"child branch\". If I understand\n>> corretly, you have something like:\n> \n> [...]\n> \n>> Maybe, to get a better understanding, you could use visualization tool\n>> like \"tig\" or \"gitk\" to observe what happens to your commits (hashes)\n>> and branches (labels) and just play around with some of these\n>> operations.\n> \n> OK, I've followed this advice and looked at the dependency graphs in\n> gitk before and after rebasing, I've managed to obtain what I was\n> after.  The repository now has two branches: master and topic.  However,\n> Gitk reveals a problem with a string of commits that are not part of any\n> branch:\n> \n> A---B---H---I                   (master)\n>      \\\n>       C---D---E                 (loose string of commits)\n>        \\\n>         D'---E'---F---G         (topic)\n> \n> How do I remove these loose commits (C, D, E)?\n>\n\nwhat you might be after is \"git gc\". But I never used it, it was not\nneccesary for me. I would let the automatic garbage collection drop my\ndangling commits. It's safer - who knows when you will still want to\nrestore your recent \"loose string of commits\".\n\nHow exactly are the loose commits causing trouble?\n\n-Moritz\n"},{"id":"279089","messageId":"20160223230401.GB15324@ikke.info","threadId":"41453","inReplyTo":"56CCE3C2.1050608@moritzneeb.de","subject":"Re: interactive rebase results across shared histories","fromName":"Kevin Daudt","fromEmail":"me@ikke.info","sentAt":"2016-02-23T23:04:01Z","receivedAt":"2016-02-23T23:04:01Z","isPatch":false,"sender":{"key":"me@ikke.info","avatar":"https://avatars.githubusercontent.com/u/135698?v=4"},"body":"On Tue, Feb 23, 2016 at 11:57:06PM +0100, Moritz Neeb wrote:\n> On 02/23/2016 06:39 PM, Seb wrote:\n> > On Sun, 21 Feb 2016 03:12:49 +0100,\n> > Moritz Neeb <lists@moritzneeb.de> wrote:\n> > \n> >> Hi Seb,\n> >> On 02/20/2016 11:58 PM, Seb wrote:\n> >>> Hello,\n> > \n> >>> I've recently learnt how to consolidate and clean up the master\n> >>> branch's commit history.  I've squashed/fixuped many commits thinking\n> >>> these would propagate to the children branches with whom it shares\n> >>> the earlier parts of the its history.  However, this is not the case;\n> >>> switching to the child branch still shows the non-rebased (dirty)\n> >>> commit history from master.  Am I misunderstanding something with\n> >>> this?\n> > \n> >> I am not sure what you meand by \"child branch\". If I understand\n> >> corretly, you have something like:\n> > \n> > [...]\n> > \n> >> Maybe, to get a better understanding, you could use visualization tool\n> >> like \"tig\" or \"gitk\" to observe what happens to your commits (hashes)\n> >> and branches (labels) and just play around with some of these\n> >> operations.\n> > \n> > OK, I've followed this advice and looked at the dependency graphs in\n> > gitk before and after rebasing, I've managed to obtain what I was\n> > after.  The repository now has two branches: master and topic.  However,\n> > Gitk reveals a problem with a string of commits that are not part of any\n> > branch:\n> > \n> > A---B---H---I                   (master)\n> >      \\\n> >       C---D---E                 (loose string of commits)\n> >        \\\n> >         D'---E'---F---G         (topic)\n> > \n> > How do I remove these loose commits (C, D, E)?\n> >\n> \n> what you might be after is \"git gc\". But I never used it, it was not\n> neccesary for me. I would let the automatic garbage collection drop my\n> dangling commits. It's safer - who knows when you will still want to\n> restore your recent \"loose string of commits\".\n> \n> How exactly are the loose commits causing trouble?\n> \n\nRight, you should normally not care about these commits. In any case,\nthe reflog is still keeping a reference to these commits, and objects\nnot older then 14 days are also kept.\n\nBut git is regularly running its gc to clean up older objects, and they\nwill not be shared when pushing.\n"},{"id":"279090","messageId":"87egc358ou.fsf@gmail.com","threadId":"41453","inReplyTo":"56CCE3C2.1050608@moritzneeb.de","subject":"Re: interactive rebase results across shared histories","fromName":"Seb","fromEmail":"spluque@gmail.com","sentAt":"2016-02-23T23:05:37Z","receivedAt":"2016-02-23T23:05:37Z","isPatch":false,"sender":{"key":"spluque@gmail.com","avatar":null},"body":"On Tue, 23 Feb 2016 23:57:06 +0100,\nMoritz Neeb <lists@moritzneeb.de> wrote:\n\n[...]\n\n>> OK, I've followed this advice and looked at the dependency graphs in\n>> gitk before and after rebasing, I've managed to obtain what I was\n>> after.  The repository now has two branches: master and topic.\n>> However, Gitk reveals a problem with a string of commits that are not\n>> part of any branch:\n\n>> A---B---H---I (master) \\ C---D---E (loose string of commits) \\\n>> D'---E'---F---G (topic)\n\n>> How do I remove these loose commits (C, D, E)?\n\n\n> what you might be after is \"git gc\". But I never used it, it was not\n> neccesary for me. I would let the automatic garbage collection drop my\n> dangling commits. It's safer - who knows when you will still want to\n> restore your recent \"loose string of commits\".\n\n> How exactly are the loose commits causing trouble?\n\nSure enough, these dangling commits were removed automatically without\nany intervention.  All is good.\n\nThanks!\n\n-- \nSeb\n"},{"id":"279520","messageId":"CAMPXz=on8ONkzDYWEEGFqqKhRoBb9zYBqmYDBsKWagdwFRPRdA@mail.gmail.com","threadId":"41453","inReplyTo":"87egc358ou.fsf@gmail.com","subject":"Re: interactive rebase results across shared histories","fromName":"David","fromEmail":"bouncingcats@gmail.com","sentAt":"2016-02-26T12:38:38Z","receivedAt":"2016-02-26T12:38:38Z","isPatch":false,"sender":{"key":"bouncingcats@gmail.com","avatar":null},"body":"On 24 February 2016 at 10:05, Seb <spluque@gmail.com> wrote:\n> On Tue, 23 Feb 2016 23:57:06 +0100,\n> Moritz Neeb <lists@moritzneeb.de> wrote:\n>\n> [...]\n>\n>>> OK, I've followed this advice and looked at the dependency graphs in\n>>> gitk before and after rebasing, I've managed to obtain what I was\n>>> after.  The repository now has two branches: master and topic.\n>>> However, Gitk reveals a problem with a string of commits that are not\n>>> part of any branch:\n>\n>>> A---B---H---I (master) \\ C---D---E (loose string of commits) \\\n>>> D'---E'---F---G (topic)\n>\n>>> How do I remove these loose commits (C, D, E)?\n>\n>\n>> what you might be after is \"git gc\". But I never used it, it was not\n>> neccesary for me. I would let the automatic garbage collection drop my\n>> dangling commits. It's safer - who knows when you will still want to\n>> restore your recent \"loose string of commits\".\n>\n>> How exactly are the loose commits causing trouble?\n>\n> Sure enough, these dangling commits were removed automatically without\n> any intervention.  All is good.\n\nThis discussion could end there without problem. But if you want to\nunderstand a little more thoroughly, read on ...\n\nFirst, for basic git use, please stop being concerned about when or whether\ndangling commits are removed or not. For basic git use, it is unimportant\n(except for advanced use like disaster recovery).\n\nBy default, git waits a while (couple of weeks I think?) and then removes\ndangling commits silently.\n\nWhy remove them? Because dangling commits are commits that git has\nbeen instructed to forget about and discard, because no reference\n(like a branch or tag) points to them.\n\nAnd because they are unimportant, gitk chooses not to show them;\nwhenever you refresh or restart gitk, it won't show any dangling commits.\n\nWhy does git wait before discarding them entirely? Because advanced\nusers might want to do something clever with them.\n\nSo your dangling commits (after rebase) are probably not removed for a\ncouple of weeks. If you were to somehow recreate a reference to them,\nthen gitk will show them again. But otherwise it treats them as unworthy\nof being shown.\n\nSo how did you ever see the dangling commits? I think it is because gitk\nwas aware of them because it had a reference to them before the rebase.\nSo if you keep gitk open it still shows them afterwards even though the\nreference is gone. And if I recall correctly, if you refresh or restart gitk,\nthey will disappear from its display.\n"},{"id":"279568","messageId":"87povj41m9.fsf@gmail.com","threadId":"41453","inReplyTo":"CAMPXz=on8ONkzDYWEEGFqqKhRoBb9zYBqmYDBsKWagdwFRPRdA@mail.gmail.com","subject":"Re: interactive rebase results across shared histories","fromName":"Seb","fromEmail":"spluque@gmail.com","sentAt":"2016-02-26T21:12:46Z","receivedAt":"2016-02-26T21:12:46Z","isPatch":false,"sender":{"key":"spluque@gmail.com","avatar":null},"body":"On Fri, 26 Feb 2016 23:38:38 +1100,\nDavid <bouncingcats@gmail.com> wrote:\n\n> On 24 February 2016 at 10:05, Seb <spluque@gmail.com> wrote:\n>> On Tue, 23 Feb 2016 23:57:06 +0100,\n>> Moritz Neeb <lists@moritzneeb.de> wrote:\n\n>> [...]\n\n>>>> OK, I've followed this advice and looked at the dependency graphs\n>>>> in gitk before and after rebasing, I've managed to obtain what I\n>>>> was after.  The repository now has two branches: master and topic.\n>>>> However, Gitk reveals a problem with a string of commits that are\n>>>> not part of any branch:\n\n>>>> A---B---H---I (master) \\ C---D---E (loose string of commits) \\\n>>>> D'---E'---F---G (topic)\n\n>>>> How do I remove these loose commits (C, D, E)?\n\n\n>>> what you might be after is \"git gc\". But I never used it, it was not\n>>> neccesary for me. I would let the automatic garbage collection drop\n>>> my dangling commits. It's safer - who knows when you will still want\n>>> to restore your recent \"loose string of commits\".\n\n>>> How exactly are the loose commits causing trouble?\n\n>> Sure enough, these dangling commits were removed automatically\n>> without any intervention.  All is good.\n\n> This discussion could end there without problem. But if you want to\n> understand a little more thoroughly, read on ...\n\nThanks David, I appreciate the insight.  Indeed, I've learnt a lot over\nthe last few days with help in this thread as I confronted a lurking\nproblem after many years neglecting it.  Briefly, long ago I was\ndeveloping a project in RCS, then on CVS and SVN, until some years ago I\nimported it into git via cvs2svn.  I had turned a blind eye to a bit of\nmess up to the very early releases, likely due to my inexperience but\nalso differences between VCS.\n\nAfter cleaning up all the mess, I've ended up with a long master branch,\nand a series of earlier commits that are not reachable from master.\nFortunately, the tags have kept them alive. This is the scenario\nsimplified:\n\nA---C---D(tag2)                 loose commits (not on any branch)\n \\\n  B(tag1)\n\nE---F---G---H---*               (master)\n\nI could put the \"loose\" (but tagged) commits on a branch at \"tag2\", but\nI hate that \"tag1\" shows as a twig there...  It would be nice to have\nall the history reachable from master.  So two questions I'm working on\nright now: 1) how to bring \"tag1\" into the \"tag2\" chain of commits, and\nthen 2) how to tie it all together into master so that it reads\nlinearly.\n\n-- \nSeb\n"},{"id":"279577","messageId":"20160226225650.GA3185@ucw.cz","threadId":"41453","inReplyTo":"87povj41m9.fsf@gmail.com","subject":"Re: interactive rebase results across shared histories","fromName":"Stepan Kasal","fromEmail":"kasal@ucw.cz","sentAt":"2016-02-26T22:56:50Z","receivedAt":"2016-02-26T22:56:50Z","isPatch":false,"sender":{"key":"kasal@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/1481596?v=4"},"body":"Hello Seb,\n\nlet me add a few things, perhaps they'll clean some misunderstandings.\n\nOn Fri, Feb 26, 2016 at 03:12:46PM -0600, Seb wrote:\n> After cleaning up all the mess, I've ended up with a long master branch,\n> and a series of earlier commits that are not reachable from master.\n> Fortunately, the tags have kept them alive. This is the scenario\n> simplified:\n> \n> A---C---D(tag2)                 loose commits (not on any branch)\n>  \\\n>   B(tag1)\n> \n> E---F---G---H---*               (master)\n\nI noticed that these are tags.  Actually, tags in git are meant to mark\ncertain fixed points, and they are not meant to change in the future.\n\nThey are used to mark releases in the project, and they can even have\na cryptographic signature attached to it, so that no one can forge them.\n\nI guess that you used them as a temporary mark for yourself when you\nreaced a point in development, or to mark a stable point as a base for\nfuture development.  If that was the case, you could have used a branch\nas well.\n\nI guess that people subconsciously still think that branch is ecpensive,\nbased on the experiences from other VCS.  It's not true: branch is\na variable that holds a value: the hex id of the top commit.\nAs you do not care how many variables you need to declare when writing\ncode, you should not hesitate to create as many branches as you need\nto mark the points in the history.\n\nPerhaps you just delte the tags.  That would be true if the code\nin these old branches has already been copied (by rebase) to the new\nmaster.\n\nIf you would like to mark the corresponding points in the rewritten\nhistory, you can create these marks again.  (As branches, perhaps.)\n\nThen you say that you want to put everything to one branch master,\nto create a linear history of development.  (Well, not true history,\nbut a made up history, you see.)\n\nFor that goal, does master already contain all the code?\nIf yes, then you have it.  You can perhaps just delete all the old\nbranches that were used to develop individual parts...\n\nI'm working on a project, where we decided to have linear history\non the main server.\nSo my own local git clone of my work contains lots of branches named\nafter features and their combination, like:\n    counting\n    counting-3counters\n    pairs\n    counting-with-pairs\n    counting-3c-pairs\n\nI use rebase heavily to move each of the feature (=series of commits)\nto another branch ot to master.\n\nFor example, when i wanted to enhance branch \"counting\" with the feature\n\"pairs,\" I did it like this:\n\ngit branch counting-with-pairs pairs\ngit rebase -i counting counting-with-pairs\n\nThat will take all the commits that are in pairs, but not in counting.\n(This is usually all the commits in \"pairs\", staring from the point\nwhere in branched from master.) And all these get replayed on the tip of\n\"counting\".\n\nLikewise, I can move the topic to the latest master, then move master\n(git checkout master; git merge --ff-only some-branch)\nand then push.\n\nBTW, another thing:\nwhen you decided to clean up the history -- are there any other\npeople working with the repository you are working with?\n\nIf yes, then each of them has to be prepared to follow your cleanup.\nAll their work is currently base on the old history; if they push\ntheir work all the old hostory will be back.\n\nThey could throw away their current local clones and start anew,\nif they had no work there.  But that's probaably not the case.\n\nSo they have to fetch your new history of master and then rebase\nall of their features --onto your new master.\n\nI hope some of my talking will be useful.\n\nStepan\n"}]}