Setup Local GIT SSH Server on Mac

Setting Up Example Git Server Locally to Accept SSH

This guide provides steps to set up a local Git server that accepts SSH connections on macOS, using built-in functionality and minimal custom configuration.

Prerequisites

Steps to Set Up the Git Server

SSH server setup

Setup

  1. Allow your terminal full disk access.

Example if using iTerm:

System Settings > Privacy & Security > full disk access > switch on for iTerm

  1. Enable SSH Server on macOS

    Ensure the SSH server is enabled on your macOS system:

    sudo systemsetup -setremotelogin on
    

    Verify SSH is enabled:

    sudo systemsetup -getremotelogin
    

    The output should indicate that remote login is enabled:

    Remote Login: On
    
  2. Set Up SSH Access

    Ensure your SSH keys are set up properly:

    • Generate an SSH key pair (if you don't have one, typically you already should have a key):

      ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
      
    • Copy the public key to the authorized_keys file:

      cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
      

      Note: the pre existing public key could have a different name. Such as

      cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
      
  3. Verify SSH Configuration for Git Access

    Ensure the following configurations are set in your SSH configuration file (/etc/ssh/sshd_config):

    PasswordAuthentication no
    PubkeyAuthentication yes
    ChallengeResponseAuthentication no
    

    Restart the SSH service to apply the changes:

    sudo launchctl stop com.openssh.sshd
    sudo launchctl start com.openssh.sshd
    

Git 'remote' Bare Repo setup

Bare Repo setup

In CLI

  1. Create a Directory for Git Repositories

    Create a directory to hold your Git repositories:

    mkdir -p ~/git-server/repos
    
  2. Initialize a Bare Git Repository

    Navigate to the repository directory and initialize a bare repository:

    cd ~/git-server/repos
    git init --bare test-repo.git
    

With JGit in kotlin:

In Kotlin
package com.thorg.core.git

import org.eclipse.jgit.api.Git
import java.io.File


// # Clone repo:
// cd "$HOME" && git clone "ssh://${USER:?}@localhost:22/Users/${USER:?}/git-server/repos/test-repo.git"
//
// # Wipe out previous repo:
// rm -rf "$HOME/git-server/repos/test-repo.git"
fun main(args: Array<String>) {

    val repoDir = File(
        System.getProperty("user.home") + "/git-server/repos/test-repo.git"
    )

    // Create the bare repository.
    //
    // This calls succeeds and appears to be a no-op if the repo already exists.
    Git.init()
        .setBare(true)
        .setDirectory(repoDir).call()
        .use { git ->
            System.out.println("Git repository at " + repoDir.getAbsolutePath())
        }
}

Example Commands for Git Operations

Example Commands for Git Operations

Adding Initial Content and Pushing to the Repository

  1. Clone the Repository Using SSH

    On the client machine, clone the repository using SSH:

    cd "$HOME" && git clone "ssh://${USER:?}@localhost:22/Users/${USER:?}/git-server/repos/test-repo.git"
    
  2. Navigate to the Cloned Repository

    cd "$HOME" && cd test-repo
    
  3. Add a New File

    echo "Initial content" > README.md
    git add README.md
    git commit -m "Initial commit"
    
  4. Push the Changes to the Remote Repository

    git push origin master
    

Fetching and Pulling Updates

  1. Fetch Updates from the Remote Repository

    git fetch origin
    
  2. Pull Updates

    git pull origin master
    

FAQs

Can we copy the contents of local-repo to remote-repo directly: NO

Why We Cannot Copy Local Repo Contents to Remote Directly

Why You Cannot Just Copy the Contents of local-repo to 'remote' Repo under git-server

When setting up a Git server, simply copying the contents of a working directory (local-repo) to the remote repository directory under git-server is not sufficient. Here's why:

1. Structure of Bare Repositories

A bare repository, which is what you need for a remote Git server, has a different structure compared to a working directory. A bare repository contains only the version control information (the .git directory) without a working directory. It is intended to be a centralized repository for collaboration.

  • Bare Repository:

    • Contains only Git data.
    • No working directory.
    • Typically ends with .git.
  • Working Directory:

    • Contains the actual files and directories being tracked by Git.
    • Includes a .git directory with the repository data.

2. Intended Usage

The intended usage of a bare repository is to serve as a central point for cloning, fetching, and pushing changes. This setup ensures that no working directory conflicts arise when multiple users interact with the repository.

3. Proper Setup

To properly set up a remote repository, you need to create a bare repository from your existing local repository. This can be done using the git clone --bare command. This command ensures that all the necessary Git data is preserved and correctly structured for use as a remote repository.

Example Commands

Creating a Bare Repository from a Local Repository:

# Create a bare repository directly in the remote directory
mkdir -p ~/git-server/repos
cd ~/local-repo
git clone --bare . ~/git-server/repos/test-repo.git

This command ensures that the test-repo.git directory under ~/git-server/repos is a valid bare repository suitable for remote interactions.

Summary

Simply copying the contents of a working directory (local-repo) to a remote repository location under git-server does not create a valid remote repository. Instead, you should use the git clone --bare command to create a bare repository, which is correctly structured for remote access and collaboration.

Security Considerations

  • Ensure only key-based authentication is allowed and password authentication is disabled. (Disable Password Auth (SSH Server MAC))
  • Use strong, complex SSH keys and keep your system and software updated.

Children
  1. Remote GIT Bare Repo Setup
  2. Setup
  3. Why We Cannot Copy Local Repo Contents to Remote Directly

Backlinks