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 14, 2011, 13:57 UTC
Message-ID
<CAMP44s1G9jJyiis7z7XbPvW925E-u=0_-h9jJKkj2wyPS9o5ig@mail.gmail.com>
In-Reply-To
<20111114122556.GB19746@sigill.intra.peff.net>
On Mon, Nov 14, 2011 at 2:25 PM, Jeff King <peff@peff.net> wrote:
Show 14 quoted lines
> On Sun, Nov 13, 2011 at 12:07:19AM +0200, Felipe Contreras wrote:
>
>> > 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?
>
> I agree that "--all --tags" looks silly. I don't know why it's
> disallowed; from my reading, it should be a perfectly sensible
> operation. You might try digging in the history or the mailing list.
Yeah, I might do that.
Show 11 quoted lines
>> > 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?
>
> Because I am worried that "--all" pushing refs/remotes will also be
> confusing; it's not what most people are going to want.
>
> If your suggestion is to deprecate the name "--all" and start calling it
> "--branches" or "--heads", then that is an improvement. But making
> "refs/*:refs/*" easier to accidentally use might not be.

That's what I meant; replace --all with --branches (remember heads is a plumbing name).

Show 38 quoted lines
>> > 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/*'
>
> Sorry, I should have been more clear with what I wrote. My "of
> course..." was more of a tangential "well, this is so far from what my
> gut tells me is reasonable that I'm not sure my definition of ugly is
> even relevant here".
>
> For me personally as a user, I prefer learning how a tool actually works
> at its core (in this case, refspecs), and then applying syntactic sugar
> to simplify usage. But I also respect that not everybody feels that way.
>
>> 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?
>
> The problem with that question is that you haven't defined mirror. Does
> that mean you just want pruning, or does it mean that you want your
> local ref namespace to match that of the remote?

Exactly, no mirror has been defined, because I don't want a mirror. A mirror is supposed to have all the refs in sync all the time; that's not what I want.

Show 10 quoted lines
> Git should be able to do each of those cases. And I think it's fine to
> have a less cumbersome syntax to specify them. But it's also important
> that we don't over-simplify the terms so much that they get option A
> when they wanted B.
>
> BTW, right now there is "git remote add --mirror ...", which sets up the
> fetch refspec for you (in this case, mirror is "make your refs look like
> the remote's"). Perhaps rather than adding syntactic sugar to fetch, it
> would be best to channel users into configuring a remote that selects
> from one of a few common setups (including different types of mirrors).

But that assumes that they would want the same refspec operation *all the time* which is not the case (at least for me). Sometimes I want to update only existing branches, sometimes I want to fetch new branches too, sometimes I want to prune local branches, sometimes not.

> It's not as flexible (I can't do a one-off mirrored push without using
> actual refspecs), but my guess is that most users would want to set up
> an actual remote, and picking from a set of configuration recipes would
> be the ideal interface for them.

I don't think so. I doubt users would like a refspec that will delete their local branches *always*; sometimes they would want to prune the remote tracking branches.

Show 19 quoted lines
>> > 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/*'
>
> No, you would just do "--prune", because your refspecs are _already_
> indicating that you are writing into the local namespace, and anything
> you have locally would be deleted by the prune operation. I.e., there is
> no need for --prune-local in this scenario; --prune already does what we
> want.

That's very risky. The user might forget that this is a mirror repo, and delete the local branches unintentionally. Plus, it would be then impossible to prune remote tracking branches.

Show 26 quoted lines
>> 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?
>
> I was trying to outline a situation where "--prune" wouldn't be
> sufficient, which is:
>
>  : we make some topic branch based on another branch
>  $ git checkout -b topic-Y origin/topic-X
>
>  : later, we (or someone else) deletes topic-X upstream
>  $ git push origin :topic-X
>
>  : now we fetch using the regular default refspecs, which put
>  : everything in a separate remote. But we ask to prune, so that
>  : deleted branches will go away.
>  $ git fetch --prune origin
>
> Now origin/topic-X doesn't exist, even though it's configured as the
> upstream of topic-Y. Fetch doesn't enter into the picture, because it is
> configured to only touch items in refs/remotes/.
That's only by default.
> As a user, how do I resolve the situation? I might say topic-Y is
> obsolete and get rid of it. I might rebase it onto another branch. Or I
> might declare it to have no upstream. But all of those are branch
> operations, not fetch operations.

Yes, but that has nothing to do with the operation I want to achieve: git remote sync. By which I mean synchronize the local branches with the branches of a certain remote.

Note that in this sync operation, the upstream branch is irrelevant.
> So what I was trying to say was that either your fetch refspecs tell
> fetch to write into your local branch namespace, or not. If they do,
> then --prune is sufficient (with no -local variant required). If not,
> then touching your local branch namespace is outside the scope of fetch.

I don't want this to be a *permanent* configuration. I see this similar to --force. You can achieve the same by adding a + at the beginning of the refspec, but this is something that should be activated on a per-command basis, thus the option. I think this should be the same.

Cheers.
-- 
Felipe Contreras
Previous: Jeff KingNext: Jeff King
Message 22 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.