A remote is a reference to a repository hosted somewhere else, usually on a platform such as GitHub, GitLab, or Bitbucket. It gives your local repository a way to exchange commits with shared repositories.
The most common remote name is origin.
Check your current remotes:
git remote -vYou might see:
origin https://github.com/example/devops-notes.git (fetch)
origin https://github.com/example/devops-notes.git (push)If you started a repository locally and later created a hosted repository, add a remote like this:
git remote add origin https://github.com/example/devops-notes.gitVerify it:
git remote -vTo remove a remote:
git remote remove originTo rename a remote:
git remote rename origin upstreamTip: In fork-based workflows,
originoften points to your fork, whileupstreampoints to the original project.
git fetchgit fetch downloads new commits and remote references without changing your working files.
git fetch originThis updates your knowledge of remote branches such as origin/main, but it does not merge them into your current branch.
fetch Is SafeBecause it does not change your working branch automatically, fetch is a safe way to inspect remote changes before deciding what to do next.
You can compare local and remote history after fetching:
git log --oneline main..origin/maingit pullgit pull is essentially a fetch followed by integration, usually a merge.
git pull origin mainIf your current branch tracks a remote branch, you can often just run:
git pullBe aware that pull can change your working tree immediately, which is why many developers prefer to fetch first when they want more control.
git pushUse git push to send local commits to a remote repository.
git push origin mainIf you are pushing a new branch for the first time:
git push -u origin feature/loginThe -u flag sets the upstream relationship, which means future pushes and pulls can use shorter commands.
A tracking branch is a local branch linked to a remote branch. This relationship makes commands like git pull and git push more convenient.
When you run:
git push -u origin feature/loginGit remembers that your local feature/login branch tracks origin/feature/login.
You can inspect tracking details with:
git branch -vvSample output:
* feature/login 3f91ab2 [origin/feature/login] Add login validation
main 1de2049 [origin/main] Update READMEIf the branch already exists remotely, set the upstream manually:
git branch --set-upstream-to=origin/feature/loginNow simple git pull and git push commands work as expected from that branch.
A typical day might look like this:
git switch main
git fetch origin
git pull origin main
git switch -c feature/update-docs
# make changes
git add .
git commit -m "Improve Git tutorial examples"
git push -u origin feature/update-docsThis sequence updates local main, creates a feature branch, and publishes it to the remote for review.
You may need to fetch first:
git fetch origingit pull Change My Files?âBecause pull integrates remote changes into your current branch. Use fetch first if you want to inspect before updating.
Your local branch is not yet linked to a remote branch. Push with -u or set the upstream manually.
Note: Authentication for push operations may use HTTPS tokens or SSH keys depending on your platform setup.
Remotes connect your local repository to shared repositories. git remote manages the connection, git fetch downloads information safely, git pull downloads and integrates changes, and git push publishes your commits. Tracking branches and upstream settings reduce repetitive typing and make collaboration smoother.
If you are unsure whether you want your working tree changed, fetch first.
Scenario: You want to see what changed on origin/main before your current branch is modified.
Question: Which command from the tutorial is the safest first step?
<MCQExercise
exercise={{
id: 'git-remote-q1',
title: 'Exercise 1: Inspecting before integrating',
description: 'Choose the command that downloads remote information without changing the current branch.',
options: [
{ id: 'a', text: 'git fetch origin' },
{ id: 'b', text: 'git pull origin main' },
{ id: 'c', text: 'git push origin main' },
{ id: 'd', text: 'git remote remove origin' },
],
correctId: 'a',
explanation: 'The lesson described git fetch as the safe way to download new remote commits and references without updating your working tree. That lets you inspect origin/main before deciding whether to merge or rebase.',
wrongExplanations: {
b: 'Pull performs a fetch plus integration, so it can change your current branch immediately.',
c: 'Push sends your changes out; it does not inspect incoming ones.',
d: 'Removing the remote would break the connection rather than help you inspect it.',
},
}}
/>
Scenario: You just created feature/login locally and want future git push and git pull commands to be shorter.
Question: Which command sets that upstream relationship while publishing the branch?
<MCQExercise
exercise={{
id: 'git-remote-q2',
title: 'Exercise 2: First push of a new branch',
description: 'Pick the command that pushes a new branch and configures upstream tracking.',
options: [
{ id: 'a', text: 'git branch --set-upstream-to=origin/main' },
{ id: 'b', text: 'git remote rename origin feature/login' },
{ id: 'c', text: 'git pull -u origin feature/login' },
{ id: 'd', text: 'git push -u origin feature/login' },
],
correctId: 'd',
explanation: 'The tutorial called out git push -u origin feature/login as the common first push for a new branch. The -u flag establishes the tracking relationship so later plain git push and git pull commands know which remote branch to use.',
wrongExplanations: {
a: 'That can set tracking in some cases, but it does not publish the new branch by itself.',
b: 'Remote rename changes remote names, not branch tracking for this new feature branch.',
c: 'Pull is for receiving changes, not for publishing a new local branch upstream.',
},
}}
/>
Question: In the fork-based setup described in the lesson, what does upstream usually refer to?
<MCQExercise
exercise={{
id: 'git-remote-q3',
title: 'Exercise 3: Fork workflow naming',
description: 'Interpret the common meaning of upstream in a fork workflow.',
options: [
{ id: 'a', text: 'A local-only branch used for stashing work.' },
{ id: 'b', text: 'The staging area that holds files before commit.' },
{ id: 'c', text: 'The original repository, while origin points to your fork.' },
{ id: 'd', text: 'A hidden Git database file inside .git.' },
],
correctId: 'c',
explanation: 'The tutorial noted the common convention that origin points to your fork and upstream points to the original project. That naming makes it easier to fetch new changes from the main source repository.',
wrongExplanations: {
a: 'upstream is a remote naming convention, not a local branch pattern.',
b: 'The staging area is a repository concept, not a remote name.',
d: 'A remote is a repository reference, not an internal database file.',
},
}}
/>
The remote branch has commits you do not have locally, so accepting your push would discard them. Run git pull --rebase to replay your work on top of theirs, resolve any conflicts, then push. Do not reach for git push --force, which deletes their commits. If you genuinely must overwrite, after an intentional rebase of your own feature branch, use git push --force-with-lease, which refuses the push if the remote has moved since you last fetched.
-u (short for --set-upstream) records origin/main as the upstream of your local main, in addition to pushing. That association is what lets you type bare git push, git pull and git status afterwards and have Git know which remote branch you mean, including the "your branch is ahead by 2 commits" line in git status. You need it once per branch; after that the plain commands work. git branch -vv shows which branches have an upstream set.
Your local copy of the remote's branch list is only updated when you fetch. Run git fetch (or git fetch --all for every remote) and then git branch -r lists the remote branches you know about. The reverse problem is stale entries for branches that have been deleted upstream, which git fetch --prune clears; git config --global fetch.prune true makes that automatic on every fetch.
They are just remote names, not Git concepts. origin is the conventional name for the repository you cloned from, set automatically by git clone. upstream is the convention in fork-based workflows for the original project you forked: origin is your fork and upstream is the source. That is what makes git fetch upstream && git rebase upstream/main the standard way to bring a fork up to date. Add it with git remote add upstream <url>, and git remote -v lists what you have.
git remote set-url origin git@github.com:user/repo.git, then confirm with git remote -v. This is the usual fix when HTTPS pushes start asking for a password that no longer works. GitHub stopped accepting account passwords for Git operations, so HTTPS needs a personal access token while SSH uses your key. Switching to SSH avoids the credential prompt entirely once your key is added to the account.
Park work in progress with git stash: apply versus pop, stash untracked files, name and inspect stashes, and decide when a branch is the better tool instead.
Undo almost anything in Git: restore files, reset soft, mixed and hard, revert on shared branches, clean untracked files and recover a bad reset with reflog.
Mark releases with Git tags: lightweight versus annotated, why push ignores tags, deleting them safely, tagging older commits and semantic-versioned releases.