30.1.12.5 Commands to see all outstanding changes

C-x v T =

Display diffs of changes to the VC fileset since the merge base of this branch and its upstream counterpart (vc-diff-outstanding).

C-x v T D

Display a diff of all changes since the merge base of this branch and its upstream counterpart (vc-root-diff-outstanding).

C-x v T l

Display log messages for changes to the VC fileset since the merge base of this branch and its upstream counterpart (vc-log-outstanding).

C-x v T L

Display log messages for all changes since the merge base of this branch and its upstream counterpart (vc-root-log-outstanding).

For decentralized version control systems (see Decentralized vs Centralized Repositories), these commands provide specialized versions of C-x v M L and C-x v M D (see see Merge Bases) which also take into account the state of upstream repositories. These commands are useful both when working on a single branch and when developing features on a separate branch (see Version Control Branches). These two cases are conceptually distinct, and so we will introduce them separately.

First, consider working on a single branch. Outstanding changes are those which you haven’t yet pushed upstream. This includes both unpushed commits and uncommitted changes in your working tree. In many cases the reason these changes are not pushed yet is that they are not finished: the changes committed so far don’t make sense in isolation.

Type C-x v T D (vc-root-diff-outstanding) to display a summary of all these changes, committed and uncommitted. This summary is in the form of a diff of what committing and pushing (see Pulling/Pushing Changes into/from a Branch) all these changes would do to the upstream repository. You can use C-x v T = (vc-diff-outstanding) instead to limit the display of changes to the current VC fileset. (The difference between C-x v T D and C-x v T = is like the difference between C-x v D and C-x v = (see Examining And Comparing Old Revisions).)21

Type C-x v T L (vc-root-log-outstanding) to display a summary of the same changes in the form of a revision log; this does not include uncommitted changes. You can use C-x v T l (vc-log-outstanding) instead to limit the display of changes to the current VC fileset.

Second, consider developing a feature on a separate branch. Call this the topic branch,22 and call the branch from which the topic branch was originally created the trunk or development trunk.

In this case, outstanding changes is a more specific notion than just unpushed and uncommitted changes on the topic branch. You’re not finished sharing changes with your collaborators until they have been merged into the trunk, and pushed. Therefore, in this example, outstanding changes are those which haven’t yet been integrated into the upstream repository’s development trunk. That means committed changes on the topic branch that haven’t yet been merged into the trunk, plus uncommitted changes.

When the current branch is a topic branch and you type C-x v T D, Emacs displays a summary of all the changes that are outstanding against the trunk to which the current branch will be merged. This summary is in the form of a diff of what committing and pushing all the changes, and subsequently merging the topic branch, would do to the trunk. As above, you can use C-x v T = instead to limit the display of changes to the current VC fileset. C-x v T L and C-x v T l show the corresponding revision logs, excluding uncommitted changes as above.

This functionality relies on Emacs correctly detecting whether the current branch is a trunk or a topic branch, and in the latter case, correctly determining the branch to which the topic branch will eventually be merged. If the autodetection doesn’t produce the right results, there are several options to tweak and override it.

The variables vc-trunk-branch-regexps and vc-topic-branch-regexps contain lists of regular expressions matching the names of branches that should always be considered trunk and topic branches, respectively. You can also specify prefix arguments to C-x v T …. Here is a summary of how to use these controls:

  1. If the problem is that Emacs thinks your topic branch is a trunk, you can add either its name, or a regular expression matching its name (see Syntax of Regular Expressions), to the vc-topic-branch-regexps variable. There are a few special kinds of value to simplify common use cases:
    • If an element contains no characters that are special in regular expressions, then the regular expression is implictly anchored at both ends, i.e., it matches only a branch with exactly that name.
    • If the first element of vc-topic-branch-regexps is the symbol not, then the meaning of vc-topic-branch-regexps is inverted, in that Emacs treats all branches whose names don’t match any element of vc-topic-branch-regexps to be topic branches.
    • If instead of a list of regular expressions the vc-topic-branch-regexps variable has the special value t, then Emacs treats as a topic branch any branch that the vc-trunk-branch-regexps variable doesn’t positively identify as a trunk.

    See Per-Directory Local Variables, regarding how to specify values of vc-topic-branch-regexps and vc-trunk-branch-regexps for a single VC repository.

  2. If the problem is that Emacs thinks your trunk is a topic branch, you can add either its name, or a regular expression matching its name, to the vc-trunk-branch-regexps variable. This works just like vc-topic-branch-regexps with the same special values we just described. E.g., if the value of vc-trunk-branch-regexps is t, Emacs treats as a trunk any branch that the vc-topic-branch-regexps variable doesn’t identify as a topic branch.
  3. Supply a double prefix argument, i.e. C-u C-u C-x v T …, and Emacs will treat the current branch as a trunk, no matter what. This is useful when you simply want to obtain a diff of all outgoing changes (see VC Change Log) plus uncommitted changes.
  4. Finally, you can take full manual control by supplying a single prefix argument, i.e. C-u C-x v T …. Emacs will prompt you for the outgoing base, which is the upstream location for which the changes are destined once they are no longer outstanding.

    To treat the current branch as a trunk specify a reference to the upstream version of the current branch, to which you and your collaborators push finished work. To treat the current branch as a topic branch specify a reference to the upstream version of the trunk to which the topic branch will later be merged.

    Exactly how to specify a reference to the upstream version of a branch depends on the version control system in use. For example, with Git, to refer to the upstream version of a branch foo, you would supply origin/foo. So if foo is the current branch then you would enter an outgoing base of origin/foo to treat foo as a trunk, or an outgoing base of origin/bar to treat foo as a topic branch which will later be merged into a trunk named bar.

    If there is a default option, it is what Emacs thinks you need to enter in order to treat the current branch as a topic branch. If there is no default, then entering nothing at the prompt means to treat the current branch as a trunk.


Footnotes

(21)

Another point of comparison is that these commands are like C-x v O = (vc-fileset-diff-outgoing) and C-x v O D (vc-root-diff-outgoing) except that they include uncommitted changes in the reported diffs. Like those other commands, you can use a prefix argument to specify a particular upstream location.

(22)

What we mean by a topic branch is any shorter-lived branch used for work which will later be merged into a longer-lived branch. Topic branches are sometimes called “feature branches”. It is also common for the term “feature branch” to be reserved for a particular kind of topic branch, one that another branch or other branches are repeatedly merged into.