The upstream branch of some local branch is the branch into which the
commits on that local branch should eventually be merged, usually
something like origin/master. For the master branch itself the
upstream branch and the branch it is being pushed to, are usually the
same remote branch. But for a feature branch the upstream branch and
the branch it is being pushed to should differ.
The commits on feature branches too should eventually end up in a
remote branch such as origin/master or origin/maint. Such a branch
should therefore be used as the upstream. But feature branches
shouldn’t be pushed directly to such branches. Instead a feature
branch my-feature is usually pushed to my-fork/my-feature or if you
are a contributor origin/my-feature. After the new feature has been
reviewed, the maintainer merges the feature into master. And finally
master (not my-feature itself) is pushed to origin/master.
But new features seldom are perfect on the first try, and so feature branches usually have to be reviewed, improved, and re-pushed several times. Pushing should therefore be easy to do, and for that reason many Git users have concluded that it is best to use the remote branch to which the local feature branch is being pushed as its upstream.
But luckily Git has long ago gained support for a push-remote which
can be configured separately from the upstream branch, using the
variables branch.<name>.pushRemote and remote.pushDefault. So we no
longer have to choose which of the two remotes should be used as "the
remote".
Each of the fetching, pulling, and pushing transient commands features
three suffix commands that act on the current branch and some other
branch. Of these, p is bound to a command which acts on the
push-remote, u is bound to a command which acts on the upstream, and e
is bound to a command which acts on any other branch. The status
buffer shows unpushed and unpulled commits for both the push-remote
and the upstream.
It’s fairly simple to configure these two remotes. The values of all
the variables that are related to fetching, pulling, and pushing (as
well as some other branch-related variables) can be inspected and
changed using the command magit-branch-configure, which is available
from many transient prefix commands that deal with branches. It is
also possible to set the push-remote or upstream while pushing (see
Pushing).
The transient prefix command magit-branch is used to create and
checkout branches, and to make changes to existing branches. It is
not used to fetch, pull, merge, rebase, or push branches, i.e., this
command deals with branches themselves, not with the commits reachable
from them. Those features are available from separate transient
commands.
magit-branch) ¶This transient prefix command binds the following suffix commands and displays them in a temporary buffer until a suffix is invoked.
By default it also binds and displays the values of some branch-related Git variables and allows changing their values.
This option controls whether the transient command magit-branch can
be used to directly change the values of Git variables. This defaults
to t (to avoid changing key bindings). When set to nil, then no
variables are displayed by that transient command, and its suffix
command magit-branch-configure has to be used instead to view and
change branch related variables.
magit-branch-configure) ¶This transient prefix command binds commands that set the value of branch-related variables and displays them in a temporary buffer until the transient is exited.
With a prefix argument, this command always prompts for a branch.
Without a prefix argument this depends on whether it was invoked as
a suffix of magit-branch and on the magit-branch-direct-configure
option. If magit-branch already displays the variables for the
current branch, then it isn’t useful to invoke another transient
that displays them for the same branch. In that case this command
prompts for a branch.
The variables are described in Branch Git Variables.
magit-checkout) ¶Checkout a revision read in the minibuffer and defaulting to the
branch or arbitrary revision at point. If the revision is a local
branch then that becomes the current branch. If it is something
else then HEAD becomes detached. Checkout fails if the working tree
or the staging area contain changes.
magit-branch-create) ¶Create a new branch. The user is asked for a branch or arbitrary revision to use as the starting point of the new branch. When a branch name is provided, then that becomes the upstream branch of the new branch. The name of the new branch is also read in the minibuffer.
Also see option magit-branch-prefer-remote-upstream.
magit-branch-and-checkout) ¶This command creates a new branch like magit-branch-create, but then
also checks it out.
Also see option magit-branch-prefer-remote-upstream.
magit-branch-checkout) ¶This command checks out an existing or new local branch. It reads a branch name from the user offering all local branches and a subset of remote branches as candidates. Remote branches for which a local branch by the same name exists are omitted from the list of candidates. The user can also enter a completely new branch name.
In the latter two cases the upstream is also set. Whether it is set
to the chosen starting point or something else depends on the value
of magit-branch-adjust-remote-upstream-alist.
magit-branch-spinoff) ¶This command creates and checks out a new branch starting at and tracking the current branch. That branch in turn is reset to the last commit it shares with its upstream. If the current branch has no upstream or no unpushed commits, then the new branch is created anyway and the previously current branch is not touched.
This is useful to create a feature branch after work has already begun on the old branch (likely but not necessarily "master").
If the current branch is a member of the value of option
magit-branch-prefer-remote-upstream (which see), then the current
branch will be used as the starting point as usual, but the upstream
of the starting-point may be used as the upstream of the new branch,
instead of the starting-point itself.
If optional FROM is non-nil, then the source branch is reset
to FROM~, instead of to the last commit it shares with its
upstream. Interactively, FROM is only ever non-nil, if the
region selects some commits, and among those commits, FROM is
the commit that is the fewest commits ahead of the source
branch.
The commit at the other end of the selection actually does not
matter, all commits between FROM and HEAD are moved to the new
branch. If FROM is not reachable from HEAD or is reachable from the
source branch’s upstream, then an error is raised.
magit-branch-spinout) ¶This command behaves like magit-branch-spinoff, except that it does
not change the current branch. If there are any uncommitted changes,
then it behaves exactly like magit-branch-spinoff.
magit-branch-reset) ¶This command resets a branch, defaulting to the branch at point, to the tip of another branch or any other commit.
When the branch being reset is the current branch, then a hard reset is performed. If there are any uncommitted changes, then the user has to confirm the reset because those changes would be lost.
This is useful when you have started work on a feature branch but realize it’s all crap and want to start over.
When resetting to another branch and a prefix argument is used, then the target branch is set as the upstream of the branch that is being reset.
magit-branch-delete) ¶Delete one or multiple branches. If the region marks multiple branches, then offer to delete those. Otherwise, prompt for a single branch to be deleted, defaulting to the branch at point.
Require confirmation when deleting branches is dangerous in some
way. Option magit-no-confirm can be customized to not require
confirmation in certain cases. See its docstring to learn why
confirmation is required by default in certain cases or if a
prompt is confusing.
magit-branch-rename) ¶Rename a branch. The branch and the new name are read in the minibuffer. With prefix argument the branch is renamed even if that name conflicts with an existing branch.
When creating a branch, whether to read the upstream branch before
the name of the branch that is to be created. The default is t,
and I recommend you leave it at that.
This option specifies whether remote upstreams are favored over local upstreams when creating new branches.
When a new branch is created, then the branch, commit, or stash at point is suggested as the starting point of the new branch, or if there is no such revision at point the current branch. In either case the user may choose another starting point.
If the chosen starting point is a branch, then it may also be set as the upstream of the new branch, depending on the value of the Git variable ‘branch.autoSetupMerge’. By default this is done for remote branches, but not for local branches.
You might prefer to always use some remote branch as upstream. If the chosen starting point is (1) a local branch, (2) whose name matches a member of the value of this option, (3) the upstream of that local branch is a remote branch with the same name, and (4) that remote branch can be fast-forwarded to the local branch, then the chosen branch is used as starting point, but its own upstream is used as the upstream of the new branch.
Members of this option’s value are treated as branch names that
have to match exactly unless they contain a character that makes
them invalid as a branch name. Recommended characters to use
to trigger interpretation as a regexp are "*" and "^". Some
other characters which you might expect to be invalid, actually
are not, e.g., ".+$" are all perfectly valid. More precisely,
if git check-ref-format --branch STRING exits with a non-zero
status, then treat STRING as a regexp.
Assuming the chosen branch matches these conditions you would end up with with e.g.:
feature --upstream--> origin/master
instead of
feature --upstream--> master --upstream--> origin/master
Which you prefer is a matter of personal preference. If you do
prefer the former, then you should add branches such as master,
next, and maint to the value of this options.
The value of this option is an alist of branches to be used as the upstream when branching a remote branch.
When creating a local branch from an ephemeral branch located on a remote, e.g., a feature or hotfix branch, then that remote branch should usually not be used as the upstream branch, since the push-remote already allows accessing it and having both the upstream and the push-remote reference the same related branch would be wasteful. Instead a branch like "maint" or "master" should be used as the upstream.
This option allows specifying the branch that should be used as the
upstream when branching certain remote branches. The value is an
alist of the form ((UPSTREAM . RULE)...). The first matching
element is used, the following elements are ignored.
UPSTREAM is the branch to be used as the upstream for branches specified by RULE. It can be a local or a remote branch.
RULE can either be a regular expression, matching branches whose upstream should be the one specified by UPSTREAM. Or it can be a list of the only branches that should not use UPSTREAM; all other branches will. Matching is done after stripping the remote part of the name of the branch that is being branched from.
If you use a finite set of non-ephemeral branches across all your repositories, then you might use something like:
(("origin/master" . ("master" "next" "maint")))
Or if the names of all your ephemeral branches contain a slash, at least in some repositories, then a good value could be:
(("origin/master" . "/"))
Of course you can also fine-tune:
(("origin/maint" . "\\`hotfix/")
("origin/master" . "\\`feature/"))
UPSTREAM can be a local branch:
(("master" . ("master" "next" "maint")))
Because the main branch is no longer almost always named "master" you should also account for other common names:
(("main" . ("main" "master" "next" "maint"))
("master" . ("main" "master" "next" "maint")))
This command creates and checks out a new orphan branch with contents from a given revision.
This command is a hybrid between magit-checkout and
magit-branch-and-checkout and is intended as a replacement for the
former in magit-branch.
It first asks the user for an existing branch or revision. If the
user input actually can be resolved as a branch or revision, then it
checks that out, just like magit-checkout would.
Otherwise it creates and checks out a new branch using the input as
its name. Before doing so it reads the starting-point for the new
branch. This is similar to what magit-branch-and-checkout does.
To use this command instead of magit-checkout add this to your init
file:
(transient-replace-suffix 'magit-branch 'magit-checkout
'("b" "dwim" magit-branch-or-checkout))
These variables can be set from the transient prefix command
magit-branch-configure. By default they can also be set from
magit-branch. See Branch Commands.
Together with branch.NAME.remote this variable defines the upstream
branch of the local branch named NAME. The value of this variable
is the full reference of the upstream branch.
Together with branch.NAME.merge this variable defines the upstream
branch of the local branch named NAME. The value of this variable
is the name of the upstream remote.
This variable controls whether pulling into the branch named NAME is done by rebasing or by merging the fetched branch.
true then pulling is done by rebasing.
false then pulling is done by merging.
pull.rebase is used. The default
of that variable is false.
This variable specifies the remote that the branch named NAME is usually pushed to. The value has to be the name of an existing remote.
It is not possible to specify the name of branch to push the local branch to. The name of the remote branch is always the same as the name of the local branch.
If this variable is undefined but remote.pushDefault is defined,
then the value of the latter is used. By default remote.pushDefault
is undefined.
This variable can be used to describe the branch named NAME. That description is used, e.g., when turning the branch into a series of patches.
The following variables specify defaults which are used if the above branch-specific variables are not set.
This variable specifies whether pulling is done by rebasing or by
merging. It can be overwritten using branch.NAME.rebase.
true then pulling is done by rebasing.
false (the default) then pulling is done by merging.
Since it is never a good idea to merge the upstream branch into a
feature or hotfix branch and most branches are such branches, you
should consider setting this to true, and branch.master.rebase to
false.
This variable specifies what remote the local branches are usually
pushed to. This can be overwritten per branch using
branch.NAME.pushRemote.
The following variables are used during the creation of a branch and control whether the various branch-specific variables are automatically set at this time.
This variable specifies under what circumstances creating a branch
NAME should result in the variables branch.NAME.merge and
branch.NAME.remote being set according to the starting point used to
create the branch. If the starting point isn’t a branch, then these
variables are never set.
always then the variables are set regardless of whether the
starting point is a local or a remote branch.
true (the default) then the variables are set when the starting
point is a remote branch, but not when it is a local branch.
false then the variables are never set.
This variable specifies whether creating a branch NAME should result
in the variable branch.NAME.rebase being set to true.
always then the variable is set regardless of whether the
starting point is a local or a remote branch.
local then the variable are set when the starting point is a
local branch, but not when it is a remote branch.
remote then the variable are set when the starting point is a
remote branch, but not when it is a local branch.
never (the default) then the variable is never set.
Note that the respective commands always change the repository-local values. If you want to change the global value, which is used when the local value is undefined, then you have to do so on the command line, e.g.:
git config --global remote.autoSetupMerge always
For more information about these variables you should also see the git-config(1) manpage. Also see the git-branch(1) manpage. , the git-checkout(1) manpage. and Pushing.
This option controls whether commands that read a branch from the user and then set it as the upstream branch, offer a local or a remote branch as default completion candidate, when they have the choice.
This affects all commands that use magit-read-upstream-branch or
magit-read-starting-point, which includes all commands that change
the upstream and many which create new branches.
These commands are not available from the transient magit-branch by
default.
This command shelves a branch. This is done by deleting the branch, and creating a new reference "refs/shelved/BRANCH-NAME" pointing at the same commit as the branch pointed at. If the deleted branch had a reflog, then that is preserved as the reflog of the new reference.
This is useful if you want to move a branch out of sight, but are not ready to completely discard it yet.
This command unshelves a branch that was previously shelved using
magit-branch-shelve. This is done by deleting the reference
"refs/shelved/BRANCH-NAME" and creating a branch "BRANCH-NAME"
pointing at the same commit as the deleted reference pointed at.
If the deleted reference had a reflog, then that is restored as
the reflog of the branch.