Getting Started with Git and Version Control

Chapter 6
Remote Repositories and Authentication

Diploma in Data science
Getting Started with Git and Version Control   •   Diploma

Remote Repositories and Authentication

Introduction

Git is a distributed version-control system. Unlike a centralised system in which developers depend on one main server, each Git clone contains a complete repository history. This design supports offline work, experimentation, and recovery. However, collaborative development requires repositories to exchange commits. A remote repository provides that collaboration point.

Remote repositories may be hosted on platforms such as GitHub, GitLab, Bitbucket, or an organisation’s own Git server. They store shared branches, tags, issues, pull or merge requests, and access-control policies. Working effectively with remotes requires more than memorising commands: a developer must understand the distinction between local branches, remote-tracking branches, and branches on the remote server; must authenticate securely; and must synchronise changes without accidentally overwriting other people’s work.

This chapter develops those concepts and applies them to an illustrative data-science project.

Learning Objectives

By the end of this chapter, you should be able to:

  • explain the purpose and structure of a remote repository;
  • distinguish a local branch, a remote branch, and a remote-tracking branch;
  • configure a remote and inspect its URLs;
  • use fetch, pull, and push appropriately;
  • configure and use SSH keys or personal access tokens;
  • establish and interpret upstream tracking relationships;
  • explain forks, upstream repositories, and synchronisation workflows;
  • diagnose common authentication and divergence problems; and
  • apply secure and professional practices when collaborating with data and code.

1. The Remote Repository Model

A remote is a named reference to another Git repository. The conventional name for the primary remote is origin, but the name is only a label and has no special technical status. A repository can have several remotes, for example:

  • origin: the repository owned by a developer or team;
  • upstream: the original project from which a fork was created;
  • course: a teaching repository; or
  • deployment: a repository used by an automated deployment process.

A remote normally has one or more URLs. The fetch URL identifies where Git obtains data; the push URL identifies where Git sends data. They may be identical, although organisations sometimes use different URLs for reading and writing.

Useful inspection commands include:

git remote -v
git remote show origin
git config --get-regexp '^remote\.'

A remote is not a second working directory on the local computer. It is a configuration entry that tells Git how to communicate with another repository. The actual exchange occurs through protocols such as HTTPS or SSH.

Local branches and remote-tracking branches

Suppose a remote called origin contains a branch named main. On a local machine, three related but distinct concepts may exist:

  1. Remote branch: the branch reference stored in the repository reached through the remote server.
  2. Remote-tracking branch: the local record origin/main, representing the last remote state known to the local repository.
  3. Local branch: a branch such as main, on which the developer makes commits.

The remote-tracking reference is updated by communication with the remote, especially by git fetch. It is not automatically updated every time another developer pushes. Therefore, origin/main can become stale until the local repository fetches again.

A useful conceptual model is:

Remote server:       main: A — B — C
                              
Local knowledge:      origin/main: A — B — C
Local work:           main:       A — B — D

Here, the local branch and the remote-tracking branch have diverged. The commit D exists only locally, while C is known as the latest remote commit. A later fetch may reveal that the remote has advanced further.

2. Fetch, Pull, and Push

Fetch: obtain information without changing the working tree

The command:

git fetch origin

contacts origin, downloads new objects and references, and updates remote-tracking branches such as origin/main. It does not normally modify the current local branch, index, or working files. This makes fetch a safe inspection operation.

To fetch all configured remotes:

git fetch --all --prune

The --prune option removes local remote-tracking references for branches that no longer exist on the remote. It does not delete local branches.

After fetching, inspect the differences before integrating them:

git log --oneline --graph --decorate --all
git diff main origin/main
git status

Pull: fetch and integrate

In its common form:

git pull origin main

is conceptually equivalent to fetching from origin and then integrating origin/main into the current branch. The integration may use a merge or a rebase, depending on configuration and options.

A merge-based pull may create a merge commit when both local and remote histories contain unique commits. A rebase-based pull replays local commits on top of the updated remote history. Rebase can produce a linear history, but it rewrites the identities of the rebased commits. It should not be used casually on commits that have already been shared and based upon by others.

Explicit forms are often clearer:

git fetch origin
git merge origin/main

or:

git fetch origin
git rebase origin/main

Before pulling, commit or temporarily store local work. A pull with uncommitted changes may be refused or may produce confusing conflicts. git stash can temporarily store changes, but a purposeful commit on a private branch is often easier to understand and recover.

Push: publish local commits

The command:

git push origin main

requests that the remote branch main be advanced to include the local branch’s commits. Git normally rejects a push that would discard commits already present on the remote. This is called a non-fast-forward rejection.

A first push commonly establishes an upstream relationship:

git push -u origin feature/clean-data

The -u option, also written --set-upstream, records that the local branch tracks origin/feature/clean-data. Later, git push and git pull can infer the destination.

The option --force-with-lease may be appropriate when rewriting a branch that the user owns, but it must be used deliberately:

git push --force-with-lease origin feature/experiment

It is safer than --force because it checks that the remote branch is still at the expected state. Neither option should be used on a protected shared branch without explicit authorisation.

3. Tracking Branches and Upstream Relationships

A local branch may have an upstream branch, which is the default remote branch used for comparison, pulling, and pushing. The relationship can be examined with:

git branch -vv
git status -sb
git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}'

For a local branch main tracking origin/main, Git can report that it is:

  • ahead by commits that can be pushed;
  • behind by commits that can be integrated; or
  • diverged, meaning both sides contain unique commits.

Tracking simplifies commands but does not eliminate the need for judgement. A branch can track the wrong remote branch, and an upstream relationship does not imply that integration is always safe.

To create a local branch from a remote-tracking branch:

git switch --track -c feature/model origin/feature/model

Modern Git may infer the tracking relationship with:

git switch feature/model

if exactly one suitable remote branch exists. Explicit commands are preferable in teaching, scripts, and ambiguous repositories.

4. Integration Strategies and Conflicts

Suppose a local branch and its upstream have diverged. A developer should first fetch and inspect:

git fetch origin
git log --oneline --left-right HEAD...origin/main

The output distinguishes commits reachable only from the local side from those reachable only from the remote side.

Merge

git merge origin/main

Merge preserves both lines of development and may create a merge commit. It is transparent and appropriate when preserving the historical branching structure is important.

Rebase

git rebase origin/main

Rebase places local commits after the updated upstream. If a conflict occurs:

git status
# edit conflicted files
git add path/to/resolved-file
git rebase --continue

To abandon the operation:

git rebase --abort

For a merge conflict, the corresponding commands are git add followed by git commit, or git merge --abort to return to the pre-merge state.

Conflict markers such as <<<<<<<, =======, and >>>>>>> are instructions for human resolution, not content that should normally remain in a finished file. In data-science projects, conflicts may occur in notebooks, dependency files, YAML configuration, SQL, and source code. Notebook conflicts are particularly difficult because JSON metadata and output cells can be changed together. Teams should minimise committed outputs and use clear notebook-review practices.

5. Authentication and Authorisation

Authentication answers “Who are you?” Authorisation answers “What are you permitted to do?” A successful network connection does not guarantee permission to push. Repository visibility, branch protection, organisation membership, and token scopes determine authorisation.

HTTPS and personal access tokens

When using HTTPS, a hosting service may require a username and a personal access token (PAT) instead of an account password. A token is a credential that can be limited by repository, scope, expiration, and other policies. The exact interface differs among hosting providers.

A typical HTTPS remote has a form similar to:

https://host.example/team/project.git

When prompted, the user supplies the account name and token through the approved credential manager. Tokens should not be placed in the remote URL, shell history, notebooks, source files, or documentation. A credential helper can store or retrieve credentials securely, depending on the operating system and organisational policy.

Good token practice includes:

  • grant the minimum scopes needed;
  • set an expiration date;
  • use separate tokens for separate purposes when practical;
  • rotate or revoke tokens when exposure is suspected; and
  • never commit tokens, cloud keys, database passwords, or .env files containing secrets.

If a secret is committed, deleting it from the latest file is not sufficient: it may remain in earlier commits, forks, caches, or build logs. The credential must be revoked or rotated first, followed by an appropriate history-removal and incident-response process.

SSH keys

SSH authentication uses a key pair:

  • the private key remains on the user’s device and must be protected; and
  • the public key is registered with the hosting service.

A key can be generated with a modern algorithm such as Ed25519:

ssh-keygen -t ed25519 -C "[email protected]"

The private key should normally be protected with a passphrase. An SSH agent can make the key available after the passphrase is entered, without repeatedly exposing the private key to applications.

An SSH remote may look like:

[email protected]:team/project.git

Connection testing depends on the hosting service, but commonly takes the form:

ssh -T [email protected]

The first connection may ask the user to verify the server’s host key. This check matters: accepting an unverified key can expose the user to a man-in-the-middle attack. In professional environments, compare the fingerprint with a trusted provider or administrator record.

SSH is convenient for repeated development, while HTTPS with a managed token may integrate more easily with enterprise identity systems. Neither method is automatically secure if private keys or tokens are mishandled.

6. Forks and Upstream Repositories

A fork is a server-side copy of a repository under another user or organisation account. A fork allows a contributor to push branches without direct write permission to the original project. The contributor can propose changes through a pull request or merge request.

A common fork configuration is:

origin   → contributor’s fork
upstream → original project

The names are conventions. The important point is the destination represented by each URL.

To add the original project as upstream:

git remote add upstream https://host.example/original/project.git
git fetch upstream

To update a local base branch from the original project:

git switch main
git fetch upstream
git merge upstream/main

Alternatively, use git rebase upstream/main when the local branch is private and a linear history is desired. Then update the fork:

git push origin main

A feature workflow is usually safer:

git switch main
git fetch upstream
git merge upstream/main
git switch -c feature/improve-validation
# edit, test, and commit
git push -u origin feature/improve-validation

The contributor then opens a pull request from the fork branch to the original project’s target branch. Review, automated tests, and maintainers’ policies determine whether it is merged.

7. Synchronisation as a Controlled Process

Synchronisation should be treated as a sequence of observations and decisions rather than as a single command. A reliable process is:

  1. inspect the working tree with git status;
  2. preserve or commit local work;
  3. fetch from the relevant remote;
  4. inspect commits and differences;
  5. choose merge or rebase according to project policy;
  6. resolve and test conflicts;
  7. push to an authorised branch; and
  8. verify the resulting remote state.

For a fork, synchronisation has two dimensions: bringing the fork up to date with upstream, and publishing that updated state to origin. These are separate operations. Fetching upstream does not update the fork automatically, and pushing to origin does not retrieve new work from the original project.

Automation can assist with synchronisation. Continuous-integration systems may fetch a pull request, run tests, check formatting, scan dependencies, and report status. Automation improves reliability but cannot decide whether a changed data definition, model assumption, or business rule is conceptually correct.

8. Applied Case: A Collaborative Data-Quality Project

Background

This illustrative case concerns a student team developing a Python pipeline that validates a public transport dataset. The original project is maintained by a university laboratory. Each student works from a fork because the team does not have direct write access to the laboratory repository.

Problem

The team’s fork contains a main branch that is two weeks behind the laboratory’s upstream/main. One student has added a validation rule locally, while another student has updated the project’s dependency file in the laboratory repository. A direct push from the first student is rejected because the remote branch has advanced.

Analysis

The student first checks the state:

git status
git branch -vv
git remote -v

The output shows that origin is the student team’s fork and upstream is the laboratory repository. The working tree contains a committed feature branch, so no uncommitted changes need protection.

Approach and solution

The team updates its knowledge of the laboratory repository:

git fetch upstream

It inspects the new commits and updates local main:

git switch main
git merge upstream/main

A conflict occurs in requirements.txt. The team keeps the laboratory’s security-patched dependency version and retains a compatible package required by the validation code. After testing in a clean virtual environment, it completes the merge and pushes the updated base branch to the fork:

git add requirements.txt
git commit
git push origin main

The student then rebases the private feature branch onto the updated main:

git switch feature/validation-rule
git rebase main

After running unit tests and checking that no credentials or raw restricted data were included, the student publishes the branch:

git push -u origin feature/validation-rule

A pull request is opened against the laboratory’s main branch.

Outcome

The team’s fork now contains the current upstream base, the feature branch is based on current dependencies, and the laboratory can review a focused change. The feature branch was not pushed with an unsafe ordinary force operation; if the rebase had rewritten an already published branch, the team would have considered --force-with-lease only after agreement.

Learning points

  • A fork and an upstream repository serve different purposes.
  • Fetching is separate from integration.
  • A rejected push protects remote commits from accidental loss.
  • Dependency conflicts require testing, not merely textual resolution.
  • Data-science repositories require attention to secrets, data licences, privacy, and reproducibility.

9. Professional, Ethical, and Governance Considerations

Remote repositories create an audit trail, but an audit trail is not a substitute for governance. Teams should define who may create branches, approve changes, merge protected branches, release data, and rotate credentials.

Important controls include branch protection, mandatory review, status checks, signed commits where appropriate, dependency scanning, secret scanning, and least-privilege access. Access should be removed promptly when a person leaves a project. Shared accounts and shared private keys weaken accountability and should be avoided.

Data scientists must also distinguish code from data rights. A publicly reachable repository does not automatically grant permission to copy, redistribute, or combine a dataset. Personal data, confidential records, and regulated information require appropriate legal and institutional controls. Large datasets should generally not be committed directly to ordinary Git history; teams may use approved artifact stores, data-versioning tools, or documented download procedures.

Reproducibility requires recording relevant code, environment specifications, data provenance, preprocessing decisions, and model configuration. However, reproducibility must be balanced with privacy and security. A repository should not expose identifiable data merely to make an analysis easy to reproduce.

10. Common Problems and Diagnostic Practices

SymptomLikely causeSuitable response
repository not foundIncorrect URL or insufficient permissionInspect git remote -v; verify access and repository name
permission denied (publickey)SSH key absent, unregistered, or not selectedTest the agent, inspect key registration, and verify the host
HTTPS repeatedly asks for credentialsCredential helper or token problemUse an approved credential manager and valid, unexpired token
non-fast-forward rejectionRemote contains commits not in local branchFetch, inspect, then merge or rebase
unrelated historiesRepositories were created independentlyConfirm that combining them is intended before using special options
conflict during pullBoth histories changed overlapping contentResolve carefully, test, and complete or abort the operation
secret detected by serverCredential or sensitive file was pushedRevoke or rotate the secret immediately and follow incident policy

When diagnosing a failure, record the exact command and message, inspect the remote URL without exposing credentials, and avoid repeatedly trying destructive commands. git reflog can often help recover local branch positions after an accidental reset or rebase, although recovery is time-sensitive and remote-side recovery may require an administrator.

11. Best-Practice Workflow

A practical default workflow is:

git switch main
git fetch --prune origin
git pull --ff-only origin main
git switch -c feature/descriptive-name
# edit files
git status
git diff
git add selected-files
git commit -m "Add descriptive validation rule"
git fetch origin
git rebase origin/main
git push -u origin feature/descriptive-name

The --ff-only option refuses to create an implicit merge when local and remote histories have diverged. This encourages the developer to make the integration decision explicitly. Project policies may instead require merge commits or pull-based integration; the policy should be followed consistently.

Keep commits focused, write messages that describe intent, review the staged diff, run tests before pushing, and avoid committing generated files unless the project requires them. Prefer short-lived feature branches and integrate them regularly. Treat branch names, remote names, and authentication configuration as part of the project’s operational documentation.

Contemporary Developments

Modern hosting platforms increasingly combine Git with identity providers, multifactor authentication, fine-grained tokens, temporary credentials, protected environments, and automated policy checks. Developers may also use command-line clients that manage pull requests and authentication through an organisation’s single sign-on system. These tools improve usability but do not remove the underlying concepts of remotes, references, authentication, authorisation, and integration.

Large monorepositories, partial clones, sparse checkouts, and large-file extensions address scale and storage challenges. Data-science teams may also connect Git workflows with experiment trackers, model registries, and data-versioning systems. These technologies extend Git; they do not change the need to understand what has been fetched, what has been integrated, and what has been published.

Chapter Summary

Remote repositories enable Git collaboration while preserving the distributed nature of local repositories. git fetch updates local knowledge without changing the working tree; git pull fetches and integrates; and git push publishes local commits subject to permission and history-safety checks. Local branches, remote branches, and remote-tracking branches are distinct, and upstream tracking relationships make routine synchronisation more convenient.

HTTPS commonly uses personal access tokens, while SSH uses protected key pairs. Both require secure credential handling and appropriate authorisation. Forks allow contribution without direct write access, while an upstream remote identifies the original project. Reliable synchronisation involves inspection, fetching, deliberate integration, testing, and controlled publication. Professional practice also requires branch protection, secret management, data governance, privacy awareness, and reproducibility.

Key Terms

Remote repository: A Git repository accessed through a network connection.

Remote: A named configuration that identifies another repository.

Origin: The conventional name for a primary remote.

Upstream: A configured remote representing an original or authoritative project.

Remote branch: A branch reference stored in a remote repository.

Remote-tracking branch: A local reference recording the last known state of a remote branch.

Tracking branch: A local branch associated with an upstream branch.

Fetch: The operation of downloading remote objects and references without integrating them.

Pull: A fetch followed by an integration operation.

Push: The operation of publishing local commits to a remote repository.

Fork: A server-side copy of a repository under another account or organisation.

Personal access token: A scoped credential used for authenticated access, commonly over HTTPS.

SSH key pair: A public and private key used for cryptographic authentication.

Authentication: Verification of an identity.

Authorisation: Determination of permitted actions.

Fast-forward: An update in which the destination reference can move directly to a descendant commit.

Non-fast-forward rejection: A refusal to update a remote because doing so might discard remote commits.

Merge: Integration that preserves separate lines of development and may create a merge commit.

Rebase: Integration that replays commits onto a new base and changes their identities.

Pull request: A platform-based proposal to review and integrate changes.

Review Questions

Short Answer Questions

  1. What is the difference between a remote branch and a remote-tracking branch?
  2. Why is git fetch generally safer for inspection than git pull?
  3. What purpose does the -u option of git push serve?
  4. Distinguish authentication from authorisation.
  5. Why might a contributor configure both origin and upstream?

Long Answer Questions

  1. Explain the complete lifecycle of fetching, integrating, testing, and pushing changes to a shared branch.
  2. Compare HTTPS with a personal access token and SSH-key authentication, including security practices for each.
  3. Explain merge and rebase, and discuss when each may be appropriate.
  4. Describe a fork-based contribution workflow from synchronising with upstream to opening a pull request.
  5. Discuss why secret management, privacy, licensing, and branch protection matter in data-science repositories.

Analytical / Application Questions

  1. Your push is rejected as non-fast-forward, and your local branch contains two valuable commits. Describe the commands and reasoning you would use to integrate the remote work without losing either history.
  2. A team discovers that a cloud API token was committed three months ago and appears in several branches. Design an incident-response sequence that addresses immediate risk, repository history, and future prevention.
  3. A data-science fork is six weeks behind its upstream repository, while a feature branch contains unreviewed notebook changes. Propose a synchronisation plan that minimises conflict risk and preserves reproducibility.

Multiple Choice Questions with Answers

Question 1

Which command updates remote-tracking branches without normally changing the current working files?

A. git fetch

B. git commit

C. git push

D. git reset --hard

Correct Answer: A. git fetch

Question 2

What does git push -u origin feature/model establish?

A. A new Git repository

B. An upstream tracking relationship for the local branch

C. A merge between main and feature/model

D. An SSH key

Correct Answer: B. An upstream tracking relationship for the local branch

Question 3

In a typical fork workflow, what does origin usually identify?

A. The original project only

B. The contributor’s fork

C. The local working directory

D. The credential manager

Correct Answer: B. The contributor’s fork

Question 4

Which credential is commonly used instead of an account password for HTTPS Git access?

A. A merge commit

B. A remote-tracking branch

C. A personal access token

D. A working-tree lock

Correct Answer: C. A personal access token

Question 5

What is the primary purpose of git push --force-with-lease?

A. To fetch all remotes

B. To rewrite a remote branch while checking that it has not unexpectedly advanced

C. To encrypt a repository

D. To create a fork automatically

Correct Answer: B. To rewrite a remote branch while checking that it has not unexpectedly advanced

Question 6

A non-fast-forward push rejection most directly indicates that:

A. The local repository has no commits

B. The remote contains commits not included in the proposed update

C. The SSH private key is always invalid

D. The working tree is necessarily clean

Correct Answer: B. The remote contains commits not included in the proposed update

Question 7

Which file should normally remain private when using SSH authentication?

A. The public key

B. The repository README

C. The private key

D. The branch name

Correct Answer: C. The private key

Question 8

What does git pull commonly perform?

A. Commit followed by push

B. Fetch followed by integration

C. Branch deletion followed by fetch

D. Token generation followed by merge

Correct Answer: B. Fetch followed by integration

Question 9

After rebasing a private feature branch onto updated main, what should normally be done before opening a pull request?

A. Delete all remote branches

B. Run relevant tests and push the feature branch

C. Commit a private key

D. Disable branch protection

Correct Answer: B. Run relevant tests and push the feature branch

Question 10

If a secret is committed and pushed, what is the most urgent first response?

A. Rename the branch only

B. Revoke or rotate the exposed secret

C. Run git status and do nothing else

D. Add the secret to another commit

Correct Answer: B. Revoke or rotate the exposed secret

Getting Started with Git and Version Control
Chapter 6 of 14