git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v6 06/10] fast-export: add new --refspec option

From
Junio C Hamano <gitster@pobox.com>
Date
Dec 9, 2013, 21:00 UTC
Message-ID
<xmqqbo0pyc2u.fsf@gitster.dls.corp.google.com>
In-Reply-To
<52a2f1c59de6f_29836d5e9830@nysa.notmuch>
Felipe Contreras <felipe.contreras@gmail.com> writes:
Show 15 quoted lines
> Junio C Hamano wrote:
>> Junio C Hamano <gitster@pobox.com> writes:
>> > Felipe Contreras <felipe.contreras@gmail.com> 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.
Previous: Felipe ContrerasNext: Junio C Hamano
Message 23 of 32 in “transport-helper: add support to delete branches”
  1. 10/10 transport-helper: add support to delete branchesFelipe Contreras, Nov 11, 2013
  2. 00/10 transport-helper: updatesFelipe Contreras, Nov 11, 2013
  3. Junio C HamanoNov 11, 2013
  4. Felipe ContrerasNov 11, 2013
  5. Junio C HamanoNov 11, 2013
  6. Richard HansenNov 12, 2013
  7. Felipe ContrerasNov 12, 2013
  8. remote-bzr: support the new 'force' optionRichard Hansen, Nov 12, 2013
  9. Felipe ContrerasNov 12, 2013
  10. 01/10 transport-helper: fix extra linesFelipe Contreras, Nov 11, 2013
  11. 08/10 fast-import: add support to delete refsFelipe Contreras, Nov 11, 2013
  12. 05/10 fast-export: improve argument parsingFelipe Contreras, Nov 11, 2013
  13. 06/10 fast-export: add new --refspec optionFelipe Contreras, Nov 11, 2013
  14. Junio C HamanoNov 11, 2013
  15. Felipe ContrerasNov 11, 2013
  16. Richard HansenNov 12, 2013
  17. Junio C HamanoNov 12, 2013
  18. Felipe ContrerasNov 12, 2013
  19. Junio C HamanoNov 12, 2013
  20. Felipe ContrerasNov 12, 2013
  21. Junio C HamanoNov 12, 2013
  22. Felipe ContrerasDec 7, 2013
  23. Junio C HamanoDec 9, 2013
  24. Junio C HamanoDec 9, 2013
  25. Felipe ContrerasApr 24, 2014
  26. 03/10 transport-helper: add 'force' to 'export' helpersFelipe Contreras, Nov 11, 2013
  27. Junio C HamanoNov 11, 2013
  28. Felipe ContrerasNov 11, 2013
  29. 09/10 fast-export: add support to delete refsFelipe Contreras, Nov 11, 2013
  30. 07/10 transport-helper: add support for old:new refspecFelipe Contreras, Nov 11, 2013
  31. 04/10 transport-helper: check for 'forced update' messageFelipe Contreras, Nov 11, 2013
  32. 02/10 transport-helper: don't update refs in dry-runFelipe Contreras, Nov 11, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.