VS Code: What is the difference between push and publish

From the docs:

If there is no upstream branch configured and the Git repository has remotes set up, the Publish action is enabled. This will let you publish the current branch to a remote.

So I'd expect that if you have an upstream branch configured, you would be able to Push (i.e. push directly to the configured upstream branch) and if you have no upstream branch configured you are only allowed to Publish (i.e. select a remote and branch to push at).


After checking the source code of Visual Studio Code.

Push

Push the current branch to the default remote upstream

public run(context?: any):Promise {
    return this.gitService.push() // ... removed for brevity        
}

Active when:

There is UPSTREAM and recent push/pulls (ahead)

if (!HEAD || !HEAD.name || !HEAD.upstream) {
    return false;
}

if (!HEAD.ahead) { // no commits to pull or push
    return false;
}

Publish

Allows you to choose which remote you want to push to.

public run(context?: any):Promise {
        const model = this.gitService.getModel();
        const remotes = model.getRemotes();
        const branchName = model.getHEAD().name;
        let promise: TPromise<string>;

        if (remotes.length === 1) {
            const remoteName = remotes[0].name;
            promise = TPromise.as(result ? remoteName : null);
        } else {
            // open the option picker            
            promise = this.quickOpenService.pick(picks, { placeHolder })
                .then(pick => pick && pick.label);
        }

        return promise
            .then(remote => remote && this.gitService.push(remote, branchName, { setUpstream: true }))            
}

Active when

There is NO UPSTREAM and off course remote branches are set.

if (model.getRemotes().length === 0) {
    return false;
}

if (!HEAD || !HEAD.name || HEAD.upstream) {
    return false;
}

Publish will push the branch to the remote AND set up the local branch to track the remote branch.

Push just pushes and doesn't set upstream tracking information (ie: branch.<name>.remote and branch.<name>.merge configuration).

When there is no upstream branch, and push.default = simple (the git default), Push will raise a dialog to suggest a publish.