Master the essential commands for collaborating with others through remote Git repositories.
A remote repository is a version of your project that is hosted on the internet or network somewhere. Git's distributed nature allows multiple developers to work independently and then share their changes.
graph LR
A["Local Repo A (Developer A)"] <--> B["Remote Repo (Server)"]
B <--> C["Local Repo B (Developer B)"]
- Fetch: Download objects and refs from remote without integrating them
- Pull: Fetch + integrate remote changes into your current branch
- Push: Upload your local branch commits to a remote repository
- Clone: Create a local copy of a remote repository
Understanding the relationship between your local and remote branches:
gitGraph
commit id: "Initial commit"
commit id: "Second commit"
branch origin/main
checkout origin/main
commit id: "Third commit"
checkout main
commit id: "Fourth commit" type: HIGHLIGHT tag: "HEAD"
commit id: "Fifth commit"
The diagram above shows:
- Your local branch
mainhas two commits ahead of the remote - The remote tracking branch
origin/mainrepresents your last known state of the remote HEADpoints to your current position on the local main branch
After pushing:
gitGraph
commit id: "Initial commit"
commit id: "Second commit"
branch origin/main
checkout main
commit id: "Third commit"
checkout origin/main
commit id: "Third commit"
checkout main
commit id: "Fourth commit"
commit id: "Fifth commit" type: HIGHLIGHT tag: "HEAD"
checkout origin/main
commit id: "Fourth commit"
commit id: "Fifth commit"
After pushing, the remote branch is updated with your local commits, and your local tracking reference to origin/main is updated to match.
Connect your local repository to a remote repository:
git remote add origin https://github.com/username/repo.gitgit remote add upstream https://github.com/original-owner/repo.gitInspect your remote connections:
git remotegit remote -vgit remote show originChange the name of a remote:
git remote rename origin destinationDelete a remote connection:
git remote remove upstreamMultiple remotes are common in open source projects:
git remote add upstream https://github.com/original-owner/repo.gitgit fetch upstreamgit merge upstream/main💡 Tip: In a fork workflow, "origin" typically points to your fork and "upstream" points to the original repository.
Download objects and refs from a remote without merging:
git fetch origingit fetch upstreamFetch only certain branches from remote:
git fetch origin feature-branchgit fetch origin main develop feature-xClean up deleted remote branches:
git fetch --prunegit fetch -pgit config --global fetch.prune trueFetch updates from all configured remotes:
git fetch --all💡 Tip: Fetching is a safe operation that doesn't change your working directory or current branch.
Fetch from a remote and integrate changes into the current branch:
git pullgit pull origin mainPull using rebase instead of merge:
git pull --rebasegit pull --rebase origin feature-branchgit config --global pull.rebase trueCustomize pull behavior:
git pull --verbosegit pull --no-commitgit pull --ff-onlygit pull is essentially a combination of git fetch and git merge (or git rebase with --rebase):
git fetch origingit merge origin/mainThese two steps combined are equivalent to:
git pull origin main
⚠️ Warning:git pullcan lead to unexpected merge conflicts. For more control, some developers prefer using fetch and merge as separate steps.
Upload local branch commits to remote repository:
git pushgit push origin mainSelect which remote to push to:
git push upstream maingit remote | xargs -L1 git pushConfigure branch tracking during push:
git push -u origin feature-branchOr:
git push --set-upstream origin feature-branchgit branch -vvOverride remote branch history (use with caution):
git push --forcegit push --force-with-lease
⚠️ Warning: Force pushing rewrites history on the remote. Never force push to shared branches unless you're absolutely certain it won't affect other team members.
By default, git push doesn't transfer tags:
git push origin v1.0.0git push origin --tagsgit push origin --follow-tagsView branches in remote repositories:
git branch -rgit branch -agit branch -rvCreate a branch on the remote repository:
git push origin local-branchgit push origin local-branch:remote-branch-nameSet up local branches to track remote branches:
git checkout -b feature-branch origin/feature-branchgit branch -u origin/feature-branchgit checkout --track origin/feature-branchRemove branches from remote repositories:
git push origin --delete feature-branchgit push origin :feature-branchAuthenticate with username and password:
git clone https://github.com/username/repo.gitWhen you push, you'll be prompted for credentials.
Authenticate using SSH keys (more secure):
ssh-keygen -t ed25519 -C "your_email@example.com"cat ~/.ssh/id_ed25519.pubgit clone git@github.com:username/repo.gitStore credentials to avoid typing them repeatedly:
git config --global credential.helper cachegit config --global credential.helper storeFor Windows:
git config --global credential.helper managerFor macOS:
git config --global credential.helper osxkeychainModern authentication for HTTPS (replacing passwords):
# Use token as password when prompted
git clone https://github.com/username/repo.git
# Username: your-username
# Password: your-personal-access-token💡 Tip: GitHub, GitLab, and other platforms now require personal access tokens instead of passwords for Git operations.
This section covers standard workflows for different collaboration models in Git.
A workflow commonly used in open source projects where you don't have direct write access to the repository.
gitGraph
commit id: "Initial project"
commit id: "More work"
branch fork/main
checkout fork/main
commit id: "Clone fork"
branch feature
checkout feature
commit id: "Make changes"
commit id: "Finalize feature"
checkout fork/main
merge feature
checkout main
merge fork/main id: "PR merged"
Create your own copy of the repository on the remote server (done through GitHub/GitLab web interface).
Create a local copy of your fork:
git clone https://github.com/your-username/repo.gitConnect to the original repository to fetch updates later:
git remote add upstream https://github.com/original-owner/repo.gitCreate a branch for your work:
git checkout -b feature-branchImplement your feature or fix:
# Make changes to code files
git add .git commit -m "Add new feature"Upload your changes to your remote fork:
git push -u origin feature-branchSubmit your changes for review (done through GitHub/GitLab web interface).
A workflow used when you have direct write access to the shared repository.
gitGraph
commit id: "Project start"
commit id: "Previous work"
branch feature-branch
checkout feature-branch
commit id: "Add feature"
commit id: "Refine feature"
checkout main
merge feature-branch id: "Merge feature"
commit id: "Hotfix"
Get a local copy of the shared repository:
git clone https://github.com/team/repo.gitCreate a branch for your specific work:
git checkout -b feature-branchImplement your feature or fix:
# Make changes to code files
git add .git commit -m "Add new feature"Stay up to date with others' work:
git fetch origingit rebase origin/mainOr alternatively:
git merge origin/mainShare your work with the team:
git push -u origin feature-branchEither merge directly or create a pull request for review, depending on team practices:
# For direct merge (if permitted):
git checkout maingit merge feature-branchgit push origin mainKeeping your fork up to date with the original repository.
gitGraph
commit id: "Original state"
branch fork/main
checkout fork/main
commit id: "Your fork"
checkout main
commit id: "Upstream updates"
commit id: "More upstream work"
checkout fork/main
merge main id: "Sync from upstream"
commit id: "Your new work"
Connect to the original repository (if not done already):
git remote add upstream https://github.com/original-owner/repo.gitDownload the latest updates from the original repository:
git fetch upstreamMove to your local main branch:
git checkout mainIncorporate the updates into your local branch:
git merge upstream/mainUpdate your remote fork with the synced changes:
git push origin mainA more structured workflow for larger projects with scheduled releases.
gitGraph
commit id: "Project start"
branch develop
checkout develop
commit id: "Development work"
branch feature/login
checkout feature/login
commit id: "Add login"
commit id: "Refine login"
checkout develop
merge feature/login
branch release/1.0
checkout release/1.0
commit id: "Release prep"
checkout main
merge release/1.0 id: "Release 1.0"
checkout develop
merge release/1.0
branch hotfix/1.0.1
checkout hotfix/1.0.1
commit id: "Critical fix"
checkout main
merge hotfix/1.0.1 id: "Release 1.0.1"
checkout develop
merge hotfix/1.0.1
Set up the Gitflow branching structure:
git flow initOr manually create develop branch:
git checkout -b develop mainCreate a feature branch from develop:
git flow feature start loginOr manually:
git checkout -b feature/login developFinish the feature, merging back to develop:
git flow feature finish loginOr manually:
git checkout developgit merge --no-ff feature/logingit branch -d feature/loginBranch off for release preparation:
git flow release start 1.0Or manually:
git checkout -b release/1.0 developMerge to main and back to develop:
git flow release finish 1.0Or manually:
git checkout maingit merge --no-ff release/1.0git tag -a v1.0 -m "Version 1.0"git checkout developgit merge --no-ff release/1.0git branch -d release/1.0Fix critical issues in production:
git flow hotfix start bug-fixOr manually:
git checkout -b hotfix/bug-fix mainApply the fix to both main and develop:
git flow hotfix finish bug-fixOr manually:
git checkout maingit merge --no-ff hotfix/bug-fixgit tag -a v1.0.1 -m "Version 1.0.1"git checkout developgit merge --no-ff hotfix/bug-fixgit branch -d hotfix/bug-fixRejected non-fast forward push:
! [rejected] main -> main (non-fast-forward)
Solution:
git pull origin maingit push --force origin mainFailed to push some refs:
Updates were rejected because the remote contains work that you do not have locally
Solution:
git fetch origingit merge origin/maingit pullLocal changes would be overwritten:
Your local changes would be overwritten by merge
Solution:
git stashgit pullgit stash popgit commit -am "WIP: Saving changes before pull"git pullMerge conflicts:
CONFLICT (content): Merge conflict in <filename>
Solution:
Edit the files to resolve conflicts.
git add <resolved-files>git commitgit merge --abortPermission denied errors:
Permission to repository.git denied to user
Solutions:
git remote -vgit remote set-url origin https://username@github.com/username/repo.gitgit remote set-url origin git@github.com:username/repo.git| Operation | Command | Description |
|---|---|---|
| Add Remote | git remote add <name> <url> |
Connect to remote repo |
| View Remotes | git remote -v |
List all remotes with URLs |
| Fetch | git fetch <remote> |
Download without merging |
| Pull | git pull <remote> <branch> |
Download and merge |
| Pull with Rebase | git pull --rebase |
Download and rebase |
| Push | git push <remote> <branch> |
Upload local commits |
| Set Upstream | git push -u <remote> <branch> |
Push and track branch |
| Delete Remote Branch | git push <remote> --delete <branch> |
Remove remote branch |
| List Remote Branches | git branch -r |
Show remote branches |