{"thread":{"id":"25777","subject":"[BUG?] push to mirrior interferes with parallel operations","startedAt":"2010-11-18T07:39:17Z","lastAt":"2010-11-19T21:54:32Z","messageCount":15,"participants":["Jan Hudec","Jeff King","Andreas Schwab","Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"156083","messageId":"e355bb33c6192a6a29de56c7be93278e.squirrel@artax.karlin.mff.cuni.cz","threadId":"25777","inReplyTo":null,"subject":"[BUG?] push to mirrior interferes with parallel operations","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2010-11-18T07:39:17Z","receivedAt":"2010-11-18T07:39:17Z","isPatch":false,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"Hello all,\n\nI have a repository populated with git-svn. For backup I have\na mirror remote set up. Today I ran 'git push backup' on one\nterminal and before it finished (it's just on a network\nfilesystem, so it's kind of slow), I ran 'git svn fetch' on\nanother. And than I didn't see any results of that fetch.\n\nWhat happened is that the push took the values of all the\nrefs -- including those in refs/remotes/svn as it's a mirror\nfor pushing them to the backup. Meanwhile the fetch udpated\nthem. But when the push finished with the remote repo, it\nupdated the local refs back to the values it pushed, undoing\nthe effects of that fetch.\n\nThe repository was created with simple:\n\n    git remote add --mirror backup /mnt/server/path/to/repo.git\n\nwhich created configuration:\n\n    [remote \"backup\"]\n\turl = /mnt/server/path/to/repo.git\n\tfetch = +refs/*:refs/*\n\tmirror = true\n\nSo, should the push be more careful when updating the refs,\nnot simulate the pull back when doing a --mirror, or the\ngit remote add not add the 'fetch = +refs/*:refs/*' line?\n\nThanks,\nJan\n\n-- \n                                        - Jan Hudec <bulb@ucw.cz>\n"},{"id":"156122","messageId":"20101118175007.GA26505@sigill.intra.peff.net","threadId":"25777","inReplyTo":"e355bb33c6192a6a29de56c7be93278e.squirrel@artax.karlin.mff.cuni.cz","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-18T17:50:08Z","receivedAt":"2010-11-18T17:50:08Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 18, 2010 at 08:39:17AM +0100, Jan Hudec wrote:\n\n> What happened is that the push took the values of all the\n> refs -- including those in refs/remotes/svn as it's a mirror\n> for pushing them to the backup. Meanwhile the fetch udpated\n> them. But when the push finished with the remote repo, it\n> updated the local refs back to the values it pushed, undoing\n> the effects of that fetch.\n\nHrm. There are actually two issues here, I think.\n\nWhat is happening, I believe, is that push is trying to\nopportunistically update your local tracking branches.\n\nSo the first issue is that you do not have the usual branches-in-heads,\ntracking-branches-in-remotes setup. Instead it is looking at your fetch\nrefspec:\n\n>     [remote \"backup\"]\n> \turl = /mnt/server/path/to/repo.git\n> \tfetch = +refs/*:refs/*\n> \tmirror = true\n\nand trying to update everything in refs/* with what it just pushed.\nUsually this is a no-op, since it is the same as the value we just\npushed, but as you found out, it is in a race with concurrent commands.\n\nI think we don't want to be doing the opportunistic update in this case.\nBut what is the correct rule for deciding not to do it? I can think of a\nfew possibilities:\n\n 1. When the mirror option is used. But this doesn't help people who\n    have a broad fetch refspec they have configured without mirror.\n\n 2. When the RHS of a fetch refspec is something that is being pushed.\n    But this doesn't cover the case of pushing local \"refs/heads/foo\" to\n    remote \"refs/heads/bar\", and then having it update \"refs/heads/bar\"\n    locally.\n\n 3. When the ref to be updated is not in refs/remotes. This feels a\n    little hack-ish, but I think would work the best in practice. The\n    refs/remotes hierarchy is supposed to just be a cache of remote\n    state, so really it is the only place such an opportunistic update\n    should be safe. People who are doing exotic things like fetching\n    directly into refs/heads will have to live without the opportunistic\n    update.\n\nThe second issue I mentioned is that transport_update_tracking_ref does\nnot actually check the old sha1 of the ref it is updating. The usual\npractice in git to avoid holding long locks is:\n\n  1. lock ref, read sha1, unlock ref\n  2. do stuff to make a new sha1, remembering old sha1\n  3. lock ref, read sha1, check that it equals old sha1, write new sha1,\n     unlock\n\nWe don't do that here. It is tempting to do something like:\n\ndiff --git a/transport.c b/transport.c\nindex 0078660..02212fb 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -605,7 +605,7 @@ void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int v\n \t\t\tdelete_ref(rs.dst, NULL, 0);\n \t\t} else\n \t\t\tupdate_ref(\"update by push\", rs.dst,\n-\t\t\t\t\tref->new_sha1, NULL, 0, 0);\n+\t\t\t\t\tref->new_sha1, ref->old_sha1, 0, 0);\n \t\tfree(rs.dst);\n \t}\n }\n\nbut that is not right. That is saying \"if we updated the remote ref R\nfrom A to B, update the tracking ref of R to B only if it is at A\".\nHowever, our tracking ref of R is not necessarily at A; it might be\nstale with respect to upstream.\n\nSo really we would need to read the current value of the tracking ref at\nthe beginning of the push. But that is inefficient, and it is not\nactually atomic with the push we are doing.\n\nSo I think it is OK to keep this the way it is, and assume that\nupdate_tracking_ref is about overwriting whatever is there. The real\nproblem in your case is that the things it is overwriting are actually\nprecious heads, not just a remote cache.\n\n-Peff\n"},{"id":"156124","messageId":"20101118175810.GB26505@sigill.intra.peff.net","threadId":"25777","inReplyTo":"20101118175007.GA26505@sigill.intra.peff.net","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-18T17:58:11Z","receivedAt":"2010-11-18T17:58:11Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 18, 2010 at 12:50:08PM -0500, Jeff King wrote:\n\n> >     [remote \"backup\"]\n> > \turl = /mnt/server/path/to/repo.git\n> > \tfetch = +refs/*:refs/*\n> > \tmirror = true\n> \n> I think we don't want to be doing the opportunistic update in this case.\n> But what is the correct rule for deciding not to do it? I can think of a\n> few possibilities:\n\nThinking on this more, perhaps it really is the fetch refspec there that\nis the problem (as you initially suggested).\n\nIt seems to me there are really two kinds of mirrors: one where you will\nfetch everything from the remote, and one where you will push everything\nto the remote.\n\nYou have the latter kind, and the fetch refspec is just causing\nproblems. Removing it would solve not only this issue, but also the fact\nthat you would never want to run \"git fetch backup\", even accidentally,\nin your repo, as it would overwrite your local work.\n\nSo I think we need --mirror=push, or something similar.\n\n-Peff\n"},{"id":"156130","messageId":"20101118184241.GN3693@efreet.light.src","threadId":"25777","inReplyTo":"20101118175007.GA26505@sigill.intra.peff.net","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2010-11-18T18:42:41Z","receivedAt":"2010-11-18T18:42:41Z","isPatch":false,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"On Thu, Nov 18, 2010 at 12:50:08 -0500, Jeff King wrote:\n> On Thu, Nov 18, 2010 at 08:39:17AM +0100, Jan Hudec wrote:\n> >\n> What is happening, I believe, is that push is trying to\n> opportunistically update your local tracking branches.\n\nIndeed.\n\n> So the first issue is that you do not have the usual branches-in-heads,\n> tracking-branches-in-remotes setup. Instead it is looking at your fetch\n> refspec:\n> \n> >     [remote \"backup\"]\n> > \turl = /mnt/server/path/to/repo.git\n> > \tfetch = +refs/*:refs/*\n> > \tmirror = true\n> \n> and trying to update everything in refs/* with what it just pushed.\n> Usually this is a no-op, since it is the same as the value we just\n> pushed, but as you found out, it is in a race with concurrent commands.\n> \n> I think we don't want to be doing the opportunistic update in this case.\n> But what is the correct rule for deciding not to do it? I can think of a\n> few possibilities:\n> \n>  1. When the mirror option is used. But this doesn't help people who\n>     have a broad fetch refspec they have configured without mirror.\n\nThe above config is what is created by default by 'git remote add --mirror'.\nSo I expect the problem to be somewhat common with mirror and a lot rarer\nwithout.\n\nWhich brings the yet another question, namely whether it actually makes sense\nto set the fetch for a mirror remote. Note that any call to fetch will almost\ninevitably abort with \"reusing to pull to checked out ref in non-bare\nrepository\" error.\n\n>  2. When the RHS of a fetch refspec is something that is being pushed.\n>     But this doesn't cover the case of pushing local \"refs/heads/foo\" to\n>     remote \"refs/heads/bar\", and then having it update \"refs/heads/bar\"\n>     locally.\n> \n>  3. When the ref to be updated is not in refs/remotes. This feels a\n>     little hack-ish, but I think would work the best in practice. The\n>     refs/remotes hierarchy is supposed to just be a cache of remote\n>     state, so really it is the only place such an opportunistic update\n>     should be safe. People who are doing exotic things like fetching\n>     directly into refs/heads will have to live without the opportunistic\n>     update.\n\nIn my case it wouldn't actually help. The race was between push to mirror and\nfetch from actual upstream (which happened to be svn via git-svn, but it\nwould happen with git upstream too) and the incorrectly rewound ref was\n'refs/remotes/svn/trunk'.\n\nA combination of 2 *and* 3 would work. I.e. update only remotes and only if\nthey are not being pushed.\n\nWhat would work on the other hand -- and be very conservative approach --\nwould be to only do oportunistic update if the fetch *option* has\n'refs/remotes/<something>' on the right side.\n\n> The second issue I mentioned is that transport_update_tracking_ref does\n> not actually check the old sha1 of the ref it is updating. The usual\n> practice in git to avoid holding long locks is:\n> \n>   1. lock ref, read sha1, unlock ref\n>   2. do stuff to make a new sha1, remembering old sha1\n>   3. lock ref, read sha1, check that it equals old sha1, write new sha1,\n>      unlock\n> \n> We don't do that here.\n> [...]\n> So really we would need to read the current value of the tracking ref at\n> the beginning of the push. But that is inefficient, and it is not\n> actually atomic with the push we are doing.\n\nIndeed, it does not sound reasonable. Plus I don't think it would actually do\nwhat we want. In the case of pushing 'refs/heads/foo' -> 'refs/heads/bar' and\nupdating local 'refs/heads/bar', it's not clear whether it should be updated\nor not.\n\nIn fact the problem is not in the race, but in the fact, that push updates\nrefs, that may have other purpose than tracking the particular remote. The\nproblem is in some cases we don't know whether a ref is purely tracking\n*that* remote or not.\n\n> So I think it is OK to keep this the way it is, and assume that\n> update_tracking_ref is about overwriting whatever is there. The real\n> problem in your case is that the things it is overwriting are actually\n> precious heads, not just a remote cache.\n\nWell, in my case it actually was a remote cache. But of different remote.\n\nThere are two common cases:\n\n 1. The mirror case, where we don't want to do the oportunistic update at\n    all.\n\n 2. The regular case of remote tracking branches, in which case the\n    'remote.<name>.fetch' option matches \".*:refs/remotes/[^*]+/.*\"\n\nand than there is a see of various strange hand-crafted setups, where it's\nnot obvious whether user actually wants the oportunistic update or not.\n\nThus I see two options to change the oportunistic update:\n\n 1. Don't do oportunistic update with mirror. That keeps the other cases work\n    as they do now. Hopefuly users are aware of the behaviour when they\n    hand-craft such setups.\n\n 2. Only do oportunistic update when the fetch specification matches\n    \".*:refs/remotes/[^*]+/.*\". That way oportunistic update will only happen\n    if the remote has it's own section in refs/remotes, so we can assume\n    nothing else is touching it.\n\nand the third option (similar to the first, but done at different point):\n\n 3. Don't set 'fetch' for mirror remotes in non-bare repositories, since\n    non-bare repositories can't be treated as mirrors of something.\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"},{"id":"156131","messageId":"20101118184904.GO3693@efreet.light.src","threadId":"25777","inReplyTo":"20101118175810.GB26505@sigill.intra.peff.net","subject":"Does it make sense to pull from mirror? (Re: [BUG?] push to mirrior interferes with parallel operations)","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2010-11-18T18:49:04Z","receivedAt":"2010-11-18T18:49:04Z","isPatch":false,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"On Thu, Nov 18, 2010 at 12:58:11 -0500, Jeff King wrote:\n> It seems to me there are really two kinds of mirrors: one where you will\n> fetch everything from the remote, and one where you will push everything\n> to the remote.\n> \n> You have the latter kind, and the fetch refspec is just causing\n> problems. Removing it would solve not only this issue, but also the fact\n> that you would never want to run \"git fetch backup\", even accidentally,\n> in your repo, as it would overwrite your local work.\n\nAccidentally did it already. Fortunately it just died with something like\n    \"refusing to pull to checked out branch of non-bare repository\"\nand did nothing at all.\n \n> So I think we need --mirror=push, or something similar.\n\nDoes it *ever* make sense to have a non-bare pull mirror. I think it does\nnot.\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"},{"id":"156133","messageId":"20101118190414.GA30438@sigill.intra.peff.net","threadId":"25777","inReplyTo":"20101118184241.GN3693@efreet.light.src","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-18T19:04:15Z","receivedAt":"2010-11-18T19:04:15Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 18, 2010 at 07:42:41PM +0100, Jan Hudec wrote:\n\n> The above config is what is created by default by 'git remote add --mirror'.\n> So I expect the problem to be somewhat common with mirror and a lot rarer\n> without.\n\nAgreed, and I think just turning off the behavior with \"mirror\" might be\nOK in practice. But I do want to consider whether we can make other\ncorner cases more sensible at the same time.\n\n> Which brings the yet another question, namely whether it actually makes sense\n> to set the fetch for a mirror remote. Note that any call to fetch will almost\n> inevitably abort with \"reusing to pull to checked out ref in non-bare\n> repository\" error.\n\nHmm. Yeah, of the \"fetch vs push mirror\" distinction I made earlier, it\nreally only makes sense to push from a non-bare repo, and to fetch into\na bare repo.\n\n> [skip some thoughtful analysis which I agree with, but I think ends up\n>  not being relevant]\n>\n> In fact the problem is not in the race, but in the fact, that push updates\n> refs, that may have other purpose than tracking the particular remote. The\n> problem is in some cases we don't know whether a ref is purely tracking\n> *that* remote or not.\n\nYeah, you're right. I think the real problem is that we generally assume\nthat by putting something on the RHS of a fetch refspec, it is used just\nfor tracking the particular remote (especially when there is a \"+\" on\nthe front!).\n\nSo the real solution is not having that fetch line.\n\n> and the third option (similar to the first, but done at different point):\n> \n>  3. Don't set 'fetch' for mirror remotes in non-bare repositories, since\n>     non-bare repositories can't be treated as mirrors of something.\n\nOf all the options, this is my favorite. It does what we want in the\ncommon cases, it's simple, and it still allows people to hand-config\ncrazy stuff if they want to.\n\nIt doesn't un-break people's existing repos, but I think we can accept\nthat (actually, the docs say that --mirror only makes sense in bare\nrepositories. Which I think is not true, as you demonstrate, but perhaps\nit dissuaded people from creating broken push mirrors in the past :) ).\n\nThat does still leave one slight corner case, which is a bare repo that\nis used for both fetch and push mirrors. E.g., a repo that straddles the\nborder between two networks might do:\n\n  git init --bare\n  git remote add --mirror network1 host.network1:foo.git\n  git remote add --mirror network2 host.network2:foo.git\n\n  git fetch network1\n  git push network2\n\nto relay commits. Both remotes will have the fetch refspec, as they are\nin a bare repo. But only the first one wants it. In the second one, we\nwill update the heads as tracking refs. A simultaneous fetch/push would\nbe in conflict.\n\nThat is such an unlikely case that we can probably just leave it to be\nhand-configured by anybody who really wants it. Or we can have:\n\n  # adds fetch = refs/*:refs/*\n  git remote add --mirror=fetch network1 host.network1:foo.git\n  # adds push = refs/*:refs/*\n  git remote add --mirror=push network2 host.network2:foo.git\n\nand the default for --mirror (with no type) can be \"fetch\" in a bare repo\nand \"push\" in a non-bare one.\n\n-Peff\n"},{"id":"156134","messageId":"20101118190544.GB30438@sigill.intra.peff.net","threadId":"25777","inReplyTo":"20101118184904.GO3693@efreet.light.src","subject":"Re: Does it make sense to pull from mirror? (Re: [BUG?] push to mirrior interferes with parallel operations)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-18T19:05:44Z","receivedAt":"2010-11-18T19:05:44Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Nov 18, 2010 at 07:49:04PM +0100, Jan Hudec wrote:\n\n> > So I think we need --mirror=push, or something similar.\n> \n> Does it *ever* make sense to have a non-bare pull mirror. I think it does\n> not.\n\nI don't think so. But it may make sense to have a bare push mirror, as I\nmention in my other email. So we may still want to make it easy for the\nuser to specify.\n\n-Peff\n"},{"id":"156202","messageId":"m2ipzt14rh.fsf@igel.home","threadId":"25777","inReplyTo":"20101118190414.GA30438@sigill.intra.peff.net","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Andreas Schwab","fromEmail":"schwab@linux-m68k.org","sentAt":"2010-11-19T19:40:18Z","receivedAt":"2010-11-19T19:40:18Z","isPatch":false,"sender":{"key":"schwab@linux-m68k.org","avatar":"https://avatars.githubusercontent.com/u/2175493?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> it really only makes sense to push from a non-bare repo,\n\nWhy?  The repo could itself be a mirror.\n\nAndreas.\n\n-- \nAndreas Schwab, schwab@linux-m68k.org\nGPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5\n\"And now for something completely different.\"\n"},{"id":"156203","messageId":"20101119194628.GA15466@sigill.intra.peff.net","threadId":"25777","inReplyTo":"m2ipzt14rh.fsf@igel.home","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-19T19:46:28Z","receivedAt":"2010-11-19T19:46:28Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Nov 19, 2010 at 08:40:18PM +0100, Andreas Schwab wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > it really only makes sense to push from a non-bare repo,\n> \n> Why?  The repo could itself be a mirror.\n\nWhy do you have a working directory if you are going to have a refspec\nthat overwrites HEAD behind your back (which, IIRC, git will simply barf\non, so all of your fetches will fail)?\n\nYes, you could do something complex like have a mirror that lives on a\ndetached HEAD and automagically updates the working tree based on some\nparticular ref. But at that point I think you are going to be setting up\n.git/config manually, anyway. This is really about what default git \"git\nremote add --mirror\" should set up.\n\n-Peff\n"},{"id":"156212","messageId":"m28w0p1071.fsf@igel.home","threadId":"25777","inReplyTo":"20101119194628.GA15466@sigill.intra.peff.net","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Andreas Schwab","fromEmail":"schwab@linux-m68k.org","sentAt":"2010-11-19T21:18:58Z","receivedAt":"2010-11-19T21:18:58Z","isPatch":false,"sender":{"key":"schwab@linux-m68k.org","avatar":"https://avatars.githubusercontent.com/u/2175493?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Fri, Nov 19, 2010 at 08:40:18PM +0100, Andreas Schwab wrote:\n>\n>> Jeff King <peff@peff.net> writes:\n>> \n>> > it really only makes sense to push from a non-bare repo,\n>> \n>> Why?  The repo could itself be a mirror.\n>\n> Why do you have a working directory if you are going to have a refspec\n> that overwrites HEAD behind your back (which, IIRC, git will simply barf\n> on, so all of your fetches will fail)?\n\nI don't understand that question.  There is no working directory in a\nbare repo.\n\nAndreas.\n\n-- \nAndreas Schwab, schwab@linux-m68k.org\nGPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5\n\"And now for something completely different.\"\n"},{"id":"156213","messageId":"20101119212118.GA19425@sigill.intra.peff.net","threadId":"25777","inReplyTo":"m28w0p1071.fsf@igel.home","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-19T21:21:18Z","receivedAt":"2010-11-19T21:21:18Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Nov 19, 2010 at 10:18:58PM +0100, Andreas Schwab wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > On Fri, Nov 19, 2010 at 08:40:18PM +0100, Andreas Schwab wrote:\n> >\n> >> Jeff King <peff@peff.net> writes:\n> >> \n> >> > it really only makes sense to push from a non-bare repo,\n> >> \n> >> Why?  The repo could itself be a mirror.\n> >\n> > Why do you have a working directory if you are going to have a refspec\n> > that overwrites HEAD behind your back (which, IIRC, git will simply barf\n> > on, so all of your fetches will fail)?\n> \n> I don't understand that question.  There is no working directory in a\n> bare repo.\n\nNow I'm confused. I thought we were talking about non-bare repos. Can\nyou clarify your question?\n\n-Peff\n"},{"id":"156215","messageId":"m24obd0zpp.fsf@igel.home","threadId":"25777","inReplyTo":"20101119212118.GA19425@sigill.intra.peff.net","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Andreas Schwab","fromEmail":"schwab@linux-m68k.org","sentAt":"2010-11-19T21:29:22Z","receivedAt":"2010-11-19T21:29:22Z","isPatch":false,"sender":{"key":"schwab@linux-m68k.org","avatar":"https://avatars.githubusercontent.com/u/2175493?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Fri, Nov 19, 2010 at 10:18:58PM +0100, Andreas Schwab wrote:\n>\n>> Jeff King <peff@peff.net> writes:\n>> \n>> > On Fri, Nov 19, 2010 at 08:40:18PM +0100, Andreas Schwab wrote:\n>> >\n>> >> Jeff King <peff@peff.net> writes:\n>> >> \n>> >> > it really only makes sense to push from a non-bare repo,\n>> >> \n>> >> Why?  The repo could itself be a mirror.\n>> >\n>> > Why do you have a working directory if you are going to have a refspec\n>> > that overwrites HEAD behind your back (which, IIRC, git will simply barf\n>> > on, so all of your fetches will fail)?\n>> \n>> I don't understand that question.  There is no working directory in a\n>> bare repo.\n>\n> Now I'm confused. I thought we were talking about non-bare repos. Can\n> you clarify your question?\n\nYou claim that pushing from a bare repo does not make sense, and I\nquestion that (I do that all the time).\n\nAndreas.\n\n-- \nAndreas Schwab, schwab@linux-m68k.org\nGPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5\n\"And now for something completely different.\"\n"},{"id":"156216","messageId":"20101119213256.GA579@burratino","threadId":"25777","inReplyTo":"m2ipzt14rh.fsf@igel.home","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-19T21:32:56Z","receivedAt":"2010-11-19T21:32:56Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Andreas Schwab wrote:\n> Jeff King <peff@peff.net> writes:\n\n>> it really only makes sense to push from a non-bare repo,\n>\n> Why?  The repo could itself be a mirror.\n\nJeff seems to have meant\n\n\tWhen in a non-bare repo, it only makes sense to push.\n\nwhich is to say, push --mirror makes sense from a bare repo but fetch\n--mirror does not.  However, I think you read\n\n\tWhen pushing, it only makes sense to use a non-bare repo\n\nto which a reasonable response is to point out that no, push --mirror\nmakes sense from a bare repo after all.\n\nI see no disagreement here. :)\n"},{"id":"156218","messageId":"20101119215143.GA19644@sigill.intra.peff.net","threadId":"25777","inReplyTo":"m24obd0zpp.fsf@igel.home","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-19T21:51:43Z","receivedAt":"2010-11-19T21:51:43Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Nov 19, 2010 at 10:29:22PM +0100, Andreas Schwab wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > On Fri, Nov 19, 2010 at 10:18:58PM +0100, Andreas Schwab wrote:\n> >\n> >> Jeff King <peff@peff.net> writes:\n> >> \n> >> > On Fri, Nov 19, 2010 at 08:40:18PM +0100, Andreas Schwab wrote:\n> >> >\n> >> >> Jeff King <peff@peff.net> writes:\n> >> >> \n> >> >> > it really only makes sense to push from a non-bare repo,\n> >> >> \n> >> >> Why?  The repo could itself be a mirror.\n> >> >\n> >> > Why do you have a working directory if you are going to have a refspec\n> >> > that overwrites HEAD behind your back (which, IIRC, git will simply barf\n> >> > on, so all of your fetches will fail)?\n> >> \n> >> I don't understand that question.  There is no working directory in a\n> >> bare repo.\n> >\n> > Now I'm confused. I thought we were talking about non-bare repos. Can\n> > you clarify your question?\n> \n> You claim that pushing from a bare repo does not make sense, and I\n> question that (I do that all the time).\n\nIt's hard to tell because you trimmed all of the context from my\nstatement, but:\n\n  1. We are talking specifically about pushing to remotes configured\n     using remote.*.mirror, and created via \"git remote add --mirror\".\n\n  2. I think you are reading what I quoted as the converse of what I\n     meant. You are saying \"if bare, pushing does not make sense\". But\n     what I meant there was \"if non-bare, only pushing makes sense\".\n     Which is why my initial response to you was so confused.\n\n     That being said, the immediately following statement you didn't\n     quote was \"[only makes sense...] to fetch into a bare repo\". Which\n     is what you are saying, and I do think is oversimplistic. But...\n\n  3. Much of the rest of my email goes on to explain a case where that\n     simple rule is not true, and discusses the implications.\n\nSo yes. You can push from a bare repo, I agree. I think we need \"git\nremote add --mirror={fetch,push}\" in order to handle all cases. But what\nshould \"git remote --mirror\" do? Be disallowed? Be a synonym for\n--mirror=fetch (as it is now)? Guess based on bare/non-bare status?\n\n-Peff\n"},{"id":"156219","messageId":"20101119215431.GB19644@sigill.intra.peff.net","threadId":"25777","inReplyTo":"20101119213256.GA579@burratino","subject":"Re: [BUG?] push to mirrior interferes with parallel operations","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-11-19T21:54:32Z","receivedAt":"2010-11-19T21:54:32Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Nov 19, 2010 at 03:32:56PM -0600, Jonathan Nieder wrote:\n\n> Andreas Schwab wrote:\n> > Jeff King <peff@peff.net> writes:\n> \n> >> it really only makes sense to push from a non-bare repo,\n> >\n> > Why?  The repo could itself be a mirror.\n> \n> Jeff seems to have meant\n> \n> \tWhen in a non-bare repo, it only makes sense to push.\n> \n> which is to say, push --mirror makes sense from a bare repo but fetch\n> --mirror does not.  However, I think you read\n\nYes, but s/bare/non-bare/ in your statement. :)\n\nThere is also more to it, see the other mail I just sent.\n\n-Peff\n"}]}