{"thread":{"id":"31183","subject":"need help with syncing two bare repos","startedAt":"2012-08-03T18:29:44Z","lastAt":"2012-08-03T21:34:42Z","messageCount":5,"participants":["Eugene Sajine","Sitaram Chamarty","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"196427","messageId":"CAPZPVFax6wa9QYOMxghhWK6LJaYWS2+WCbWQLA+LE53TdNXJhQ@mail.gmail.com","threadId":"31183","inReplyTo":null,"subject":"need help with syncing two bare repos","fromName":"Eugene Sajine","fromEmail":"euguess@gmail.com","sentAt":"2012-08-03T18:29:44Z","receivedAt":"2012-08-03T18:29:44Z","isPatch":false,"sender":{"key":"euguess@gmail.com","avatar":null},"body":"Hi,\n\nCould somebody please advise about how to address the following:\n\nI have a bare repo (bareA) on one server in network1 and i have a\nmirror of it on another server (bareB) in network2\nBareB is updated periodically - no problem here\nIf bareA dies users are supposed to move seamlessly to bareB.\nWhen bareA goes back up users are moved back but before it starts\nserving repos (before git-daemon starts) it updates from bareB.\n\nNow the problem i have is if bareA doesn't actually die, but the\nconnection between two networks drops.\nIn this case users from network2 will stop seeing bareA, they will\nstart working with bareB, while users in netwrok1 will continue\nto work with bareA.\n\nWhat would be the best way of syncing the bareB back to bareA when\nconnection is restored?\n\nI think the best variant would be to do something like:\n\n$ git pull --rebase /refs/heads/*:/refs/heads/*\n$ git push origin /refs/heads/*:/refs/heads/*\n\nbut pull will not work on bare repos as i understand and there might\nbe conflicts that will lead to unknown (for me) state of bare repos\n\nMay be I'm looking into wrong direction? May be simple two way rsync\nwill do the job? But I'm a bit reluctant to rely on rsync because I'm\nafraid it may screw up the repository information.\n\nAny ideas are much appreciated!\n\nThanks,\nEugene\n"},{"id":"196428","messageId":"CAMK1S_jmML56ef2EVZqEX6i+_y-NyaoazZdXQQ+N88GWL4X2Qg@mail.gmail.com","threadId":"31183","inReplyTo":"CAPZPVFax6wa9QYOMxghhWK6LJaYWS2+WCbWQLA+LE53TdNXJhQ@mail.gmail.com","subject":"Re: need help with syncing two bare repos","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2012-08-03T19:14:18Z","receivedAt":"2012-08-03T19:14:18Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On Fri, Aug 3, 2012 at 11:59 PM, Eugene Sajine <euguess@gmail.com> wrote:\n> Hi,\n>\n> Could somebody please advise about how to address the following:\n>\n> I have a bare repo (bareA) on one server in network1 and i have a\n> mirror of it on another server (bareB) in network2\n> BareB is updated periodically - no problem here\n> If bareA dies users are supposed to move seamlessly to bareB.\n> When bareA goes back up users are moved back but before it starts\n> serving repos (before git-daemon starts) it updates from bareB.\n>\n> Now the problem i have is if bareA doesn't actually die, but the\n> connection between two networks drops.\n> In this case users from network2 will stop seeing bareA, they will\n> start working with bareB, while users in netwrok1 will continue\n> to work with bareA.\n>\n> What would be the best way of syncing the bareB back to bareA when\n> connection is restored?\n>\n> I think the best variant would be to do something like:\n>\n> $ git pull --rebase /refs/heads/*:/refs/heads/*\n> $ git push origin /refs/heads/*:/refs/heads/*\n>\n> but pull will not work on bare repos as i understand and there might\n> be conflicts that will lead to unknown (for me) state of bare repos\n>\n> May be I'm looking into wrong direction? May be simple two way rsync\n> will do the job? But I'm a bit reluctant to rely on rsync because I'm\n> afraid it may screw up the repository information.\n\nThe way I solve this is to insist that I *manually* specify which is\nthe push destination and not make it automated.  The other one is a\nread-only mirror until something is manually switched.\n\nMight not be ideal for every situation; your call...\n"},{"id":"196433","messageId":"7vboirbva3.fsf@alter.siamese.dyndns.org","threadId":"31183","inReplyTo":"CAPZPVFax6wa9QYOMxghhWK6LJaYWS2+WCbWQLA+LE53TdNXJhQ@mail.gmail.com","subject":"Re: need help with syncing two bare repos","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-08-03T20:00:36Z","receivedAt":"2012-08-03T20:00:36Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eugene Sajine <euguess@gmail.com> writes:\n\n> I think the best variant would be to do something like:\n>\n> $ git pull --rebase /refs/heads/*:/refs/heads/*\n> $ git push origin /refs/heads/*:/refs/heads/*\n\nYou perhaps meant \"worst\" not \"best\" here.  From the point of view\nof people who have pushed into the \"origin\" repository we see above,\ntheir history is rewritten; you are screwing half the population by\ndoing this.\n\nNot allowing B to accept pushes while it is not positively sure that\nA has gone down would of course be the best solution (in your scenario,\nB started serving when it merely found out that *it* cannot contact\nA), but barring that, the recovery for two histories at A and B,\nonce they diverged, should be to \"merge\" corresponding branches.\n"},{"id":"196438","messageId":"CAPZPVFZpLBXG0Ntbf06dWRS_Z4hVzMXF-2FmfqvT2mN9A8Ektg@mail.gmail.com","threadId":"31183","inReplyTo":"7vboirbva3.fsf@alter.siamese.dyndns.org","subject":"Re: need help with syncing two bare repos","fromName":"Eugene Sajine","fromEmail":"euguess@gmail.com","sentAt":"2012-08-03T20:31:41Z","receivedAt":"2012-08-03T20:31:41Z","isPatch":false,"sender":{"key":"euguess@gmail.com","avatar":null},"body":"On Fri, Aug 3, 2012 at 4:00 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Eugene Sajine <euguess@gmail.com> writes:\n>\n>> I think the best variant would be to do something like:\n>>\n>> $ git pull --rebase /refs/heads/*:/refs/heads/*\n>> $ git push origin /refs/heads/*:/refs/heads/*\n>\n> You perhaps meant \"worst\" not \"best\" here.  From the point of view\n> of people who have pushed into the \"origin\" repository we see above,\n> their history is rewritten; you are screwing half the population by\n> doing this.\n>\n> Not allowing B to accept pushes while it is not positively sure that\n> A has gone down would of course be the best solution (in your scenario,\n> B started serving when it merely found out that *it* cannot contact\n> A), but barring that, the recovery for two histories at A and B,\n> once they diverged, should be to \"merge\" corresponding branches.\n\nJunio,\n\nThanks for chipping in!\nPlease correct me if I'm wrong, but wouldn't merge result in the same\nhistory changes for people pushing to the origin (bareA)?\nStill all their consequent changes will not be fast-forwardable\nbecause of merge commit. Or am i missing something?\nIt might be that the command i specified is incorrect.\n\nI meant that I would execute \"pull --rebase\" (or proper analogue for\nbare repo) for each branch on B side and then push those refs to A.\nThis way it would pretend that B is another \"dev repo\".\nMay be you can advise on correct commands to do that properly?\n\nI'll think about not allowing pushes to B while not sure it is really\ntime, so it is not reacting on irrelevant connectivity issues or bareA\ndowntime due to the maintenance.\n\nThanks,\nEugene\n"},{"id":"196443","messageId":"7vy5lvacct.fsf@alter.siamese.dyndns.org","threadId":"31183","inReplyTo":"CAPZPVFZpLBXG0Ntbf06dWRS_Z4hVzMXF-2FmfqvT2mN9A8Ektg@mail.gmail.com","subject":"Re: need help with syncing two bare repos","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-08-03T21:34:42Z","receivedAt":"2012-08-03T21:34:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eugene Sajine <euguess@gmail.com> writes:\n\n> On Fri, Aug 3, 2012 at 4:00 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Eugene Sajine <euguess@gmail.com> writes:\n>>\n>>> I think the best variant would be to do something like:\n>>>\n>>> $ git pull --rebase /refs/heads/*:/refs/heads/*\n>>> $ git push origin /refs/heads/*:/refs/heads/*\n>>\n>> You perhaps meant \"worst\" not \"best\" here.  From the point of view\n>> of people who have pushed into the \"origin\" repository we see above,\n>> their history is rewritten; you are screwing half the population by\n>> doing this.\n>>\n>> Not allowing B to accept pushes while it is not positively sure that\n>> A has gone down would of course be the best solution (in your scenario,\n>> B started serving when it merely found out that *it* cannot contact\n>> A), but barring that, the recovery for two histories at A and B,\n>> once they diverged, should be to \"merge\" corresponding branches.\n>\n> ... but wouldn't merge result in the same\n> history changes for people pushing to the origin (bareA)?\n> Still all their consequent changes will not be fast-forwardable\n> because of merge commit. Or am i missing something?\n\nWelcome to the world of distributed version control.\n\nEven with a single server, it always is possible that other people\nhave been working on their changes and pushed their results out\nwhile you are working on your changes when you are working with\nothers.  It is perfectly expected that your changes may not be\nfast-forwardable.  In such a case, you can, and you are expected to,\nfetch the updated tip from the public meeting point, integrate your\nwork with it and then push the result back.\n\nThat is not an issue.\n\nIf the project has \"strictly linear history only\" policy [*1*], then\nthe \"fetch the updated tip, integrate your work and push back\" would\ninvolve a rebase on the participant's part, and only in that very\nnarrow context, it wouldn't make a difference if you rebase at the\nserver end while doing your recovery procedure.  In a way, the\nrebase during your recovery procedure is doing the rebase the\nparticupants would have to perform anyway for them.\n\nBut in a more general workflow where project participants are either\nallowed or encouraged to merge (as opposed to rebase and immediately\npush the untested results out), the history resulting from a merge\nby a participant, when he finds that what he has is not a strict\ndescendant of the recovered A's history, will contain the commits he\nmade originally to A when it was half-alive and their doppelgänger\ncommits your recovery procedure produced by rebasing, which is a\ndisaster.\n\n\n[Footnote]\n\n*1* Projects can enforce strictly linear history by rejecting push\nof a history with any merges in their pre-receive hooks.  Such a\npractice may be denying its participants major benefit of Git,\nnamely, distributedness, but it is probably easier to explain to\npeople coming from CVS or systems where branching and merging are\nimpossibly hard.\n"}]}