Felipe Contreras <felipe.contreras@xxxxxxxxx> writes: > Junio C Hamano wrote: >> Junio C Hamano <gitster@xxxxxxxxx> writes: >> > Felipe Contreras <felipe.contreras@xxxxxxxxx> writes: > >> But it does not have to stay that way. In order to move things >> forward in that direction, this new configuration has to be >> distinguishable from the traditional "refspec", as it embodies a >> different concept. > > Is it a different concept? > > % git config remote.origin.fetch '+refs/heads/*:refs/remotes-test/origin/*' > % git fetch origin master > > What do you call this thing? ------^ The answer to that question is the "value of the 'remote.*.fetch' configuration variable". The refspec mechanism and syntax used in "fetch" and "push" were invented and designed to express two things [*1*]: 1) what is the set of objects that are necessary and sufficient to complete some histories need to be transferred; what are the tips of these histories that are being completed? 2) after the object transfer, some refs on the side that receive the objects are optionally to be updated; 2-a) which refs are they? 2-b) what objects are they updated to point at? A refspec consists of one or more elements, each of which has right and left hand side separated by a colon, i.e. RHS:LHS, and 1) is determined by the RHS 2-a) is determined by the LHS 2-b) is determined by the correspondence between RHS-to-LHS. A wildcarded "refs/heads/*:refs/remotes/origin/*" dynamically expands to what the side that sends objects have, e.g. if fetching from a repository with 'master' and 'next' branches, it becomes refs/heads/master:refs/remotes/origin/master refs/heads/next:refs/remotes/origin/next So with $ refspec='refs/heads/master:refs/remotes/origin/master refs/heads/next:refs/remotes/origin/next' $ git fetch origin $refspec we transfer objects to allow us to have complete histories leading to 'master' and 'next' from the origin repository. And we update our refs/remotes/origin/{next,master} refs. Traditionally, when there is _no_ refspec on the command line, the value of 'remote.*.fetch' configuration variable is used as the fallback default, and that usage is still true. When used in that way, the value of the variable _is taken as_ a refspec. However, we can no longer say that the variable _is_ a refspec with the modern Git, and here is why. "git fetch origin master" used to ignore the 'remote.*.fetch' configuration variable completely, but since f2690487 (which is a fairly recent invention), the variable participates in the "fetch" process in a different way [*2*]. With this in the config: [remote "origin"] fetch = refs/heads/master:refs/remotes/origin/master fetch = refs/heads/next:refs/remotes/origin/next the command with 'master' refspec on the command line transfers the objects required to complete the history only for the 'master', and not 'next': $ git fetch origin master In this usage, 'master' on the command line is the only thing that determines what histories are completed (because it does not say 'next', the objects necessary to complete its history are not transferred unless they are needed to complete 'master'). The value of the 'remote.*.fetch' configuration does not participate in the determination of the history being transferred at all. It is not used as a refspec. But unlike Git of the last year, we do map this 'master' using the 'remote.*.fetch' configuration variable, in order to decide 2) above. We find that the given remote ref, 'master', has an element that corresopnds to it in the 'remote.*.fetch' configuration, and that element tells us to update refs/remotes/origin/master to point at the object they call 'master', effectively turning the above command line into this form (using "refspec" that has only one element, refs/heads/master:refs/remotes/origin/master): $ git fetch origin refs/heads/master:refs/remotes/origin/master There is no "refs/heads/next:refs/remotes/origin/next" here, because the 'fetch' configuration is not used as a refspec, but as something else. My understanding of the added option parameter to "git fast-export" is that it is not about specifying the history being transferred, but is about mapping the name of the destination. For example, does object between 'master' and 'next' participate in the datastream produced with this? fast-export \ --refspec=refs/heads/master:refs/remotes/origin/master \ --refspec=refs/heads/next:refs/remotes/origin/next \ master If this parameter were a refspec, as we have discussed already in previous rounds [*3*], we should be able to give it on the command line, like any normal refspec, instead of repeating the same thing (i.e. up to what commit should the history be transported) as in: fast-export --refspec=refs/heads/master:refs/remotes/origin/master master but just fast-export refs/heads/master:refs/remotes/origin/master [Footnote] *1* Note that readers are hearing the authoritative definition given by the person who invented and designed it back in August 2005. *2* And a recent $gmane/238832 moves "push" in the direction to be in line with "fetch" in this regard. *3* And I think I even outlined the code to do so. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html