Working with remotes is everyday work in every team – but many people only use git pull and have a vague idea of what actually happens. Tracking refs, the difference between fetch and pull, when to use --force-with-lease instead of --force, and how remote branches actually work is knowledge that saves you from irreversible mistakes.
Remote – configure and manage
# List remote repositories git remote -v # Add remote git remote add upstream https://github.com/magento/magento2.git # Change URL git remote set-url origin git@github.com:company/project.git # Remove remote git remote remove upstream # Fetch information about all remotes git remote update
Fetch – safe update
Fetch downloads changes from remote and updates tracking refs (origin/main, origin/develop) without touching local branches. Always safe.
# Fetch changes from all remotes git fetch --all # Fetch a specific remote git fetch origin # Fetch a specific branch git fetch origin main # After fetch check what is new git log main..origin/main --oneline git diff main origin/main # List remote branches git branch -r git branch -a # local + remote
Pull – fetch + merge in one
# Standard pull (merge) git pull origin main # Pull with rebase instead of merge git pull --rebase origin main # Set rebase as the default pull strategy git config --global pull.rebase true # Check what will be merged before pull git fetch origin git log HEAD..origin/main --oneline
Push and force-with-lease
# Regular push git push origin main # Push new branch and set tracking git push -u origin feature/order-export # Force push (DANGEROUS - overwrites remote history) git push --force origin main # never on shared branches! # Force-with-lease (safe equivalent of --force) # Aborts if someone else pushed changes since last fetch git push --force-with-lease origin main # When is force-with-lease needed? # After git rebase -i on a feature branch - SHAs have changed # After git commit --amend on a feature branch # Never on main/develop/release!
Tracking branches
# Check tracking for each branch git branch -vv # * main a3d5e2f [origin/main] Add product export # feature/cart b4c6d7e [origin/feature/cart: ahead 2] Fix total # Set tracking manually git branch --set-upstream-to=origin/main main # Create local branch tracking remote git checkout --track origin/feature/new-api # or shorter: git checkout feature/new-api # Git automatically finds origin/feature/new-api
Working with multiple remotes
# Typical fork setup: origin = your fork, upstream = original git remote add origin git@github.com:henryk/magento2-module.git git remote add upstream git@github.com:company/magento2-module.git # Update your fork from upstream git fetch upstream git checkout main git rebase upstream/main git push origin main # Check if your branch is current with upstream git log HEAD..upstream/main --oneline
Cleaning stale tracking refs
# Remove tracking refs for branches deleted on remote git fetch --prune git remote prune origin # Set automatic pruning git config --global fetch.prune true # Display stale tracking refs git remote prune origin --dry-run
Summary
Fetch is safe – it only updates tracking refs. Pull is fetch + merge, with a rebase option. Force-with-lease is the only acceptable form of force push on feature branches after rebase. Tracking branches connect local branches with their remote counterparts and enable git push without specifying remote/branch. Next post: team workflow – Git Flow, trunk-based development and code review.
