Is there a way to set up a git repository, so that git pull defaults to one remote and git push defaults to another? I know I can set both by changing the value of the remote variable in branch section of .git/config, but how to do it for each direction separately?
7 Answers
Since Git version 1.7.0, you can set this with:
git remote set-url --push origin https://your.push.com/blah/
8 Comments
Since Git 1.8.3, you can use the remote.pushDefault option to do exactly what you want (i.e. having different default remotes for pull and push). You can set the option just like any other; for example, to set it to the pushTarget remote, use
git config remote.pushDefault pushTarget
This option will have the following effect:
git pullwill pull from the remote specified by theremoteoption in the relevant branch section in.git/config, whilegit pushwill push to the remote specified byremote.pushDefault.
Note that you need to specify the name of a remote, not an URL. This makes this solution more flexible than the solution involving remote.<name>.pushurl, because (for example) you will still have tracking branches for both remotes. Whether you need or want this flexibility is up to you.
The release notes say this option was added specifically to support triangular workflows.
3 Comments
upstream because... well... it's upstream of my repository during those pulls. But the option is pushDefault, not pullDefault, so I used downstream as the name in the example. It's probably a better idea to call it defaultPushTarget ;)For Git 1.6.4 and later, set remote.<name>.pushurl with git config.
One might use this to pull using the read-only https: protocol and push using an ssh-based protocol.
Say origin's url (remote.origin.url) is https://git.example.com/some/repo.git. It is read-only, but you have write access through the ssh-based ‘URL’ [email protected]:some/repo.git. Run the following command to effect pushing over the ssh-based protocol:
git config remote.origin.pushurl [email protected]:some/repo.git
1 Comment
Thanks to MvanGeest for linking to the git 1.8.3 release notes. Those release notes say:
- A triangular "pull from one place, push to another place" workflow
is supported better by new
remote.pushdefault(overrides the "origin" thing) andbranch.*.pushremote(overrides thebranch.*.remote) configuration variables.
I use such a triangular workflow all the time for open-source contributions. For example: I have my own GitHub fork of llvm/llvm-project, and I want to keep my own main branch up-to-date with the upstream's main. So I frequently git pull upstream main; it would be convenient if I could just type git pull instead. But, I don't want any chance that I might fat-finger git push<return> instead of git push origin main<return> and accidentally push to the upstream project's repo before I intended to! So, before today, my .git/config looked like this:
[remote "origin"]
url = [email protected]:Quuxplusone/llvm-project
fetch = +refs/heads/*:refs/remotes/origin/*
[remote "upstream"]
url = [email protected]:llvm/llvm-project
fetch = +refs/heads/*:refs/remotes/upstream/*
[branch "main"]
merge = refs/heads/main
remote = origin
Based on the release note quoted above, I've just changed my local repo's .git/config to this:
[remote "origin"]
url = [email protected]:Quuxplusone/llvm-project
fetch = +refs/heads/*:refs/remotes/origin/*
[remote "upstream"]
url = [email protected]:llvm/llvm-project
fetch = +refs/heads/*:refs/remotes/upstream/*
[branch "main"]
merge = refs/heads/main
remote = upstream
pushremote = origin
Now I can do a simple git checkout main ; git pull to pull from upstream/main, and a simple git checkout main ; git push to push to origin/main. This is the "triangular workflow" I want.
2 Comments
git config --edit works, but FWIW, I just do nano .git/config. :) The config file for a given checkout/repo is always stored in a file named $ROOT_OF_MY_CHECKOUT/.git/config.From what I can gather from the git config man page, the upstream repo is:
- by default origin
- set by
branch.remote - always for both
git pull/fetchandgit pull
For a given branch, I don't see any way to have two separate remote by default.
2 Comments
git config remote... and git remote set-url...` answers, for a single branch or for an entire copy of a repo.origin for the current branch and push/pull to/from the matching branch name: git push --set-upstream origin <current_branch_name>user392887's answer is mostly correct, but:
You should prefer to use SSH. According to GitHub, "We strongly recommend using an SSH connection when interacting with GitHub. SSH keys are a way to identify trusted computers, without involving passwords."
Anyone using RHEL/CentOS 6 will be using git 1.7.1 by default, which supports
set-url.
So, the preferred solution for git 1.7.1. and later is:
git remote set-url --push origin [email protected]:username/somerepo.git
1 Comment
In case you also came here looking for a per-branch solution, here it is from the manual:
branch.<name>.pushRemoteWhen on branch , it overrides branch..remote for pushing. It also overrides remote.pushDefault for pushing from branch . When you pull from one place (e.g. your upstream) and push to another place (e.g. your own publishing repository), you would want to set remote.pushDefault to specify the remote to push to for all branches, and use this option to override it for a specific branch.
1 Comment
git config branch.my_branch.pushRemote my_push_remote