0

I have setup of my personal fork with:

master branch mirroring master branch in upstream repo and fork that is my main branch including my changes - and other feature/WIP/testing/testcase branches as usual.

master branch has a default configured remote origin/master where my repo lives and where I push update master.

But I am pulling from upstream remote.

How can I configure git so I can:

  • git push while on master branch and push to origin
  • git pull upstream while on master branch and pull from upstream/master (right now I need to do git pull upstream master)

Now git pull upstream is resulting in

Because this is not the default configured remote for your current branch

specify default branch for a non-default remote for pull may seem to be a duplicate but is not - "This does not answer the question, since this only works for the default remote (origin)!"

The same Specify default pull branch for a given remote - it allows setting only one

reducing activity
  • 1,985
  • 2
  • 36
  • 64
  • recently it got extra annoying as even `git pull upstream master` is not always working (as some repos decided that renaming `master` to `main` is a good use of everyone time and effective way to reduce amount of evil in the world). And `git pull upstream` `git pull upstream master` `git pull upstream main` is getting ridiculous. – reducing activity Aug 10 '21 at 08:54
  • If I understood correctly, `git pull upstream master` works as intended? – Val Berthe Aug 10 '21 at 10:01
  • @ValBerthe Yes. – reducing activity Aug 10 '21 at 10:12
  • Have you tried setting `default = current` in `[push]` and `[pull]` sections of your `.gitconfig` file ? – Val Berthe Aug 10 '21 at 10:20
  • @ValBerthe I just tried, it had no effect at all. I restarted command line window to ensure that new file version was loaded. – reducing activity Aug 10 '21 at 10:38
  • Won't help your use case, but I recommend *avoiding* the `git pull` command entirely. Run your own two-separate-commands. You then control the second command explicitly. Of course you're trying to avoid being explicit in the first place. But this *does* give you a *new option*, which I'll write up as an answer. – torek Aug 10 '21 at 17:23

2 Answers2

1

You can setup a remote so that it has different push and pull urls, e.g : git fetch origin would fetch from upstream, git push origin would push to fork,
however I don't know of a stock configuration option to specify two distinct branch names depending on the remote.

IMHO the easiest way would be to have the branches in your fork repo follow the same names as the upstream repo, so that you can push/pull to branch main in both cases.

One other generic option is : you can define aliases to run the appropriate commands.


Here is how to set up origin with two distinct urls :

# you can have distinct protocols for both urls :
git remote set-url origin https://upstream.repo
git remote set-url --push origin ssh://fork.repo

With your origin remote set up like this, if you set the upstream branch for your local master branch to origin/main :

git branch -u origin/main master

the default action for :

  • git push will be to push your local branch to main on fork
  • git pull will be to fetch anbd merge branch main from upstream
LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • > IMHO the easiest way would be to have the branches in your fork repo follow the same names as the upstream repo they do this (`master` is used for the main upstream branch - both in `upstream` and `origin` remotes) > so that you can push/pull to refs/heads/main in both cases. I am confused by that. So I would do `git pull refs/heads/main`? – reducing activity Aug 10 '21 at 11:17
  • No : set your branch remote to `origin/main` : `git branch -u origin/main`, now `git push` pushes to branch `main` on `fork`, and `git pull` fetches from branch `main` on `upstream` – LeGEC Aug 10 '21 at 11:40
  • `refs/heads/main` is what gets written in your config file – LeGEC Aug 10 '21 at 11:41
  • edited the answer, to hopefully make it clearer – LeGEC Aug 10 '21 at 12:23
0

If you're willing to ditch git pull entirely, here's how to automate the job.

Step 1: write yourself a new Git command. Let's call it up for now. This command is a simple script, which we'll see at the bottom of this posting. To make it an executable Git command, make it an executable script named git-up and put this somewhere such that your $PATH will find it. Running git up will now run your git-up script.

Step 2: in each repository in which you want this to happen, run:

git config branch.<name>.up origin/<other-name>

where <name> is the name of the branch you want your script to update, and origin/<other-name> is the remote-tracking name in your Git repository that will be updated by git fetch.

Step 3: replace git pull with git up.

Now for the script. We'll need it to be executable (remember to chmod +x!), and run by a shell such as /bin/sh or /bin/bash, so:

#! /bin/sh

The script should:

  • figure out which branch we are on right now
  • locate the branch.name.up setting: error if not set
  • run git fetch
  • run git merge $setting

These steps are accomplished with:

branch=$(git symbolic-ref --short HEAD) || exit
up=$(git config --get branch.$branch.up) || {
    echo "no name configured for git-up for $branch" 1>&2
    exit 1
}
git fetch && git merge $up

This is all untested, so test each part and make any necessary fixes.

torek
  • 448,244
  • 59
  • 642
  • 775