{"thread":{"id":"28460","subject":"any way to \"re-sync\" a bare repository against another bare repository?","startedAt":"2011-09-22T17:22:37Z","lastAt":"2011-09-22T19:23:30Z","messageCount":3,"participants":["Chris Friesen","Michael Witten"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"176004","messageId":"4E7B6EDD.1040106@genband.com","threadId":"28460","inReplyTo":null,"subject":"any way to \"re-sync\" a bare repository against another bare repository?","fromName":"Chris Friesen","fromEmail":"chris.friesen@genband.com","sentAt":"2011-09-22T17:22:37Z","receivedAt":"2011-09-22T17:22:37Z","isPatch":false,"sender":{"key":"chris.friesen@genband.com","avatar":null},"body":"Suppose I have a parent bare repository.  I do a \"git clone --bare\" to \ncreate a child repository, and then clone the child to create a \ngrandchild repository.\n\nIf changes get pushed into the parent repository, is there any way to \ncause the child to be updated?\n\nJust a \"git fetch <parent>\" doesn't seem to help.  If I set up parent as \na remote branch I can fetch it, but then it shows all the branches as \n\"parent/<branch>\" rather than updating the child.\n\nI just tried a \"git clone --mirror\" to create the child and it seems to \nallow me to pick up changes in the parent via \"git fetch\".  Is that the \nproper way to handle this?\n\nThanks,\nChris\n\n-- \nChris Friesen\nSoftware Developer\nGENBAND\nchris.friesen@genband.com\nwww.genband.com\n"},{"id":"176010","messageId":"7142366f54c44cea82542adf8aea5bb9-mfwitten@gmail.com","threadId":"28460","inReplyTo":"4E7B6EDD.1040106@genband.com","subject":"Re: any way to \"re-sync\" a bare repository against another bare repository?","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":null,"receivedAt":"2011-09-22T18:41:42Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Thu, 22 Sep 2011 11:22:37 -0600, Chris Friesen wrote:\n\n> Suppose I have a parent bare repository.  I do a \"git clone --bare\" to \n> create a child repository, and then clone the child to create a \n> grandchild repository.\n\nFirstly, what exactly is the scenario you are trying to achieve? Perhaps\nthere is a better way to do what you are trying to do.\n\n> If changes get pushed into the parent repository, is there any way to \n> cause the child to be updated?\n\nThe documentation answers your question (but badly, as with much of the\ndocumentation); from `git help clone':\n\n  --bare\n      Make a bare GIT repository. That is, instead of creating\n      <directory> and placing the administrative files in\n      <directory>/.git, make the <directory> itself the $GIT_DIR.\n      This obviously implies the -n because there is nowhere to\n      check out the working tree. Also the branch heads at the\n      remote are copied directly to corresponding local branch\n      heads, without mapping them to refs/remotes/origin/. When\n      this option is used, neither remote-tracking branches nor\n      the related configuration variables are created.\n\nIn particular:\n\n                                  Also the branch heads at the\n      remote are copied directly to corresponding local branch\n      heads, without mapping them to refs/remotes/origin/. When\n      this option is used, neither remote-tracking branches nor\n      the related configuration variables are created.\n\nIn particular:\n\n                                                           When\n      this option is used, neither remote-tracking branches nor\n      the related configuration variables are created.\n\nThus, you have to explicitly tell git what you fetched and which\nbranch heads should be updated.\n\nConsider this:\n\n  $ git init parent\n  $ git clone        parent child0\n  $ git clone --bare parent child1\n\nNow, look at the config file for the child0 repository:\n\n  $ cat child0/.git/config \n  [core]\n          repositoryformatversion = 0\n          filemode = true\n          bare = false\n          logallrefupdates = true\n  [remote \"origin\"]\n          fetch = +refs/heads/*:refs/remotes/origin/*\n          url = /path/to/parent\n  [branch \"master\"]\n          remote = origin\n          merge = refs/heads/master\n\nIn particular:\n\n          fetch = +refs/heads/*:refs/remotes/origin/*\n\nThat is the default `refspec'; when `git fetch' is not explicitly\ntold on the command line what to fetch and which branch head[s] to\nupdate, then this refspec is used as a default.\n\nNow, look at the config file for the child1 repository:\n\n  $ cat child1/config\n  [core]\n          repositoryformatversion = 0\n          filemode = true\n          bare = true\n  [remote \"origin\"]\n          url = /path/to/parent\n\nIn particular, note that a bare repository doesn't include any\nsuch default information for `git fetch'. However, you could be\nexplicit about it; from within the chidl1 repo:\n\n  $ git fetch origin '+refs/heads/*:refs/remotes/origin/*'\n\n> Just a \"git fetch <parent>\" doesn't seem to help.  If I set up parent as \n> a remote branch I can fetch it,\n\nFirstly, it doesn't make any sense to say \"set up parent as a remote\nbranch\"; what you mean is \"set up `<parent>' as a remote with a default\nrefspec that creates any associated remote-tracking branch heads\".\n\nSecondly, by setting up `<parent>' as a remote, you are creating the\nmissing refspec in your config file:\n\n  [remote \"<parent>\"]\n          url = /path/to/parent\n          fetch = +refs/heads/*:refs/remotes/<parent>/*\n\nwhich is why you get this:\n\n> but then it shows all the branches as \"<parent>/<branch>\" rather\n> than updating the child.\n\nYou need a different refspec, namely:\n\n  +refs/heads/*:refs/heads/*\n\nSo, either be explicit:\n\n  git fetch '<parent>' '+refs/heads/*:refs/heads/*'\n\nor update your config:\n\n  git config 'remote.<parent>.fetch' '+refs/heads/*:refs/heads/*'\n\nOf course, there is an easier way that does all of this [and more]\nfor you:\n\n> I just tried a \"git clone --mirror\" to create the child and it seems to \n> allow me to pick up changes in the parent via \"git fetch\".  Is that the \n> proper way to handle this?\n\nThe documentation answers your question (but badly, as with much of the\ndocumentation); from `git help clone':\n\n  --mirror\n      Set up a mirror of the source repository. This implies\n      --bare. Compared to --bare, --mirror not only maps local\n      branches of the source to local branches of the target, it\n      maps all refs (including remote-tracking branches, notes\n      etc.) and sets up a refspec configuration such that all\n      these refs are overwritten by a git remote update in the\n      target repository.\n\nIn particular:\n\n                sets up a refspec configuration such that all\n      these refs are overwritten by a git remote update in the\n      target repository.\n\nConsider this:\n\n  $ git clone --mirror parent child2\n  $ cat child2/config\n  [core]\n          repositoryformatversion = 0\n          filemode = true\n          bare = true\n  [remote \"origin\"]\n          fetch = +refs/*:refs/*\n          mirror = true\n          url = /path/to/parent\n\nIn particular:\n\n          fetch = +refs/*:refs/*\n\nThat's a very liberal refspec! It basically says that fetch\nshould mirror everything by default.\n\nSincerely,\nMichael Witten\n"},{"id":"176012","messageId":"4E7B8B32.3070609@genband.com","threadId":"28460","inReplyTo":"7142366f54c44cea82542adf8aea5bb9-mfwitten@gmail.com","subject":"Re: any way to \"re-sync\" a bare repository against another bare repository?","fromName":"Chris Friesen","fromEmail":"chris.friesen@genband.com","sentAt":"2011-09-22T19:23:30Z","receivedAt":"2011-09-22T19:23:30Z","isPatch":false,"sender":{"key":"chris.friesen@genband.com","avatar":null},"body":"Thanks for that very thorough response.\n\nThe rationale for this is somewhat convoluted...I have a vendor-supplied \nbuild system that expects to be pointed at a bare repository.  For \nperformance reasons I want to have a local bare repo on each build \nmachine that can be kept in sync with a master repo on a main server.\n\nChris\n\n\nOn 09/22/2011 12:50 PM, Michael Witten wrote:\n> On Thu, 22 Sep 2011 11:22:37 -0600, Chris Friesen wrote:\n>\n>> Suppose I have a parent bare repository.  I do a \"git clone --bare\" to\n>> create a child repository, and then clone the child to create a\n>> grandchild repository.\n>\n> Firstly, what exactly is the scenario you are trying to achieve? Perhaps\n> there is a better way to do what you are trying to do.\n>\n>> If changes get pushed into the parent repository, is there any way to\n>> cause the child to be updated?\n>\n> The documentation answers your question (but badly, as with much of the\n> documentation); from `git help clone':\n>\n>    --bare\n>        Make a bare GIT repository. That is, instead of creating\n>        <directory>  and placing the administrative files in\n>        <directory>/.git, make the<directory>  itself the $GIT_DIR.\n>        This obviously implies the -n because there is nowhere to\n>        check out the working tree. Also the branch heads at the\n>        remote are copied directly to corresponding local branch\n>        heads, without mapping them to refs/remotes/origin/. When\n>        this option is used, neither remote-tracking branches nor\n>        the related configuration variables are created.\n>\n> In particular:\n>\n>                                    Also the branch heads at the\n>        remote are copied directly to corresponding local branch\n>        heads, without mapping them to refs/remotes/origin/. When\n>        this option is used, neither remote-tracking branches nor\n>        the related configuration variables are created.\n>\n> In particular:\n>\n>                                                             When\n>        this option is used, neither remote-tracking branches nor\n>        the related configuration variables are created.\n>\n> Thus, you have to explicitly tell git what you fetched and which\n> branch heads should be updated.\n>\n> Consider this:\n>\n>    $ git init parent\n>    $ git clone        parent child0\n>    $ git clone --bare parent child1\n>\n> Now, look at the config file for the child0 repository:\n>\n>    $ cat child0/.git/config\n>    [core]\n>            repositoryformatversion = 0\n>            filemode = true\n>            bare = false\n>            logallrefupdates = true\n>    [remote \"origin\"]\n>            fetch = +refs/heads/*:refs/remotes/origin/*\n>            url = /path/to/parent\n>    [branch \"master\"]\n>            remote = origin\n>            merge = refs/heads/master\n>\n> In particular:\n>\n>            fetch = +refs/heads/*:refs/remotes/origin/*\n>\n> That is the default `refspec'; when `git fetch' is not explicitly\n> told on the command line what to fetch and which branch head[s] to\n> update, then this refspec is used as a default.\n>\n> Now, look at the config file for the child1 repository:\n>\n>    $ cat child1/config\n>    [core]\n>            repositoryformatversion = 0\n>            filemode = true\n>            bare = true\n>    [remote \"origin\"]\n>            url = /path/to/parent\n>\n> In particular, note that a bare repository doesn't include any\n> such default information for `git fetch'. However, you could be\n> explicit about it; from within the chidl1 repo:\n>\n>    $ git fetch origin '+refs/heads/*:refs/remotes/origin/*'\n>\n>> Just a \"git fetch<parent>\" doesn't seem to help.  If I set up parent as\n>> a remote branch I can fetch it,\n>\n> Firstly, it doesn't make any sense to say \"set up parent as a remote\n> branch\"; what you mean is \"set up `<parent>' as a remote with a default\n> refspec that creates any associated remote-tracking branch heads\".\n>\n> Secondly, by setting up `<parent>' as a remote, you are creating the\n> missing refspec in your config file:\n>\n>    [remote \"<parent>\"]\n>            url = /path/to/parent\n>            fetch = +refs/heads/*:refs/remotes/<parent>/*\n>\n> which is why you get this:\n>\n>> but then it shows all the branches as \"<parent>/<branch>\" rather\n>> than updating the child.\n>\n> You need a different refspec, namely:\n>\n>    +refs/heads/*:refs/heads/*\n>\n> So, either be explicit:\n>\n>    git fetch '<parent>' '+refs/heads/*:refs/heads/*'\n>\n> or update your config:\n>\n>    git config 'remote.<parent>.fetch' '+refs/heads/*:refs/heads/*'\n>\n> Of course, there is an easier way that does all of this [and more]\n> for you:\n>\n>> I just tried a \"git clone --mirror\" to create the child and it seems to\n>> allow me to pick up changes in the parent via \"git fetch\".  Is that the\n>> proper way to handle this?\n>\n> The documentation answers your question (but badly, as with much of the\n> documentation); from `git help clone':\n>\n>    --mirror\n>        Set up a mirror of the source repository. This implies\n>        --bare. Compared to --bare, --mirror not only maps local\n>        branches of the source to local branches of the target, it\n>        maps all refs (including remote-tracking branches, notes\n>        etc.) and sets up a refspec configuration such that all\n>        these refs are overwritten by a git remote update in the\n>        target repository.\n>\n> In particular:\n>\n>                  sets up a refspec configuration such that all\n>        these refs are overwritten by a git remote update in the\n>        target repository.\n>\n> Consider this:\n>\n>    $ git clone --mirror parent child2\n>    $ cat child2/config\n>    [core]\n>            repositoryformatversion = 0\n>            filemode = true\n>            bare = true\n>    [remote \"origin\"]\n>            fetch = +refs/*:refs/*\n>            mirror = true\n>            url = /path/to/parent\n>\n> In particular:\n>\n>            fetch = +refs/*:refs/*\n>\n> That's a very liberal refspec! It basically says that fetch\n> should mirror everything by default.\n>\n> Sincerely,\n> Michael Witten\n\n\n-- \nChris Friesen\nSoftware Developer\nGENBAND\nchris.friesen@genband.com\nwww.genband.com\n"}]}