Mastering synchronization when collaborating in a team: telling git fetch and git pull apart, keeping history tidy with git pull --rebase, viewing remote branches, and deleting remote branches using git push origin --delete.

In episode 8 you successfully brought your local repository to GitHub and made your first push. But the real collaboration story is just beginning: when several developers work on the same project, the local and remote repositories will drift apart. You work on feature A, your teammate works on feature B — and then both need to come back in sync.
This episode equips you with four synchronization tools: git fetch, git pull, git push, and git pull --rebase. Used correctly, everyone can work in parallel without overwriting each other.
Since episode 8, your repository has two views that evolve independently: local and remote. Git does not sync them automatically — every synchronization step is an explicit command. This is why the terms "behind" and "ahead" appear when you check your status.
git statusOutput like "Your branch is behind 'origin/main' by 2 commits" tells you the remote has 2 commits you do not have yet. How do you pull them down? Two ways: fetch and pull.
git fetch origin takes the latest commit history from the remote into the local remote references (origin/main), but does not touch your working branch or working directory at all. It is like downloading the latest news without changing your life in the slightest.
git fetch originAfter the fetch, you can compare first: git log --oneline main..origin/main shows the commits that only exist on the remote. Only when you are confident do you merge manually.
Tip
git fetch is a safe move that never changes your working directory. When you are unsure about the remote state, run fetch first and observe the difference — this habit will save you from many surprises.
git pull origin main is a shortcut: fetch first, then merge. It takes the remote commits and immediately merges them into your active local branch. In many cases this is exactly what you need, with one caveat: automatic merges can produce an extra commit.
git pull origin mainBecause pull is fetch + merge, if changes on both sides overlap, you may run into conflicts — the resolution techniques are exactly the same as in episode 7.
The small problem with a plain git pull: when you have local commits and the remote also has new commits, Git creates a merge commit on every synchronization. In a team that pushes frequently, history fills up with noisy merge "knots".
The modern solution: git pull --rebase origin main. This command pulls the remote commits, then reapplies your local commits on top of them — the result is a linear history, as if all changes happened in sequence.
git pull --rebase origin mainWarning
Rebase only rewrites local commits that have not been published. As long as no one else has pulled your commits, git pull --rebase is safe and is the modern team standard. Once it succeeds, continue with a plain git push.
Once the upstream is registered (episode 8), the command is simply git pull --rebase without mentioning origin main.
Branches on the remote are recorded in Git as origin/branch-name. To map them out:
git branch -r origin/main
origin/fitur-rebrandgit branch -r shows only remote branches; git branch -a (all) shows local and remote branches together, with remote references marked remotes/origin/....
References like origin/main are called remote-tracking branches: local versions of the remote state as of your last fetch. That is why they are not automatically up to date — refresh them anytime with git fetch origin.
Just as local branches are deleted after being merged, branches on the remote also need cleaning up. The modern way is to send a delete command via push:
git push origin --delete fitur-rebrandgit push origin --delete <branch-name> deletes that branch on the remote and also removes the origin/fitur-rebrand reference from your local repository. After that, also delete the local branch with git branch -d fitur-rebrand if it is no longer needed.
Note
GitHub automatically offers "Delete branch" after a Pull Request is merged. But with this CLI approach you can clean up remote branches at any time — it is also useful for branches that were never merged.
Combined, the tidy daily workflow popular with modern teams is: pull in remote changes, tidy up your local commits on top of them, then push back.
git fetch origin
git pull --rebase origin main
# kerjakan fitur, beberapa commit lokal
git pushThis sequence ensures you always work on top of the latest version, avoids noisy merge commits, and pushes changes only after the local history is clean. When a push is rejected because the remote moved again, simply repeat git pull --rebase followed by git push — never use force push to overwrite someone else's work.
Warning
If git push is rejected with a "non-fast-forward" message, that is Git protecting you. Do not force it with --force. Sync first with git pull --rebase, then push again.
Key points of this episode:
git fetch pulls history without merging; git pull is fetch plus merge.git pull --rebase origin main keeps history linear by reapplying your local commits.git branch -r and git branch -a map out remote branches.git push origin --delete <branch-name> deletes a branch from the remote.Now you can sync with your team. In episode 10, we turn this collection of commands into rules of the game: four Git collaboration workflows — from Centralized, Feature Branch, and Gitflow, to Trunk-Based Development, the favorite of the modern CI/CD era. See you there!