Appearance
Push and fetch
Push and fetch live in the History mode, next to the commits they move. The two arrows on the History toolbar open the Push and Fetch hubs; a dot on an arrow means there is something to do. There is no pull: fetch brings the remote's commits down, and Integrate in the Git mode brings them into your branch, so you see and choose each half.
A project has exactly one remote, origin, set from the URL it was cloned from. Its URL and credential are edited in the project's settings.
Push
The Push hub lists every branch with something to send, each saying why: Ahead of origin/main, Create origin/feature, Diverged from origin/main, or origin/feature exists on the remote and was never fetched. A branch that is only behind is not listed. A line under the title says when the remote was last checked. Nothing to push means every branch matches its remote.
Tap a branch for its review. The commits that are not on the remote are listed, each ticked; untick a commit to push only up to the one below it, since a push always sends a contiguous range from the oldest. The note under the list says how many go, and whether the branch gains an upstream. Tap Push. A Diverged row skips the review: the only thing the app can do for it is a force push, so it opens that screen directly; a tags row whose every tag needs force does the same.
Push rejected
A push is rejected when the remote branch has commits yours does not. The review then shows Push rejected with two ways forward: fetch the branch and bring it into yours from the Git mode, then push again; or Force push…, which overwrites the remote branch with yours.
Force push
A force push is always made "with lease": it succeeds only if the remote branch is still at the commit the app last saw, so nothing that arrived in between is overwritten unread. The screen shows the lease, the commits you would add, and under Remote commits to be replaced the commits that would be dropped, with their authors. The confirm counts them, and counts how many are by someone other than you.
The force screen never fetches. If the remote has moved since the last fetch, the button is replaced by Fetch origin/main, the stale parts are marked Outdated, and the screen re-reads the situation when you come back. A force push that would only remove commits, because your branch adds nothing, is refused outright.
Fetch
The Fetch hub lists what the remote has that you do not, grouped into Checked-out local branches, Other branches with changes, New branches on the remote, and Deleted on the remote, with a Tags row. Nothing to fetch means you have it all. The refresh button asks the remote again.
Tap a branch for its review. The incoming commits are listed and ticked; untick to fetch only up to a commit. A fetch moves your copy of the remote branch, origin/main, and never your own branches. To bring the commits into your branch afterwards, go to Integrate.
A name under New branches on the remote that you also have locally is pointed out: fetching creates the tracking branch and leaves yours alone.
A rewritten remote branch
If the remote branch was rewritten, by a force push from somewhere else, a fetch cannot continue from what you have. The review says the branch was rewritten and offers Replace…. The replace screen lists both sides of the trade, what is taken and what is dropped from your copy of the remote branch, and confirms before doing it. Your own branches are not affected.
Deleted on the remote
A branch the remote no longer has stays in your clone until you remove it. Its row opens a review that says whether any commits would become unreachable, and Remove takes it away.
Tags
The Tags row on each hub opens the tag review.
- Push tags lists tags to publish, move or delete, each ticked. A tag that exists on the remote at a different commit cannot go with the others. Publish the rest, then move it with Force push…, which reads the remote first and shows what each tag moves from and to.
- Fetch tags lists new and changed tags, then tags the remote deleted. For a tag that differs on the two sides, ticking it takes the remote's version; the delete glyph removes yours and leaves the remote's to fetch as a new tag.
Authentication
Push and fetch use the credential recorded in the project's settings, and only that one. If it is missing or was removed, the operation stops and names the project's settings as the place to fix it. See Authentication troubleshooting.
Common failures
- Push rejected: see above. The remote has commits you do not.
- Authentication failed: the credential was refused. Check it under Settings → Git Credentials.
- Can't reach the server: see Cloning troubleshooting.
- A protected branch: the host's rules refused the push, for example a branch that only takes pull requests. The message is the host's, shown as it came; the rule lives there.
