Skip to content

Push and fetch

Once you have local commits (Committing changes), push sends them to a remote. Fetch brings down whatever the remote has that you don't have yet.

The Git mode in a project workspace exposes both as buttons. The status strip at the bottom shows whether you're ahead, behind, or diverged from the tracked remote branch.

Push

Tap Push in the Git mode. Hachicode pushes your current branch to its tracked remote branch (set up automatically when you cloned).

What happens under the hood:

  1. The app authenticates using the project's selected credential (set up at clone time; reconfigurable in Project settings → Sync).
  2. Git's standard push protocol runs against the remote.
  3. The remote either accepts the push (fast-forward) or rejects it (non-fast-forward — see below).

After a successful push, your local branch and the remote tracking branch are in sync; the status strip drops "ahead by N" to clean.

Authentication on push

Same credential model as the clone screen. If the credential is missing, expired, or the wrong shape for the URL transport, push fails with an auth error. See Authentication troubleshooting.

The credential is chosen automatically by host match. To change it for a specific project, go to Project settings → Sync → Edit remote.

Fetch

Tap Fetch in the Git mode. Hachicode runs git fetch against the project's remote, bringing down commits and refs without modifying your working tree.

After a fetch:

  • The status strip updates to reflect any new "behind by N" count.
  • Remote-tracking branches (origin/main etc.) advance to wherever the remote has them.
  • Your local branches don't move — fetch is read-only with respect to your local state.

Fetch vs pull

Hachicode does fetch, not pull. There's no in-app git pull (which is "fetch + merge"). The "merge" step has to happen elsewhere — see the next section.

The "no in-app merge conflicts" rule

This is the single most distinctive thing about hachicode's git surface. Conflict resolution UI is intentionally absent.

What this means in practice:

  • If a push is rejected because the remote has commits you don't have ("non-fast-forward"), hachicode reports the divergence and asks you to fetch first, then resolve the divergence on a laptop before pushing again.
  • If a fetch brings down commits that would conflict with your local commits on the same branch, hachicode shows the divergence but doesn't offer an in-app merge or rebase.

Why? Because conflict resolution on a 9.7" tablet, even with a keyboard, is genuinely worse than on a laptop. Half-implementing it would create a footgun: users would muddle through merges they'd be better off doing elsewhere. The product call is "if you hit a conflict, hachicode tells you so clearly and gets out of the way."

Practical workflow when you hit divergence:

  1. Push from hachicode → rejected with "diverged from remote."
  2. Open the project on a laptop (or any environment with git CLI access).
  3. git fetch && git rebase origin/main (or merge, your call).
  4. Resolve any conflicts in your usual tools.
  5. Push from there.
  6. Back in hachicode, fetch — your local branch now matches the remote and the divergence indicator clears.

If you don't have laptop access, you can still get the data out via the project's remote — push to a backup branch, sync that branch on another device, resolve there.

Working with multiple remotes

By default a clone has one remote (origin). To add more:

  • Project settings → Sync → Add remote

Each remote has its own URL and credential. The Push button in Git mode pushes to the currently tracked remote; to push to a different one, change the tracking in Project settings → Sync → Edit tracking first.

This is heavy machinery and most users won't need it. The multi-remote story exists for cases like pushing to a fork plus the upstream, or syncing the same project across hosts.

Force-push policy

Hachicode does not offer force-push. The push button only ever does a regular (fast-forward-only) push. If you've rewritten history locally and need to force-push, do it from a laptop.

This is part of the same "no in-app rewrite or conflict resolution" stance — force-push is rewrite-history. Keeping it out of the app avoids accidental damage to shared branches.

Common push failures

  • "Updates were rejected" / "Non-fast-forward" — the remote has commits you don't have. Fetch first; resolve elsewhere; come back.
  • Authentication failed — credential is wrong, expired, or the wrong transport. See Authentication troubleshooting.
  • Network unreachable — same diagnostics as Cloning troubleshooting → Host unreachable.
  • Protected branch / push policy on the remote — the host's branch protection rules rejected the push (e.g. requires PR, requires signed commits, etc.). Read the remote's error message; the policy lives on the host, not in the app.

See also

Last updated: