We closed module 3 with an open problem: all the work on task-manager lives inside a single .git/, the one on Ana's Ubuntu laptop. Bruno's branches only ever existed in our imagination, and Carla has spent three modules waiting on her Windows 11 machine for somebody to tell her where to download the project from.
This module closes that circle, and it starts where it has to start: by understanding what a remote is. The answer will disappoint anyone hoping for magic, because a remote is not a server, nor a service, nor a synchronised copy of your project. A remote is a short name for a URL. Nothing more. Everything else — fetch, pull, push, tracking branches — is built on top of that tiny idea.
We are not going to register any remote in this lesson (that is the next one). We are going to build the right mental model: why a distributed system has no technically central server, what a bare repository is and why the one on the server has no files to work with, what exactly those origin/main references that have been showing up since lesson 02-02 are, and what platforms like GitHub or GitLab add on top of the Git you already know.
Contents
- What a remote is: a short name for a URL
- Why there is no central server (technically)
- The reference repository: a convention, not an imposition
- Bare repositories: the server needs no files
- Remote references:
.git/refs/remotes/ origin/mainis a local, read-only reference- Naming conventions:
origin,upstreamand the rest - Hosting platforms: what they add on top of Git
- The complete mental map
- What a remote is: a short name for a URL
Let us start with the exact definition, because almost all the confusion that follows comes from not having it clear.
A remote is an entry in your repository's configuration that associates a short name with a URL (and with some rules about which references to bring from there).
That is literally all there is to it. When you type origin, Git looks in .git/config for a [remote "origin"] section, reads the URL inside and uses it. It is exactly the same mechanism as a shell alias or an entry in /etc/hosts: a convenient name for something long and awkward to type.
Compare the two ways of doing the same thing:
# With no remote registered: the whole URL, every time
git fetch https://git.example.com/team/task-manager.git main
# With the remote registered: a short name
git fetch origin mainBoth work. The first one proves the point: Git can talk to any repository if you give it the URL directly, without registering anything. Remotes exist so that you do not have to repeat the URL forty times a day, and so that you can attach extra configuration to it.
What a remote is NOT
Knowing what is not behind that word matters just as much:
| A remote is not… | Why people think it is |
|---|---|
| A synchronised folder, Dropbox-style | Nothing synchronises by itself: objects travel only when you run fetch, pull or push |
| A permanent connection | Git is completely asynchronous: it works offline and only connects during those three commands |
| An identical copy of your repository | The remote has its own branches, and they may be ahead of or behind yours |
| A server with intelligence | The other end runs Git, just like you; there is no business logic over there |
| Something compulsory | A Git repository works perfectly well with no remote at all, like Ana's for three modules |
That last point deserves emphasis. Everything you have done so far — committing, branching, merging, resolving conflicts, browsing the history — works offline and without remotes. Remotes do not add capabilities to Git: they add transport. They are the mechanism by which the objects in one .git/objects/ end up in another .git/objects/.
The URLs a remote accepts
A remote can point at very different places, and not all of them are on the internet:
# HTTPS: the most common one with hosting platforms
https://git.example.com/team/task-manager.git
# SSH, scp-style short form (the one you will see most)
[email protected]:team/task-manager.git
# SSH, full URL form (equivalent to the one above)
ssh://[email protected]/team/task-manager.git
# Local path: a folder on your own machine or on a mounted disk
/home/ana/backups/task-manager.git
# Local path in file:// format
file:///home/ana/backups/task-manager.git
# git:// protocol (no authentication, read-only, all but obsolete)
git://git.example.com/team/task-manager.gitYou already met the protocols in lesson 02-02 when we covered git clone; they are exactly the same ones, because clone is nothing more than "create a repository + register a remote + fetch the lot".
One detail worth internalising: a local path is a perfectly valid URL. You can have a remote pointing at a folder on your own disk, and the whole module works the same. That is superb for practising, and we will use it in the exercises: you need no account anywhere and no internet connection to learn remotes.
- Why there is no central server (technically)
In lesson 01-01 we saw the difference between centralised and distributed version control. Now comes the practical consequence, which is more radical than it usually looks.
In Subversion or CVS, the server is structurally different from the client: it holds the history, it decides which revision numbers get assigned and it is indispensable for almost every operation. No server, no version control.
Git has no such distinction. All repositories are equal. The repository sitting on git.example.com runs the same Git, stores the same objects in the same format and holds no special privilege over Ana's. If the server burnt down this afternoon, any of the three could stand up a new one from their own copy and the team would be working again in five minutes.
flowchart TB
subgraph ANA["Ana's laptop · Ubuntu"]
A1["Complete repository<br/>.git/objects + .git/refs<br/>+ working tree"]
end
subgraph BRUNO["Bruno's MacBook · macOS"]
B1["Complete repository<br/>.git/objects + .git/refs<br/>+ working tree"]
end
subgraph CARLA["Carla's laptop · Windows 11"]
C1["Complete repository<br/>.git/objects + .git/refs<br/>+ working tree"]
end
subgraph SRV["git.example.com · bare repository"]
S1["Complete repository<br/>objects + refs<br/><b>no</b> working tree"]
end
A1 <-->|push / fetch| S1
B1 <-->|push / fetch| S1
C1 <-->|push / fetch| S1
A1 <-.->|technically possible:<br/>direct exchange| B1
Look at the dashed line between Ana and Bruno. It is not decoration: it is Git working exactly as designed. Bruno can register Ana's laptop as a remote and pull her commits straight across, with no server involved. Linus Torvalds designed Git for the Linux kernel, where hundreds of people swap patches and branches without any compulsory central repository.
So why does everybody use a server?
Because the reasons for having a reference repository are not technical but organisational:
- Availability. Ana's laptop is switched off at night, on the plane and while she is on holiday. A server is always on.
- A point of agreement. With a reference repository, the question "which is the good version of
main?" has a single, boring answer. Without one, there are three answers and three opinions. - An implicit backup. If Bruno's disk dies, the work he pushed still exists.
- Access control. Somebody has to decide who may write to
main. That needs a place where such rules can be enforced. - Automation. Automated tests, deployments and notifications need a fixed point to hook into (module 7).
- Network directionality. Ana cannot connect to Carla's laptop: it sits behind her home router, with a changing IP and no open ports. A server with a stable address solves the problem of everybody being able to reach a common place.
That last reason is the most underrated and probably the most decisive in practice.
- The reference repository: a convention, not an imposition
Out of all the above comes an idea worth nailing down:
A project's "official" repository is official because the team has agreed it is, not because Git distinguishes it in any way.
If tomorrow the team decides the good repository now lives on another server, all three need do is change one line of configuration — the URL of their origin remote — and that other one becomes the official one. Git never notices the change and does not care. It is a five-second migration per person, something unthinkable in a centralised system.
That flexibility has an uncomfortable side: Git protects nothing on its own. There is no native concept of "this branch is sacred" or "only Ana may write here". Anyone with write access can, in principle, rewrite main on the server. The protections teams rely on — protected branches, mandatory reviews, checks that must pass before integrating — are added by hosting platforms on top of Git, not by Git.
We will look at them in detail in module 7, but internalise the split right now: Git moves objects; the platform sets the rules.
- Bare repositories: the server needs no files
In lesson 02-01 we left an idea half-finished: git init --bare creates a repository with no working tree, and we said it would make sense once we talked about remotes. That moment has arrived.
What it is exactly
A normal repository looks like this:
task-manager/ ├── .git/ ← the repository (objects, references, configuration) │ ├── objects/ │ ├── refs/ │ ├── HEAD │ └── config ├── index.html ← the working tree ├── styles.css ├── app.js └── README.md
A bare repository looks like this instead:
task-manager.git/ ├── objects/ ← what lived inside .git/ in the other one ├── refs/ ├── HEAD ├── config ├── description └── hooks/
It is the contents of .git/ promoted to the root, and not a single project file. Hence the name bare: it has no working copy to dress itself in.
By convention, the directories of bare repositories end in .git — task-manager.git — so you can tell at a glance what they are. That is precisely where the trailing .git in the URLs you have been seeing all course comes from.
Why the server's repository has to be bare
Imagine for a moment that it were not: that the server held a normal repository, with its index.html and its app.js on disk, and with HEAD pointing at main.
Ana runs git push and sends three new commits to main. What should happen on the server?
- If Git updated the
mainbranch and the working-tree files, it would be modifying files on a machine where somebody might be editing them at that very moment. It could destroy work without warning. - If it updated the branch but not the files, the server's repository would be left in an inconsistent state:
git statusover there would report dozens of modified and deleted files when in fact nobody has touched anything.
Neither option is acceptable, so Git picks a third: refusing. If you try to push to the branch that is checked out in a non-bare repository, you get this:
! [remote rejected] main -> main (branch is currently checked out) error: failed to push some refs to '/home/ana/backups/task-manager'
With a bare repository the problem disappears at the root: since there is no working tree, nothing can be left inconsistent. Receiving a push boils down to adding objects and moving a pointer, which is a clean, safe operation.
| Normal repository | Bare repository | |
|---|---|---|
| Working tree | Yes | No |
| Created with | git init / git clone |
git init --bare / git clone --bare |
| Structure | project/.git/… |
project.git/… (everything at the root) |
| Used for | Working: editing, committing | Sharing: receiving and serving |
Accepts git push to its checked-out branch |
No | Yes (it has no "checked-out" branch in that sense) |
| Can you edit code in it | Yes | There are no files to edit |
git status |
Informative | Error: no working copy |
What sits behind GitHub, GitLab or Gitea is always a bare repository. When you clone, the platform serves the objects out of one; when you push, it receives them into one.
Creating one to practise with
This will come in handy in every exercise of the module, so try it now:
Exactly what we expected: the contents of a .git/, with no project files. And its configuration says so:
That git -C <path> is a handy trick: it runs the command as if you were inside that directory, without having to go there and come back.
This directory is a perfectly valid "server". You can push changes to it and clone from it. The only difference from GitHub is that it lives on your disk and has no web interface.
- Remote references:
.git/refs/remotes/
.git/refs/remotes/Here is the centrepiece of the lesson, and probably the concept that generates the most misunderstandings in the whole of Git.
In module 3 you learnt that a branch is a 41-byte file in .git/refs/heads/ with a hash inside it. Well then: there is a second, sibling directory, .git/refs/remotes/, holding files that are exactly the same.
Let us look at the repository Bruno cloned in lesson 02-02:
Two files with the same hash inside. The first is Bruno's main branch; the second is the remote reference origin/main.
The complete reference layout looks like this:
| Directory | Holds | Example name |
|---|---|---|
.git/refs/heads/ |
Your local branches | main, feature/csv-export |
.git/refs/remotes/<remote>/ |
Remote references | origin/main, origin/docs/update-notes |
.git/refs/tags/ |
Tags (lesson 05-05) | v1.2.0 |
And, as you saw in lesson 03-01, many of these references may end up compressed into .git/packed-refs instead of existing as loose files. You query them the same way:
git rev-parse resolves any reference name to its hash, wherever it happens to be stored. It is the robust way to query them and the one you should use in scripts.
origin/main is a local, read-only reference
origin/main is a local, read-only referenceNow for the important claim, the one you need to grasp for the rest of the module to make sense:
origin/mainis not on the server. It is on your disk. It is a note Git left itself saying "last time I spoke toorigin, itsmainbranch was at this commit".
Think of it as a dated photograph, not a live window. Three consequences follow, and they are worth committing to memory:
First: origin/main can be out of date, and usually is. If Bruno pushed three commits ten minutes ago and you have not run a fetch, your origin/main still points at yesterday's commit. Git has no way of knowing: there is no open connection and no notification. It only finds out when you ask it to talk to the server.
Second: it only updates at specific moments. Remote references change when you run git fetch, git pull (which does a fetch internally), git clone or a successful git push. At any other time they are frozen.
Third: you cannot work on it directly. It is read-only as far as your day-to-day work is concerned:
Git does not move you onto an origin/main branch, because it is not a branch of yours: it leaves you in detached HEAD on that commit, exactly the state you studied in lesson 03-02. And if you commit there, your commits will hang around with no branch holding them up.
In the same way, you cannot commit onto it or merge into it. What you can do — and will do constantly — is use it as a reference, just like any other commit name:
# What do I have that the server did not have last time I looked?
git log --oneline origin/main..main
# What did the server have that I do not?
git log --oneline main..origin/main
# What content differences are there?
git diff origin/main main
# Create a branch from it
git switch -c fix/urgent origin/main
# Merge its content into my current branch
git merge origin/mainAll the range and reference syntax from module 2 (.., ~, ^) works with them without any difference, because they are perfectly ordinary references: only the directory they live in and who updates them changes.
The diagram to remember
flowchart LR
subgraph LOCAL["Bruno's local repository"]
M["main<br/>(local branch)<br/>refs/heads/main"]
OM["origin/main<br/>(remote reference)<br/>refs/remotes/origin/main"]
end
subgraph SERVER["git.example.com (bare)"]
SM["main<br/>(the real branch)<br/>refs/heads/main"]
end
M -->|"git merge origin/main<br/>(local integration)"| OM
OM -->|"git fetch<br/>(refreshes the photo)"| SM
M -->|"git push<br/>(sends objects and moves the branch)"| SM
Three different things with similar names: your main, your origin/main and the server's main. Lesson 04-06 is devoted entirely to that distinction, because it is the source of most of the confusion. For now, hold on to this: the first two are on your disk; the third is not.
How to see them
That origin/HEAD is an extra created by git clone: it remembers which branch is the server's default. It is what lets you write git log origin as shorthand for git log origin/main, and what makes a clone land you on main rather than on some other branch.
- Naming conventions:
origin, upstream and the rest
origin, upstream and the restA remote's name is entirely up to you. It can be origin, server, bob or x. But there are well-established conventions worth respecting, because anyone joining the project — or any tutorial you read — will take them for granted:
| Name | Conventional meaning | When it shows up |
|---|---|---|
origin |
The repository you cloned from; the team's reference one | Set automatically by git clone |
upstream |
The original repository your personal copy came from | When working with forks (module 7) |
fork |
Your personal copy, when origin is the original project |
An alternative convention to the one above |
staging, production |
Deployment repositories | In push-based deployment workflows (module 10) |
backup, mirror |
A secondary copy of the repository | Redundancy |
A couple of words about upstream are in order now, to head off a classic confusion, because the word is used in Git with two completely different meanings:
upstreamas a remote name: the original project you forked. It is a plain naming convention, nothing special about it. Covered in lesson 07-01.- upstream as a tracking branch: the remote reference your local branch is paired with. This one really is a Git concept with configuration of its own, and it is the subject of lesson 04-06.
They are different things sharing a word. When you read "the branch has no upstream", it means the second sense.
Practical recommendation: call your team's reference repository origin and do not overthink it. The convention is so entrenched that departing from it only generates questions.
- Hosting platforms: what they add on top of Git
At this point it is worth being blunt to dispel a very widespread misunderstanding: GitHub is not Git. GitHub is a company that hosts Git repositories and adds services around them. Git worked before GitHub existed and would work just the same if it disappeared tomorrow.
Everything you have done across three modules, and everything you will do in this one, works against a bare repository on a server with SSH, with no platform in between. Platforms provide what Git deliberately does not.
| Platform | Model | Distinctive traits |
|---|---|---|
| GitHub | Commercial service; self-hosted option (Enterprise Server) | The largest ecosystem; Actions for automation; a huge open-source community |
| GitLab | Commercial service; free, self-hostable community edition | A complete DevOps platform: CI/CD, container registry, issue tracking, deployment |
| Gitea / Forgejo | Self-hosted free software | Very lightweight (a single binary); ideal for small servers or internal networks |
| Bitbucket | Commercial service (Atlassian) | Tight integration with Jira and the rest of the Atlassian toolset |
| Codeberg | Non-profit service built on Forgejo | Free hosting for open-source projects |
| SourceHut | Minimalist commercial service | An email-and-patches workflow, in the style of the Linux kernel |
What a platform adds exactly
- Hosting with availability and backups: the always-on machine no laptop can be.
- Access control: who reads, who writes, who administers; plus protected branches, which prevent
mainfrom being rewritten or deleted. - Change proposals (pull requests on GitHub, merge requests on GitLab): the conversation, review and approval of a set of commits before integrating it. It is a social layer on top of the
git mergeyou already know. Module 7. - Issue tracking, milestones and work boards.
- Continuous integration: running tests and deployments automatically on every push. Modules 7 and 10.
- Web interface: browsing the code, reading the history, comparing branches and viewing diffs without cloning anything.
- Documentation: rendered
README.md, wikis, project web pages. - Search and discovery: finding code and projects, which is what made GitHub what it is.
The point that matters for this module: none of those services changes how fetch, push or merge work. Learning Git properly serves you equally well on all six platforms, and moving from one to another means changing a URL.
- The complete mental map
Before moving on to practice, let us bring everything together in a single diagram of the journey a commit makes from Ana's keyboard to Carla's disk:
flowchart TB
subgraph A["Ana · Ubuntu"]
A1["Working<br/>tree"] -->|"git add"| A2["Index"]
A2 -->|"git commit"| A3["Local repository<br/>.git/objects"]
end
A3 -->|"git push origin main"| S["Bare server<br/>git.example.com"]
subgraph C["Carla · Windows 11"]
C3["Local repository<br/>.git/objects<br/>+ refs/remotes/origin/main"] -->|"git merge origin/main"| C1["Working<br/>tree"]
end
S -->|"git fetch origin"| C3
Pay attention to the asymmetry in the lower half. Carla's git fetch reaches only as far as her local repository: it updates origin/main and downloads objects, but it does not touch a single file in her working tree. A second step is needed — an integration, normally a merge — for Ana's work to appear in her files. That two-step separation is the heart of lesson 04-04, and it is what distinguishes fetch from pull.
And notice what does not appear in the diagram: nothing happens by itself. Every arrow is a command somebody runs.
Common Mistakes and Tips
Mistake 1: believing that origin is a reserved word in Git. It is not: it is the name git clone gives the remote by default, and it could be anything else. In git fetch origin, the word origin is a name configured in your .git/config, not part of the command's syntax.
Mistake 2: thinking that origin/main queries the server. It is a file on your disk with a hash inside. If you have not run fetch, it may be days out of date. When somebody tells you "but it is already on the server", your first reflex should be git fetch, not an argument.
Mistake 3: believing the server "has" your repository. Your repository is yours and it is complete on your disk. The server has another repository, one that happens to share history with yours. That is why you can work offline for a whole week.
Mistake 4: trying to push to a non-bare repository. If you set up your own server with git init instead of git init --bare, the first push will fail with branch is currently checked out. Repositories that receive pushes must be created with --bare.
Mistake 5: confusing the platform with Git. "GitHub will not let me force push to main" is not a limitation of Git but a protected-branch rule configured on the platform. Telling which layer is talking to you saves an enormous amount of debugging time.
Tip 1: set up a local bare to practise with. git init --bare /tmp/server/project.git gives you a real server, with no accounts, no passwords and no internet. The entire module can be done that way, and it is the best way to learn without fear of breaking anything.
Tip 2: get into the habit of running git remote -v first thing when you land in an unfamiliar repository. Together with git status and git log --oneline -5, it tells you where you are and who you are talking to.
Tip 3: always think in terms of "three different things". main, origin/main and the server's main. The moment a remote-related problem baffles you, ask yourself which of the three you are talking about. Nine times out of ten, that is where the answer is.
Exercises
Exercise 1: anatomy of a bare repository
Create a bare repository and a normal one in /tmp and answer with commands:
- What differences are there in each one's directory structure?
- What does
core.baresay in each one's configuration? - What happens if you run
git statusinside the bare one? - How much space does each take up when freshly created, and why is the difference tiny?
Exercise 2: remote references laid bare
Starting from a bare repository with some content, clone it twice to stand in for Bruno and Carla. Then:
- Locate the file on disk holding Carla's
origin/mainreference and show its contents. - Check that the hash matches the one on her local
mainbranch. - Have Bruno push a new commit to the bare repository.
- Without running
fetch, check that Carla'sorigin/mainstill points at the old commit. Explain why. - Use
git rev-parseto check the branch's real state in the bare repository.
Exercise 3: explaining it in your own words
Carla has just joined and writes to you: "So when I run git clone, am I downloading a shared folder? If I change something, does everyone else find out?"
Write a reply of between 150 and 250 words clarifying: what a remote is, why her repository is complete and independent, what origin/main is and when anything gets synchronised. Without using the word "magic" and without assuming anything the course has not covered.
Solutions
Solution 1:
Initialized empty Git repository in /tmp/comparison/normal/.git/ Initialized empty Git repository in /tmp/comparison/bare.git/
The message already shows the difference: one initialises normal/.git/ and the other bare.git/ directly.
The normal repository holds only .git; the bare one has that same content at its root.
# 2. The flag in the configuration
git -C /tmp/comparison/normal config core.bare
git -C /tmp/comparison/bare.git config core.bareThe message is literal: status compares the working tree against the index, and here there is no working tree to compare.
Practically identical: in both cases what takes up space is the empty directory structure and the template files in hooks/. A real difference would show up once there is content, and even then it would be small: the bare one only saves the deployed copy of the files, not the objects.
Solution 2:
# Set up the "server" with some content
mkdir -p /tmp/practice && cd /tmp/practice
git init --bare server.git
# A starting repository to feed it
git clone server.git initial
cd initial
echo "<h1>Task manager</h1>" > index.html
git add . && git commit -m "Add initial task manager structure"
git push origin main
cd ..
# The two clones
git clone server.git bruno
git clone server.git carla# 1. Carla's remote-reference file
find /tmp/practice/carla/.git/refs -type f
cat /tmp/practice/carla/.git/refs/remotes/origin/main/tmp/practice/carla/.git/refs/heads/main /tmp/practice/carla/.git/refs/remotes/origin/main /tmp/practice/carla/.git/refs/remotes/origin/HEAD 4f8c2a1e9b3d7f6a2c8e4b1d9f3a7c5e2b8d6f4a
(The hash will be different on your machine; the structure is what matters.)
Freshly cloned, both references point at the same commit.
# 3. Bruno works and pushes
cd /tmp/practice/bruno
echo "body { font-family: sans-serif; }" > styles.css
git add . && git commit -m "Add base styles for the list"
git push origin mainThe same hash as before. And the explanation is precisely the central idea of the lesson: origin/main is a file on Carla's disk that nobody has touched. Bruno wrote to the bare repository, not to Carla's laptop. Git has no notification mechanism whatsoever: the reference will only update when Carla runs fetch or pull.
A different hash: Bruno's commit. Carla's reference is out of date, and it will stay that way until she talks to the server.
# Final check: after the fetch, it catches up
git -C /tmp/practice/carla fetch origin
git -C /tmp/practice/carla rev-parse origin/mainAnd notice a detail that anticipates lesson 04-04: Carla's main is still on the old commit and her files have not changed. The fetch has only updated the photograph.
Solution 3:
Hello Carla. No, it is not a shared folder: it is rather better than that.
When you clone, you are not downloading a link to something remote but a complete, independent copy of the project, with all the history, all the branches and the whole object database. From that moment on you can commit, create branches, merge them and look up two-year-old history offline and without anybody's permission. Your repository is every bit as valid as the server's.
What the clone does record is where it came from: it stores the URL under the short name
origin. That is a remote, no more and no less: a name for a URL.As for whether everyone else finds out: no, and this is important. Nothing synchronises automatically. Your commits stay on your disk alone until you run
git push, and other people's do not reach you until you rungit fetchorgit pull. You will see references calledorigin/main: they are not the server, they are a note Git keeps on your own disk about how the server looked the last time you spoke to it. If you have not fetched for two days, that note is two days old.In short: you work locally, and you decide when to send and when to receive.
Conclusion
This lesson has built the mental model that holds up the whole module. The essentials:
- A remote is a short name for a URL stored in
.git/config. It is not a synchronised copy, nor an open connection, nor anything compulsory. Git can talk to a repository by being given the URL directly; the remote merely saves you repeating it. - Technically there is no central server. All Git repositories are equal and complete. The "reference" repository is such by team agreement, and the reasons for having one are organisational: availability, a point of agreement, backup, access control, automation and network directionality.
- A bare repository is a repository with no working tree: the contents of
.git/at the root. It is the correct way to set up a repository that receives pushes, because that way it cannot end up in an inconsistent state. What sits behind GitHub or GitLab is always a bare one. - Remote references live in
.git/refs/remotes/and are files identical to those of local branches.origin/mainis a local, read-only reference that remembers where the remote was the last time it was contacted. It updates only withfetch,pull,cloneorpush. main,origin/mainand the server'smainare three different things. The first two are on your disk.originandupstreamare naming conventions, not reserved words. And watch out: upstream also means something else — the tracking branch — which we will see in lesson 04-06.- Hosting platforms add services on top of Git (access control, change proposals, continuous integration, a web interface), but they do not change how Git works. Learning Git serves you equally well on all of them.
What comes next
You now know what a remote is. In lesson 04-02: Adding a Remote Repository we move on to practice: Ana finally publishes task-manager. We will register the remote with git remote add, inspect what appears with git remote -v and git remote show, learn to rename it, remove it and change its URL, and — above all — open .git/config to pick apart, calmly, that fetch = +refs/heads/*:refs/remotes/origin/* line we have been glimpsing for two modules without explanation. It is the refspec, the piece almost nobody understands and which, once grasped, stops fetch and push looking arbitrary.
Mastering Git: From Beginner to Advanced
Module 1: Introduction to Git
- What Is Git?
- Installing Git
- Basic Git Terminology
- The Git Data Model
- Configuring Git
- Initial Configuration
Module 2: Basic Git Operations
- Creating a Repository
- Cloning a Repository
- The Basic Git Workflow
- Staging and Committing Changes
- Inspecting Changes with git diff
- Viewing Commit History
Module 3: Branching and Merging
- Understanding Branches
- Creating and Switching Branches
- Merging Branches
- Merge Strategies
- Resolving Merge Conflicts
- Branch Management
Module 4: Working with Remote Repositories
- Understanding Remote Repositories
- Adding a Remote Repository
- Authenticating with Remote Repositories
- Fetching and Pulling Changes
- Pushing Changes
- Tracking Branches
Module 5: Advanced Git Operations
Module 6: Git Tools and Techniques
- Using Git Hooks
- Git Bisect
- Git Blame
- Git Log and Aliases
- Git Submodules
- Multiple Working Copies with git worktree
Module 7: Collaboration and Workflow Strategies
- Forks and Pull Requests
- Code Reviews with Git
- The Git Flow Workflow
- GitHub Flow
- Trunk Based Development
- Continuous Integration with Git
Module 8: Git Best Practices and Tips
- Writing Good Commit Messages
- Keeping a Clean History
- Ignoring Files with .gitignore
- File Attributes with .gitattributes
- Security Best Practices
- Performance Tips
Module 9: Troubleshooting and Debugging
- Common Git Problems
- Undoing Changes
- Resolving Divergence with the Remote
- Recovering Lost Commits
- Dealing with Corrupted Repositories
- Advanced Debugging Techniques
