LFCA 87 ๐ง Git Remotes โ push, pull, clone
The previous chapter covered the three local commands: git init, git add, and git commit. Those commands create a repository on your machine. This chapter covers the commands that connect that repository to a remote: git clone, git remote, git push, and git pull. The remote is the shared copy of the repository on a server โ GitHub, GitLab, Bitbucket, or a self-hosted Git server. It is the synchronization point that allows multiple developers to collaborate on the same codebase.
The LFCA exam places Git under DevOps Fundamentals, which carries 12โ16% of the total weight. The study plan lists “Git Concepts” as a core DevOps topic. The exam expects you to understand the remote workflow: how to clone an existing repository, how to connect a local repository to a remote, how to push your commits, and how to pull changes made by others.
Key point: A remote is a named reference to another copy of the repository. The default name for the remote is origin. When you clone a repository, Git automatically creates the origin remote pointing to the URL you cloned from. When you push, you send your commits to the remote. When you pull, you fetch the remote’s commits and merge them into your local branch. The remote is not a single server โ a local repository can have multiple remotes, each with its own name.
Why remotes matter
A local repository is useful for one person. A remote repository is what makes collaboration possible. Without a remote, every developer works in isolation. With a remote, the team shares a single source of truth.
The collaboration problem. Two developers work on the same feature. Without a remote, they cannot share their changes. With a remote, each developer pushes their commits to the shared repository. The other developer pulls the commits and sees the changes. The remote is the synchronization point.
The backup problem. A local repository is a backup of the project’s history. But a local machine can fail. A remote repository is a second copy of the history. If the local machine is lost, the remote still has the commits. The developer can clone the remote to a new machine and recover the project.
The deployment problem. A CI/CD pipeline watches the remote repository. When a developer pushes a commit, the pipeline triggers. The pipeline builds the code, runs the tests, and deploys the artifact. The remote is the trigger for automation. Without a remote, there is nothing for the pipeline to watch.
The code review problem. A pull request is a request to merge one branch into another. The pull request is hosted on the remote. The other developers review the changes, comment on them, and approve or reject. The remote is the platform for code review. Without a remote, code review is a manual process with no record.
The trade-off. A remote adds a network dependency. Pushing and pulling require connectivity. The operations can fail if the network is down. But the remote is what makes the collaboration possible. The dependency is the price of working with others.
a. git clone โ Copying a Remote Repository
The git clone command creates a local copy of a remote repository. It is the first command a developer runs when joining an existing project.
git clone https://github.com/user/repo.git
The command performs several operations. It creates a new directory named after the repository. It initializes a Git repository in that directory. It adds the remote URL as the origin remote. It fetches all the commits from the remote. It checks out the default branch into the working directory.
The clone can be directed to a different directory name:
git clone https://github.com/user/repo.git my-project
The clone can also be made from a local path:
git clone /path/to/local/repo
Git supports several URL formats for cloning. The HTTPS format is the most common. The SSH format is used for authenticated access. The Git protocol is used for read-only access. The choice depends on the remote server’s configuration and the developer’s authentication setup.
After cloning, the developer has a complete copy of the repository’s history. The origin remote is configured to point to the URL. The developer can work locally, commit changes, and push them back to the remote.
b. git remote โ Managing Remotes
The git remote command manages the list of remotes for a local repository. The most common remote is origin, which is created automatically when a repository is cloned. A local repository can have multiple remotes.
To list the remotes:
git remote
The output shows the remote names:
origin
To list the remotes with their URLs:
git remote -v
The output shows the fetch and push URLs:
origin https://github.com/user/repo.git (fetch)
origin https://github.com/user/repo.git (push)
To add a new remote:
git remote add upstream https://github.com/other/repo.git
The upstream remote is commonly used in forked repositories. The developer’s fork is the origin, and the original repository is the upstream. The developer can pull changes from the upstream and push them to their own fork.
To remove a remote:
git remote remove upstream
To rename a remote:
git remote rename origin upstream
The remote name is a local reference. Changing the name does not affect the remote repository. It only changes the name that the local repository uses to refer to the remote.
c. git push โ Sending Commits to the Remote
The git push command sends the local commits to the remote. It is how the developer shares their work with the team.
git push
The command pushes the current branch to the remote branch that it tracks. If the local branch is not tracking a remote branch, the command fails. The tracking relationship is established with the -u flag on the first push:
git push -u origin main
The -u flag is short for --set-upstream. It tells Git that the local main branch tracks the origin/main branch. After this, git push and git pull work without arguments on the main branch.
To push a different branch:
git push origin feature/login
The command pushes the local feature/login branch to the origin remote. If the remote branch does not exist, it is created.
The --all flag pushes all branches:
git push --all origin
The --tags flag pushes all tags:
git push --tags origin
A push can fail if the remote has commits that the local repository does not have. This happens when another developer has pushed to the same branch since the last pull. The push is rejected with a message like “Updates were rejected because the remote contains work that you do not have locally.” The developer must pull the remote changes, merge them, and push again.
The --force flag overrides the rejection and overwrites the remote branch. It should be used with extreme caution because it can destroy the remote’s history. The --force-with-lease flag is a safer alternative: it only forces the push if the remote has not changed since the last fetch.
d. git pull โ Fetching and Merging Remote Changes
The git pull command fetches the commits from the remote and merges them into the current branch. It is how the developer gets the changes made by others.
git pull
The command is a combination of two operations: git fetch and git merge. The git fetch downloads the new commits from the remote. The git merge combines them into the local branch. The git pull command does both in a single step.
The git fetch command alone downloads the new commits without merging them. The developer can inspect the changes before merging.
git fetch origin
The fetched commits are stored in the remote-tracking branches. The origin/main branch is the local copy of the remote’s main branch. The developer can compare the local branch to the remote-tracking branch:
git log HEAD..origin/main
The command shows the commits that are in the remote-tracking branch but not in the local branch. The developer can review the changes before merging them.
The git pull command can be configured to use a merge or a rebase strategy. The default is merge. The git pull --rebase command rebases the local commits on top of the remote commits instead of creating a merge commit. The choice depends on the team’s workflow.
A pull can produce a merge conflict if the local and remote changes affect the same lines of the same file. The developer must resolve the conflict manually, stage the resolved files, and commit the merge.
Complete Example Session
This session demonstrates the remote workflow: cloning, pushing, pulling, and adding a remote.
# ============================================
# PART 1: CLONE A REMOTE REPOSITORY
# ============================================
git clone https://github.com/user/repo.git
# Output:
# Cloning into 'repo'...
# remote: Enumerating objects: 100, done.
# remote: Counting objects: 100% (100/100), done.
# Receiving objects: 100% (100/100), done.
# Resolving deltas: 100% (50/50), done.
# The repository is cloned into the 'repo' directory.
# The 'origin' remote points to the URL.
cd repo
# ============================================
# PART 2: CHECK THE REMOTE
# ============================================
git remote -v
# Output:
# origin https://github.com/user/repo.git (fetch)
# origin https://github.com/user/repo.git (push)
# ============================================
# PART 3: MAKE A CHANGE AND PUSH
# ============================================
echo "# Updated README" > README.md
git add README.md
git commit -m "Update README"
git push
# Output:
# Enumerating objects: 5, done.
# Counting objects: 100% (5/5), done.
# Writing objects: 100% (3/3), 250 bytes | 250.00 KiB/s, done.
# To https://github.com/user/repo.git
# a1b2c3d..f6e5d4c main -> main
# The commit is pushed to the remote.
# The remote's main branch now has the new commit.
# ============================================
# PART 4: PULL CHANGES FROM THE REMOTE
# ============================================
# Another developer has pushed a commit.
# The local repository is behind.
git pull
# Output:
# remote: Enumerating objects: 5, done.
# remote: Counting objects: 100% (5/5), done.
# Unpacking objects: 100% (3/3), done.
# From https://github.com/user/repo.git
# f6e5d4c..g7h8i9j main -> origin/main
# Updating f6e5d4c..g7h8i9j
# Fast-forward
# file.txt | 1 +
# 1 file changed, 1 insertion(+)
# The remote's commit is fetched and merged.
# The local branch is now up to date.
# ============================================
# PART 5: FETCH WITHOUT MERGE
# ============================================
git fetch origin
# Output:
# remote: Enumerating objects: 3, done.
# From https://github.com/user/repo.git
# g7h8i9j..h8i9j0k main -> origin/main
# The remote's commits are fetched.
# The local branch is unchanged.
# The developer can review the changes before merging.
git log HEAD..origin/main
# Output:
# commit h8i9j0k...
# Author: Bob <bob@example.com>
# Add new feature
# The commit is in the remote-tracking branch but not in the local branch.
git merge origin/main
# The remote-tracking branch is merged into the local branch.
# ============================================
# PART 6: ADD A NEW REMOTE
# ============================================
git remote add upstream https://github.com/original/repo.git
git remote -v
# Output:
# origin https://github.com/user/repo.git (fetch)
# origin https://github.com/user/repo.git (push)
# upstream https://github.com/original/repo.git (fetch)
# upstream https://github.com/original/repo.git (push)
# The upstream remote is added.
# The developer can pull changes from the original repository.
# ============================================
# PART 7: PUSH A NEW BRANCH
# ============================================
git checkout -b feature/login
# ... make changes ...
git add .
git commit -m "Add login feature"
git push -u origin feature/login
# Output:
# * [new branch] feature/login -> feature/login
# Branch 'feature/login' set up to track remote branch 'feature/login' from 'origin'.
# The new branch is pushed to the remote.
# The tracking relationship is established with -u.
# ============================================
# PART 8: PULL WITH REBASE
# ============================================
git pull --rebase
# The local commits are rebased on top of the remote commits.
# The history is linear instead of having a merge commit.
# ============================================
# PART 9: PUSH ALL BRANCHES
# ============================================
git push --all origin
# All local branches are pushed to the origin remote.
# ============================================
# PART 10: THE REMOTE WORKFLOW SUMMARY
# ============================================
# git clone: copy a remote repository
# git remote: manage remotes
# git push: send commits to the remote
# git pull: fetch and merge remote commits
# git fetch: fetch remote commits without merging
The ten parts cover cloning a repository, checking the remote, pushing a commit, pulling changes, fetching without merge, adding a new remote, pushing a new branch, pulling with rebase, pushing all branches, and the workflow summary.
Quick Reference
The Remote Commands
| Command | Purpose |
|---|---|
git clone <url> | Copy a remote repository |
git remote | List remotes |
git remote -v | List remotes with URLs |
git remote add <name> <url> | Add a remote |
git remote remove <name> | Remove a remote |
git remote rename <old> <new> | Rename a remote |
git push | Send commits to the remote |
git push -u <remote> <branch> | Push and set upstream |
git push --all <remote> | Push all branches |
git pull | Fetch and merge |
git fetch <remote> | Fetch without merging |
The Remote Names
| Name | Purpose |
|---|---|
origin | Default remote, created on clone |
upstream | Original repository in a fork |
| Custom | Any name the developer chooses |
The URL Formats
| Format | Example |
|---|---|
| HTTPS | https://github.com/user/repo.git |
| SSH | git@github.com:user/repo.git |
| Git | git://github.com/user/repo.git |
| Local | /path/to/repo.git |
The Push Flags
| Flag | Purpose |
|---|---|
-u / --set-upstream | Set tracking relationship |
--all | Push all branches |
--tags | Push all tags |
--force | Overwrite remote (dangerous) |
--force-with-lease | Safer force |
The Pull Flags
| Flag | Purpose |
|---|---|
--rebase | Rebase instead of merge |
--no-rebase | Merge instead of rebase |
--ff-only | Fail if not fast-forward |
Best Practices
โ Do This:
# Use -u on the first push
git push -u origin main # โ
# Pull before pushing
git pull && git push # โ
# Use fetch to review changes
git fetch origin && git log HEAD..origin/main # โ
# Use HTTPS or SSH depending on the setup
git clone git@github.com:user/repo.git # โ
โ Don’t Do This:
# Don't use --force on a shared branch
git push --force origin main # โ
# Don't push without pulling first
git push # may be rejected # โ
# Don't commit and push secrets
git push origin main # with .env committed # โ
# Don't use the wrong remote name
git push upstream main # if you meant origin # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Push rejected | Remote has newer commits | Pull, merge, push |
| Remote origin exists | Already added | Use a different name |
| Cannot clone private repo | No authentication | Use SSH or PAT |
| Tracking not set | No -u on first push | git push -u origin branch |
| Merge conflict on pull | Same file changed | Resolve manually |
| Wrong remote | Multiple remotes | Check git remote -v |
Real-World Examples
1. Clone a Repository
git clone https://github.com/user/repo.git
2. List Remotes
git remote -v
3. Add a Remote
git remote add origin https://github.com/user/repo.git
4. Push a Branch
git push -u origin main
5. Pull Changes
git pull
6. Fetch Without Merge
git fetch origin
7. Push a New Branch
git push -u origin feature/login
8. Pull with Rebase
git pull --rebase
9. Remove a Remote
git remote remove upstream
10. Rename a Remote
git remote rename origin upstream
Visual
The Remote Workflow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ REMOTE REPOSITORY (origin) โ
โ main โ
โ feature/login โ
โ โ
โ โฒ โ
โ โ git push โ
โ โ โ
โ LOCAL REPOSITORY โ
โ main โ
โ feature/login โ
โ โ โ
โ โ git pull โ
โ โผ โ
โ REMOTE REPOSITORY (origin) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Clone Operation
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ git clone <url> โ
โ โ
โ 1. Create the directory โ
โ 2. git init โ
โ 3. git remote add origin <url> โ
โ 4. git fetch origin โ
โ 5. git checkout main โ
โ โ
โ The result is a complete local copy. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Push Rejection
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PUSH REJECTED โ
โ โ
โ Local: A โโ> B โโ> C โ
โ Remote: A โโ> B โโ> D โ
โ โ
โ The remote has commit D. โ
โ The local does not have D. โ
โ The push is rejected. โ
โ โ
โ Fix: git pull, merge, git push โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Fetch vs Pull
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ git fetch โ
โ โโ Downloads commits from remote โ
โ โโ Does not merge โ
โ โโ Updates remote-tracking branches โ
โ โ
โ git pull โ
โ โโ git fetch + git merge โ
โ โโ Downloads and merges โ
โ โโ Updates the current branch โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| git clone | Copy a remote repository |
| git remote | Manage remotes |
| git push | Send commits to the remote |
| git pull | Fetch and merge remote commits |
| git fetch | Fetch without merging |
| Default remote | origin |
| Fork remote | upstream |
| Push tracking | -u / --set-upstream |
| URL formats | HTTPS, SSH, Git, local |
| Force push | --force, --force-with-lease |
| LFCA weight | DevOps Fundamentals, 12โ16% |
Key takeaways:
git clonecreates a local copy of a remote repository. The command initializes a repository, adds the remote asorigin, fetches the commits, and checks out the default branch. The result is a complete local copy of the project’s history .git remotemanages the list of remotes. Theoriginremote is created automatically on clone. Additional remotes can be added withgit remote add. Theupstreamremote is commonly used in forked repositories to refer to the original repository .git pushsends local commits to the remote. The-uflag on the first push establishes the tracking relationship. After that,git pushandgit pullwork without arguments. A push is rejected if the remote has commits that the local repository does not have .git pullfetches and merges remote commits. The command is a combination ofgit fetchandgit merge. Thegit fetchcommand downloads the commits without merging. The developer can review the changes before merging .- The remote is the synchronization point for collaboration. Multiple developers push their commits to the remote and pull the commits made by others. The remote is also the trigger for CI/CD pipelines and the platform for code review .
- A local repository can have multiple remotes. The
originremote is the developer’s fork. Theupstreamremote is the original repository. The developer can pull changes from the upstream and push them to their own fork. - The
--forceflag is dangerous. It overwrites the remote’s history. It should only be used when the developer is certain that no one else has pushed to the branch. The--force-with-leaseflag is a safer alternative that checks whether the remote has changed since the last fetch.
Remember: git clone copies the remote repository. git remote manages the list of remotes. git push sends your commits. git pull fetches and merges the commits made by others. The remote is the shared copy that makes collaboration possible. The origin remote is the default. The upstream remote is the original. The -u flag establishes the tracking relationship. The remote is the synchronization point for the team.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!