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

Re: [RFC/PATCH] remote: add new sync command

From
Felipe Contreras <felipe.contreras@gmail.com>
Date
Nov 12, 2011, 22:07 UTC
Message-ID
<CAMP44s06p+KyJAu4ddiCa8CFRq5eogbqxxJU16Z-SUb3GSp67Q@mail.gmail.com>
In-Reply-To
<20111111181352.GA16055@sigill.intra.peff.net>
On Fri, Nov 11, 2011 at 8:13 PM, Jeff King <peff@peff.net> wrote:
Show 14 quoted lines
> On Fri, Nov 11, 2011 at 02:30:48PM +0200, Felipe Contreras wrote:
>
>> > Doesn't --all mean all refs, including tags and branches?
>>
>> Nope, only branches, try it. I also found it strange. And what is
>> more, you can't use --all and --tags at the same time. Totally
>> strange.
>
> Yeah, you're right. Sorry for my confusion.
>
> So in that sense, it is poorly named, and "--branches" (or "--heads")
> would be more accurate. At the same time, it is probably more likely
> what the user wants to do (you almost never want to push "refs/remotes",
> for example).

But you do want to push tags, and --all --tags doesn't sound right; if I'm pushing everything, why do I specify I want to push more stuff. And then, why it --all --tags disallowed?

> So I am a little hesitant to suggest changing it, even
> with a warning and deprecation period.
It is confusing and wrong, what more reason do you need?
Show 8 quoted lines
>> And yes, in this particular use-case that's what I am trying to avoid,
>> but in other use-cases (like creating a new repo and pushing
>> *everything*), a *true* --all would be nice.
>
> Right. It looks like that is just spelled "--mirror" (which gives you
> pruning also), or "refs/*:refs/*" (without pruning). The latter is even
> more flexible, as you could do "refs/*:refs/foo/*" to keep several
> related backups in one upstream repo.

So, we agree that --all is the same as 'refs/heads/*'. Therefore we already have this mixture of refspecs and options.

> Just to get back to the original patch for a second: are we in agreement
> that what you want to do with "sync" is almost possible now (modulo a
> separate --prune option), and that there is a separate issue of making
> friendlier syntax for a few common refspecs?
Yes.
Show 18 quoted lines
>> > We could add syntactic sugar to make
>> > --branches mean "refs/heads/*". But I do worry that pseudo-options like
>> > that just end up creating more confusion (I seem to recall there being a
>> > lot of confusion about "--tags", which is more or less the same thing).
>>
>> But it's not, that could explain part of the confusion. I think these
>> would be totally intuitive.
>>
>>  --branches
>>  --tags
>>  --other
>>  --all
>>  --update
>>  --prune
>
> My problem with them syntactically is that you have option-looking
> things that are really not flags, but rather syntactic placeholders for
> refspecs.
We already have those: --all -> 'ref/heads/*', --tags -> 'refs/tags/*'.
Show 18 quoted lines
> So you have:
>
>  git push --prune remote --branches
>
> which looks wrong from the perspective of usual option-parsing rules.
> And does:
>
>  git push remote --prune --branches
>
> work? Or:
>
>  git push --prune --branches remote
>
> ?
>
> I think we could make them all work if we want. But somehow the syntaxes
> just look wrong to me. Using a non-dashed placeholder for special
> refspecs makes more sense to me like:
I don't see any problem with making them all work.
Show 11 quoted lines
>  git push --prune remote BRANCHES
>
> and then it really is just a special way of spelling "refs/heads/*". But
> then, I also think it's good for users to understand that the options
> are refspecs, and what that means. It's not a hard concept, and then
> when they inevitably say "how can I do BRANCHES, except put the result
> somewhere else in the remote namespace", it's a very natural extension
> to learn about the right-hand side o the refspec.
>
> Of course I also think BRANCHES looks ugly, and people should just learn
> "refs/heads/*".

Look, I'm all in favor of people learning stuff, but I have been involved in Git since basically day 1, and up to this day I was (am?) not familiar with refspecs, I don't use them regularly, and never really had a need to, and that's fine. People are already complaining about the learning curve of git, and what you are suggesting is that:

Instead of doing: % git push remote --branches --tags

They should do: % git push remote 'refs/heads/*' 'refs/tags/*'

I disagree, I think refspecs should remain as plumbing, and there must be a porcelain way to achieve the options I proposed.

> I dunno. Maybe my brain is fried from knowing too much about how git
> works. I don't have much of an "ordinary user" perspective anymore.
Maybe :)
Show 18 quoted lines
>> But what about 'git fetch'? You didn't comment anything. I think we
>> should try to be consistent in these imaginary future options, maybe
>> to devise a transition, or at least to identify good names for the new
>> options.
>
> Yeah, fetch makes it harder because the options may have subtly
> different meanings. Using non-option placeholders would work around
> that. You would still have options for pruning, which to me is not
> really a refspec, but an option that acts on the refspecs.
>
> From the list in your previous email, you wrote:
>
>> --prune -> rename to --prune-tracking?
>> --prune-local (new; prune local branches that don't exist on the remote)
>
> I think --prune wouldn't need renaming. If you fetch into tracking
> branches, then pruning would prune tracking branches. If you fetch as a
> mirror (refs/*:refs/*), then you would prune everything.

I'm not going to investigate the subtleties of these different setups, I'm going to put my common user hat and ask; how do I fetch as a mirror?

> And "--prune-local" doesn't seem like a fetch operation to me. Either
> you are mirroring, and --prune already handles it as above. Or you are
> interested in getting rid of branches whose upstream has gone away. But
> that's not a fetch operation; that's a branch operation.
This would make things more confusing to the user.

Say on one side I do this push? % git push test --prune 'refs/heads/*' 'refs/tags/*'

What do I do in the other side to synchronize the repo? % git fetch test --prune-local 'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*'

I would prefer this of course: % git fetch test --all --prune-local

But you are saying it should be: % git fetch test 'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*' % git branch --prune-remote test

That doesn't sound right to me; mixing branch operations with a specific remote?

Again, I think conceptually it's much easier to think about these operations to be related to a specific remote, sure, fetch and push mostly deal with specific remotes, but even more 'git remote'.

-- 
Felipe Contreras
Previous: Jeff KingNext: Jeff King
Message 20 of 26 in “remote: add new sync command”
  1. remote: add new sync commandFelipe Contreras, Nov 7, 2011
  2. Jeff KingNov 7, 2011
  3. Felipe ContrerasNov 7, 2011
  4. Jeff KingNov 7, 2011
  5. Felipe ContrerasNov 7, 2011
  6. Jeff KingNov 7, 2011
  7. Junio C HamanoNov 7, 2011
  8. Jeff KingNov 7, 2011
  9. Felipe ContrerasNov 8, 2011
  10. Junio C HamanoNov 8, 2011
  11. Felipe ContrerasNov 8, 2011
  12. Junio C HamanoNov 9, 2011
  13. Jakub NarebskiNov 11, 2011
  14. Junio C HamanoNov 11, 2011
  15. Jakub NarebskiNov 11, 2011
  16. Felipe ContrerasNov 8, 2011
  17. Jeff KingNov 8, 2011
  18. Felipe ContrerasNov 11, 2011
  19. Jeff KingNov 11, 2011
  20. Felipe ContrerasNov 12, 2011
  21. Jeff KingNov 14, 2011
  22. Felipe ContrerasNov 14, 2011
  23. Jeff KingNov 21, 2011
  24. Felipe ContrerasNov 21, 2011
  25. Jeff KingNov 30, 2011
  26. Felipe ContrerasNov 30, 2011

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.