If you are using a fast-forward merge, then you can simply use
git fetch <remote> <sourceBranch>:<destinationBranch>
Examples:
# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master
# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo
And also, you can work on this using git fetch.
This way is a little safer than just force-moving the branch reference since git fetch will automatically prevent accidental non-fast-forwards as long as you don't use + in the refspec.
Sometimes, you cannot merge a branch B into branch A without checking out A first if it would result in a non-fast-forward merge.
This is because a working copy is needed to resolve any potential conflicts.
To do this without checking out a branch first, you can use
git fetch with a refspec.
git fetch upstream master:master
You'll probably want to make an alias for it in your git configuration file, like this one:
[alias]
sync = !sh -c 'git checkout --quiet HEAD; git fetch upstream master:master; git checkout --quiet -'
This will help you to push the changes without any checkouts.