Separate default remotes for pulling and pushing

7 messages, 3 authors, 2016-06-15 · open the first message on its own page

Separate default remotes for pulling and pushing

From: David Lee <hidden>
Date: 2016-06-15 22:51:11

Hello,

I couldn't find a way to do this, but it seems it would be a fairly common use-case:

I want to set up different default remotes for pushing and pulling so that I can pull from remote a using "git pull" and push to remote b using "git push". This is particularly useful when committing to projects on github, since you may only push to your fork, but you only want to pull updates from the original.

Right now, I can either set the original as my default remote, in which case I must use "git push myfork", or I can set my fork as the default remote, in which case I must use "git pull original".

Please let me know if I'm overlooking a feature already present in git that allows me to have separate remotes for pull and push. Otherwise, I hope it gets implemented in the next version of git!

Thanks for reading,
David

Re: Separate default remotes for pulling and pushing

From: Sverre Rabbelier <hidden>
Date: 2016-06-15 22:51:11

Heya,

On Sat, May 7, 2011 at 10:10, David Lee [off-list ref] wrote:
I want to set up different default remotes for pushing and pulling
See 'git remote set-url --push' [0].

[0] http://www.kernel.org/pub/software/scm/git/docs/git-remote.html

-- 
Cheers,

Sverre Rabbelier

Re: Separate default remotes for pulling and pushing

From: Jeff King <hidden>
Date: 2016-06-15 22:51:12

On Sat, May 07, 2011 at 11:50:35AM +0200, Sverre Rabbelier wrote:
On Sat, May 7, 2011 at 10:10, David Lee [off-list ref] wrote:
quoted
I want to set up different default remotes for pushing and pulling
See 'git remote set-url --push' [0].

[0] http://www.kernel.org/pub/software/scm/git/docs/git-remote.html
That probably doesn't quite do what David wants. It's useful when the
URL for pushing and pulling a particular repository are different.

But if I understand it correctly, David has two _separate_ repositories.
And using remote.*.pushurl for that has some unwanted side effects,
because the tracking ref namespace (i.e., "remotes/origin/*") is shared
by both, even though their refs may not be at the same position.

For example, when pushing "refs/heads/master" to the remote, git will
update "refs/remotes/origin/master" to the pushed value. But that ref is
supposed to reflect the value of the last fetch from his "original"
repository, and now it doesn't. The ref value will flip back and forth
between what's in the two repositories as he pushes and fetches.

I don't think there is currently a way to do what he wants. I think it
would be useful for certain workflows. As I see it, there are a few
pretty common setups for remotes:

  1. Centralized; you push and pull from a single repo, shared with
     other developers. In this case, you call it "origin" and everything
     is easy.

  2. Decentralized, you're the maintainer; you pull from other people or
     apply patches via email. When you push, you push out to some
     publishing point. You'd probably call your publishing point
     "origin" (though I think Junio calls kernel.org "ko" and just types
     "git push ko"). You never pull from some single place all the time,
     so you don't care about a shorthand for it.

  3. Decentralized, you're a developer with a patch-based workflow; you
     fetch from the maintainer, then develop and submit patches via a
     mailing list. You call the maintainer's repo "origin" and pull from
     it automatically.  You never push, so it doesn't matter that
     there's no shorthand.

  4. Decentralized, you're a developer that publishes work via git. You
     call the upstream maintainer "origin", so fetches are convenient
     (and git does this for you at clone, after all). But pushing, even
     though you probably always push to the same central, does not have
     a convenient shorthand.

     This is David's case (and mine, and I suspect some other git
     developers who do enough work that they want to make it publicly
     available via git, or even just have backups). It's also encouraged
     by sites like github, where you might clone the upstream's
     repository, but then pushes your changes up to a personal "fork"
     to let others see and merge them.

So I think part of the reason we don't have such an option is that cases
1-3 are so common. But it would be a nice convenience for people in case
4.

-Peff

Re: Separate default remotes for pulling and pushing

From: David Lee <hidden>
Date: 2016-06-15 22:51:12

Hey Jeff,

Thanks for the super write-up.
That probably doesn't quite do what David wants. It's useful when the
URL for pushing and pulling a particular repository are different.

But if I understand it correctly, David has two _separate_ repositories.
And using remote.*.pushurl for that has some unwanted side effects,
because the tracking ref namespace (i.e., "remotes/origin/*") is shared
by both, even though their refs may not be at the same position.

For example, when pushing "refs/heads/master" to the remote, git will
update "refs/remotes/origin/master" to the pushed value. But that ref is
supposed to reflect the value of the last fetch from his "original"
repository, and now it doesn't. The ref value will flip back and forth
between what's in the two repositories as he pushes and fetches.
I was actually using Sverre's recommendation with virtually no problems except for what you mention: the ref value flips back and forth.
 4. Decentralized, you're a developer that publishes work via git. You
    call the upstream maintainer "origin", so fetches are convenient
    (and git does this for you at clone, after all). But pushing, even
    though you probably always push to the same central, does not have
    a convenient shorthand.
