Unlock Git’s Decentralized Power: From Bare Repos to Multi‑Account SSH & CI/CD
This article explains Git’s true decentralized architecture, details how repositories store snapshots, shows step‑by‑step how to create a private bare Git server, configure SSH keys for multiple accounts, and automate deployment with hooks and CI/CD scripts.
Git Series Articles
Project size demands a deeper understanding of Git branch management and collaboration strategies.
1. Git Push Principle and Protocol Analysis
1.1 Git Distributed File System
In essence, a Git repository is a normal folder containing a .git directory, which is the working directory or local repository . When you edit files, Git tracks changes via the .git folder. Each git commit creates a snapshot (a version).
Inspecting the .git directory shows its size is comparable to the total size of the working files because it stores the complete history of all branches, allowing restoration of any snapshot at any time.
1.2 Installation Steps
Git is a simple command‑line tool consisting of binary executables; it has no daemon or background service. For local use, Git can create versions and snapshots without any remote service.
# macOS install Git
brew install git
# Verify version
git --version1.3 Git Data Exchange Protocol
Git uses a highly efficient data‑exchange protocol built on the application layer. Objects (commit, tree, blob, etc.) are packed into a packfile . The client and server communicate via RPC to request data and push changes. The protocol itself is logical only; transport (HTTPS, SSH) provides security and stability.
1.4 Internal Data Structures
blob – stores file contents (each unique content has a SHA‑1/SHA‑256 hash).
tree – stores directory structure, pointing to blobs or sub‑trees.
commit – entry point of a snapshot (tree hash + parent commit + message).
refs/heads/ – stores branch pointers to commit IDs.
HEAD – points to the currently checked‑out branch.
1.5 Branch Switching, Deleting, Restoring
Switching branches moves HEAD to another commit and checks out the corresponding snapshot into the working directory.
Deleting a file records a snapshot without the file, while the history still retains previous versions.
Restoring a file retrieves the blob from an earlier commit and restores its contents.
2. Building a Private Git Service
Git operates over SSH; any two machines that can SSH to each other can pull and push.
2.1 Initialize a Bare Repository on Machine A
mkdir /User/usera/TestProServer
cd /User/usera/TestProServer
mkdir .git
cd .git
git init --bare2.2 SSH from Machine B to Machine A
macOS and Linux have SSH built‑in; Windows can use OpenSSH or third‑party tools.
# Check SSH service on macOS
sudo systemsetup -getremotelogin
ps -ef | grep sshd
# Check SSH service on CentOS
sudo systemctl status sshd
ps -ef | grep sshdAfter the first login (password entry), the terminal operates on Machine A.
2.3 Generate SSH Key on B and Copy to A
# Generate a new key (choose a safe path)
ssh-keygen -t rsa -b 4096 -C "your@email"
# Copy the public key to A
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
# Verify which key is used
ssh -v [email protected]2.4 Add Remote Repository on B (Sourcetree or CLI)
Using Sourcetree, drag a folder to initialise a Git repo, then set the remote URL to ssh://[email protected]:/User/usera/TestProServer/.git.
# Add remote via CLI
git remote add origin ssh://[email protected]:/User/usera/TestProServer/.git
# Clone the bare repo
git clone ssh://[email protected]:/User/usera/TestProServer/.git2.5 Create a Working Clone on A for Visibility
git clone /User/usera/TestProServer/.git /User/usera/TestProServerWorkThe bare repo accepts push/pull; the working clone provides source files and can be used for automatic deployment.
2.6 Post‑Receive Hook for Auto‑Deployment
#!/bin/bash
GIT_WORK_TREE=/User/usera/TestProServerWork git checkout -fWhen B pushes, A automatically updates the working directory.
2.7 Semi‑Automatic CI/CD Workflow
Trigger a script on push to build and deploy a Spring Boot project.
#!/bin/bash
# ==== Configuration ====
PROJECT_DIR="/opt/myproject"
BRANCH="master"
JAR_NAME="myapp.jar"
JAVA_OPTS="-Xms512m -Xmx1024m"
LOG_FILE="/opt/myproject/app.log"
# =====================
echo "==== [$(date)] Starting deployment ===="
cd "$PROJECT_DIR" || { echo "Project directory not found"; exit 1; }
echo "Fetching latest code..."
git fetch origin
git checkout "$BRANCH"
git pull origin "$BRANCH"
echo "Building with Maven..."
mvn clean package -DskipTests || { echo "Maven build failed"; exit 1; }
echo "Stopping old application..."
PID=$(pgrep -f "$JAR_NAME")
if [ -n "$PID" ]; then
kill -9 "$PID"
echo "Stopped PID=$PID"
else
echo "No running instance found"
fi
echo "Starting new application..."
nohup java $JAVA_OPTS -jar "target/$JAR_NAME" > "$LOG_FILE" 2>&1 &
echo "Deployment complete! Logs: $LOG_FILE"This mirrors the basic Jenkins workflow: listen for changes, run build steps, and deploy.
3. SSH Management of Multiple Git Accounts
3.1 View and Set Global User
# Show current global config
git config --global user.name
git config --global user.email
# Set a secondary account globally (if needed)
git config --global user.name "Secondary Name"
git config --global user.email "[email protected]"3.2 Generate Separate SSH Keys for Each Account
# Primary account
ssh-keygen -t rsa -C "[email protected]" -f ~/.ssh/id_rsa
# Secondary account
ssh-keygen -t rsa -C "[email protected]" -f ~/.ssh/id_rsa_gitee_alt3.3 Add Public Keys to Gitee Accounts
Log into each Gitee account, go to Settings → SSH Keys, and paste the corresponding .pub file.
3.4 Configure ~/.ssh/config with Host Aliases
# Primary account
Host gitee-main
HostName gitee.com
User git
IdentityFile ~/.ssh/id_rsa
# Secondary account
Host gitee-linshidream
HostName gitee.com
User git
IdentityFile ~/.ssh/id_rsa_gitee_altUse the alias (e.g., gitee-linshidream) in remote URLs.
3.5 Per‑Repository User Configuration
# Inside a specific repo
git config user.name "Secondary Name"
git config user.email "[email protected]"
# Verify
git config user.name
git config user.email
# Reset global config to primary account when done
git config --global user.name "Primary Name"
git config --global user.email "[email protected]"This achieves per‑repository email settings for multi‑account collaboration.
4. Git and P2P Decentralization
4.1 Decentralization Meaning
Decentralization means there is no single central server; any node can push/pull from any other node, allowing development even when offline.
4.2 Git vs. Strict P2P
Git is not a full P2P system like BitTorrent—it lacks automatic node discovery and chunk exchange—but its data model is fully decentralized: each repository holds the complete history and can act as a temporary hub.
4.3 Design Insight
Git separates the transport layer (HTTPS, SSH) from its own object protocol, a pattern common in many software systems (e.g., messaging apps that support multiple transports but share a single message processor).
4.4 Git as a Personal Cloud Drive
Because of its decentralization, Git can be used as a simple personal cloud drive by pushing new files to a central server and cloning to other devices. Large files require Git LFS.
In summary, understanding Git’s decentralized architecture, private server setup, multi‑account SSH configuration, and CI/CD automation provides a solid foundation for modern software development workflows.
Lin is Dream
Sharing Java developer knowledge, practical articles, and continuous insights into computer engineering.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