By "push to the same central", I assume you mean "push to the same mirror of origin".
    This is David's case (and mine, and I suspect some other git
    developers who do enough work that they want to make it publicly
    available via git, or even just have backups). It's also encouraged
    by sites like github, where you might clone the upstream's
    repository, but then pushes your changes up to a personal "fork"
    to let others see and merge them.

So I think part of the reason we don't have such an option is that cases
1-3 are so common. But it would be a nice convenience for people in case
4.
I think github is making option 4 the dominant use case. In fact, in our workplace we have a similar workflow set up, where we pull from a central origin, but push to individual mirrors from where commits are reviewed, tested, and merged unto origin.

--David

Re: Separate default remotes for pulling and pushing

From: Jeff King <hidden>
Date: 2016-06-15 22:51:12

On Mon, May 09, 2011 at 01:34:22AM -0700, David Lee wrote:
quoted
 4. Decentralized, you're a developer that publishes work via git. You
    call the upstream maintainer "origin", so fetches are convenient
    (and git does this for you at clone, after all). But pushing, even
    though you probably always push to the same central, does not have
    a convenient shorthand.
By "push to the same central", I assume you mean "push to the same mirror of origin".
Yeah, sorry, that was supposed to be "central spot", but I think you got
the meaning.
I think github is making option 4 the dominant use case. In fact, in
our workplace we have a similar workflow set up, where we pull from a
central origin, but push to individual mirrors from where commits are
reviewed, tested, and merged unto origin.
Yeah, I think we will see more of that as decentralized workflows (and
the tools that support them) mature.

With respect to supporting an alternate default push destination, I'm
not sure what is the best change to make. If "origin" were simply the
default, I would say we should have a push.defaultRemote config that
lets you specify something else.

But it's not that simple. If you are on branch "foo", and you have
"branch.foo.remote" set in your config, then the value of that config
option becomes the default remote. Which makes some sense for pulling
(and there is the associated branch.*.merge config), but of course
pushing may not match.

But now we have precedence questions. If I have config like:

  [push]
    defaultRemote = my-mirror

  [branch "foo"]
    remote = origin
    merge = refs/heads/master

which remote should be the default for "git push"? Obviously if I'm not
on "foo", it should be my-mirror. But if I am, should push.defaultRemote
take precedence? Should there also be a branch.*.pushRemote config that
takes precedence over branch.*.remote?

I have to admit that I have never found the branch.*.remote config to be
useful for any of my workflows, so I am not really sure how people use
it.

-Peff

Re: Separate default remotes for pulling and pushing

From: David Lee <hidden>
Date: 2016-06-15 22:51:12

But now we have precedence questions. If I have config like:

 [push]
   defaultRemote = my-mirror

 [branch "foo"]
   remote = origin
   merge = refs/heads/master

which remote should be the default for "git push"? Obviously if I'm not
on "foo", it should be my-mirror. But if I am, should push.defaultRemote
take precedence? Should there also be a branch.*.pushRemote config that
takes precedence over branch.*.remote?

I have to admit that I have never found the branch.*.remote config to be
useful for any of my workflows, so I am not really sure how people use
it.
What about removing the branch.*.remote config by default, and if it's not set, then it defaults to whatever the repo-wide setting is for defaultRemote? Then a branch.*.remote would override the defaultRemote, and a branch.*.pushRemote would again override that.

Re: Separate default remotes for pulling and pushing

From: Jeff King <hidden>
Date: 2016-06-15 22:51:12

On Mon, May 09, 2011 at 12:01:53PM -0700, David Lee wrote:
quoted
But now we have precedence questions. If I have config like:

 [push]
   defaultRemote = my-mirror

 [branch "foo"]
   remote = origin
   merge = refs/heads/master

which remote should be the default for "git push"? Obviously if I'm not
on "foo", it should be my-mirror. But if I am, should push.defaultRemote
take precedence? Should there also be a branch.*.pushRemote config that
takes precedence over branch.*.remote?

I have to admit that I have never found the branch.*.remote config to be
useful for any of my workflows, so I am not really sure how people use
it.
What about removing the branch.*.remote config by default, and if it's
not set, then it defaults to whatever the repo-wide setting is for
defaultRemote? Then a branch.*.remote would override the
defaultRemote, and a branch.*.pushRemote would again override that.
The branch.*.remote config does much more, though. For example, it is
part of the "upstream" branch config. So getting rid of it is definitely
not an option.

-Peff
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help