Skip to content

Latest commit

 

History

History
1701 lines (1226 loc) · 40.6 KB

07-init-clone.md

File metadata and controls

1701 lines (1226 loc) · 40.6 KB

创建与克隆仓库完全指南

本章是 Git 仓库创建与克隆的深度教程,涵盖从零开始创建本地仓库、从远程克隆仓库的各种方式与高级技巧。无论你是初学者还是有一定经验的开发者,都能在这里找到实用的操作指南。


目录


1. git init 详解(初始化本地仓库)

1.1 什么是 git init

git init 是 Git 中最基础的命令之一,它的作用是在当前目录下创建一个全新的 Git 仓库。执行该命令后,Git 会在当前目录下生成一个名为 .git 的隐藏目录,这个目录包含了 Git 进行版本控制所需的所有元数据和配置信息。

.git 目录的内部结构如下:

.git/
├── HEAD          # 指向当前分支的指针
├── config        # 仓库级别的配置文件
├── description   # 仓库描述(GitWeb 使用)
├── hooks/        # Git 钩子脚本目录
├── info/         # 全局排除文件信息
├── objects/      # 存储所有数据对象(提交、树、blob)
│   ├── info/
│   └── pack/
├── refs/         # 存储分支和标签的指针
│   ├── heads/    # 本地分支
│   └── tags/     # 标签
└── logs/         # 引用日志

1.2 基本用法

# 在当前目录初始化 Git 仓库
git init

# 创建新目录并初始化
git init my-project

# 初始化一个空的 Git 仓库(不创建 .git 目录中的模板文件)
git init --bare my-project.git

1.3 git init 的各种参数

# 指定初始分支名称(Git 2.28+)
git init -b main
git init --initial-branch=main

# 使用指定模板目录
git init --template=/path/to/template

# 将仓库初始化为共享仓库
git init --shared=group

# 在已有目录中重新初始化(安全操作,不会覆盖已有数据)
git init

1.4 深入理解 git init 的工作原理

当你执行 git init 时,Git 实际上完成了以下操作:

第一步:创建 .git 目录结构

Git 会创建完整的目录层级,包括 objects、refs/heads、refs/tags、hooks 等子目录。

第二步:创建初始引用

Git 会创建 HEAD 文件,其内容通常为 ref: refs/heads/main(或 ref: refs/heads/master,取决于你的 Git 配置),表示当前指向 main 分支。

第三步:创建配置文件

生成仓库级别的 .git/config 文件,其中包含该仓库的默认配置。

第四步:创建模板文件

如果指定了模板目录,Git 会将模板中的钩子脚本等文件复制到 .git/hooks 目录中。

1.5 在已有项目中初始化 Git

如果你已经有一个包含代码的项目目录,可以直接在其中执行 git init:

# 进入项目目录
cd /path/to/existing-project

# 初始化 Git 仓库
git init

# 查看状态
git status

# 添加所有文件到暂存区
git add .

# 创建第一次提交
git commit -m "Initial commit: add existing project files"

1.6 修改默认分支名称

从 Git 2.28 开始,你可以通过配置来改变默认的初始分支名称:

# 全局设置默认分支名为 main
git config --global init.defaultBranch main

# 之后执行 git init 时,初始分支将自动命名为 main
git init my-new-project

1.7 git init 与 git clone 的区别

特性 git init git clone
创建方式 从零开始创建新仓库 从已有仓库复制
数据来源 无,空仓库 包含完整的提交历史
远程仓库 不自动关联 自动设置 origin 远程
适用场景 全新项目 参与已有项目

2. git clone 详解(克隆远程仓库)

2.1 什么是 git clone

git clone 命令用于将一个远程仓库完整地复制到本地。克隆操作不仅会下载仓库中的所有文件,还会包含完整的提交历史、分支信息、标签等所有版本控制数据。克隆完成后,本地仓库与远程仓库完全一致,你可以立即开始工作。

2.2 基本用法

# 克隆远程仓库到当前目录
git clone https://github.com/user/repo.git

# 克隆到指定目录名
git clone https://github.com/user/repo.git my-local-name

# 克隆并指定本地目录
git clone https://github.com/user/repo.git /path/to/local/dir

2.3 git clone 的完整执行流程

当你执行 git clone 时,Git 会按顺序完成以下步骤:

第一步:创建目标目录

Git 在当前目录下创建一个与仓库同名的目录(或使用你指定的目录名)。

第二步:初始化本地仓库

在目标目录中执行 git init,创建 .git 目录结构。

第三步:添加远程仓库引用

自动将源仓库地址添加为名为 origin 的远程仓库。

第四步:获取远程数据

从远程仓库下载所有对象(提交、树、blob)和引用(分支、标签)。

第五步:检出工作目录

将 HEAD 指向的分支(通常是 main)的最新提交检出到工作目录中。

第六步:设置上游跟踪

为本地分支设置远程跟踪分支,使得 git pull 和 git push 可以正常工作。

2.4 git clone 的常用参数

# 仅克隆特定分支
git clone -b develop https://github.com/user/repo.git

# 浅克隆(只获取最近 N 次提交)
git clone --depth 1 https://github.com/user/repo.git

# 克隆时不检出工作目录(适用于 CI/CD)
git clone --no-checkout https://github.com/user/repo.git

# 克隆时指定进度显示
git clone --progress https://github.com/user/repo.git

# 安静模式(减少输出信息)
git clone -q https://github.com/user/repo.git

# 克隆时使用稀疏检出
git clone --filter=blob:none --sparse https://github.com/user/repo.git

2.5 克隆后的仓库状态

克隆完成后,你可以使用以下命令查看仓库状态:

# 查看远程仓库信息
git remote -v
# origin  https://github.com/user/repo.git (fetch)
# origin  https://github.com/user/repo.git (push)

# 查看所有分支(包括远程分支)
git branch -a
# * main
#   remotes/origin/main
#   remotes/origin/develop

# 查看当前分支状态
git status
# On branch main
# Your branch is up to date with 'origin/main'.
# nothing to commit, working tree clean

3. 克隆方式对比(HTTPS vs SSH vs GitHub CLI)

3.1 HTTPS 方式克隆

URL 格式: https://github.com/用户名/仓库名.git

git clone https://github.com/octocat/Hello-World.git

优点:

  • 不需要额外配置,开箱即用
  • 穿过防火墙更容易(通常只开放 443 端口)
  • 适合初学者和临时使用
  • 可以使用凭据管理器缓存密码

缺点:

  • 每次推送需要输入用户名和密码(除非配置了凭据缓存)
  • 速度相对较慢(HTTP 协议开销)
  • 在国内网络环境下可能不稳定

配置凭据缓存:

# 缓存凭据 15 分钟(默认)
git config --global credential.helper cache

# 缓存凭据 1 小时(3600 秒)
git config --global credential.helper 'cache --timeout=3600'

# 永久存储凭据(明文存储在磁盘上,安全性较低)
git config --global credential.helper store

# macOS 系统使用钥匙串
git config --global credential.helper osxkeychain

# Windows 系统使用凭据管理器
git config --global credential.helper manager

3.2 SSH 方式克隆(推荐)

URL 格式: git@github.com:用户名/仓库名.git

git clone git@github.com:octocat/Hello-World.git

优点:

  • 安全性高,使用密钥对认证
  • 无需每次输入密码
  • 传输速度快
  • 适合日常开发和自动化场景

缺点:

  • 需要事先配置 SSH 密钥
  • 某些企业防火墙可能屏蔽 SSH 端口(22)
  • 密钥管理需要额外注意安全

SSH 密钥配置步骤:

# 1. 生成 SSH 密钥对
ssh-keygen -t ed25519 -C "your_email@example.com"

# 2. 启动 ssh-agent
eval "$(ssh-agent -s)"

# 3. 添加私钥到 ssh-agent
ssh-add ~/.ssh/id_ed25519

# 4. 复制公钥内容
# macOS
pbcopy < ~/.ssh/id_ed25519.pub
# Linux(需要安装 xclip)
xclip -selection clipboard < ~/.ssh/id_ed25519.pub
# Windows (Git Bash)
clip < ~/.ssh/id_ed25519.pub

# 5. 在 GitHub 上添加公钥
# Settings → SSH and GPG keys → New SSH key

# 6. 测试连接
ssh -T git@github.com
# 成功会显示:Hi username! You've successfully authenticated...

SSH 配置文件(多账号场景):

# ~/.ssh/config
# 默认 GitHub 账号
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

# 第二个 GitHub 账号
Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

# 使用第二个账号克隆时
git clone git@github-work:company/project.git

3.3 GitHub CLI 方式克隆

前提条件: 安装并认证 gh 命令行工具。

# 安装 GitHub CLI(macOS)
brew install gh

# 安装 GitHub CLI(Ubuntu/Debian)
sudo apt install gh

# 认证登录
gh auth login

# 克隆仓库
gh repo clone octocat/Hello-World

# 克隆到指定目录
gh repo clone octocat/Hello-World my-local-dir

优点:

  • 自动处理认证,无需手动配置 SSH 或 HTTPS 凭据
  • 可以直接使用 GitHub API 功能
  • 支持多种 GitHub 操作(创建 Issue、PR 等)

缺点:

  • 需要额外安装工具
  • 依赖 GitHub 平台,不适用于其他 Git 托管服务

3.4 三种方式对比总结

特性 HTTPS SSH GitHub CLI
初始配置难度 简单 中等 简单
认证方式 用户名/密码或 Token SSH 密钥 OAuth
安全性 中等 高 高
传输速度 一般 快 快
企业防火墙兼容 好 一般 好
自动化脚本适用 需配置 Token 推荐 可用
多平台兼容 通用 通用 仅 GitHub

3.5 如何选择克隆方式

  • 初学者:建议从 HTTPS 开始,配置简单
  • 日常开发:推荐 SSH,一次配置长期受益
  • GitHub 重度用户:可以使用 GitHub CLI,功能最全面
  • CI/CD 环境:推荐 SSH 或 HTTPS + Token
  • 企业内网:根据防火墙策略选择 HTTPS 或 SSH

4. 浅克隆(--depth)与部分克隆(--filter)

4.1 浅克隆(Shallow Clone)

浅克隆是指只克隆仓库最近的一部分提交历史,而不是完整的提交记录。这在很多场景下非常有用,特别是当仓库历史非常庞大时。

# 只克隆最近 1 次提交
git clone --depth 1 https://github.com/user/repo.git

# 克隆最近 10 次提交
git clone --depth 10 https://github.com/user/repo.git

# 浅克隆特定分支
git clone --depth 1 -b develop https://github.com/user/repo.git

浅克隆的特点:

# 浅克隆后查看提交历史
git log --oneline
# 只显示最近的 N 条提交记录

# 查看仓库是否为浅克隆
git rev-parse --is-shallow-repository
# true 表示是浅克隆

将浅克隆转换为完整仓库:

# 获取完整历史
git fetch --unshallow

# 或者获取所有远程分支的历史
git fetch --unshallow origin

浅克隆的适用场景:

  • CI/CD 流水线,只需要最新代码进行构建
  • 快速查看仓库的最新状态
  • 节省磁盘空间和网络带宽
  • 大型开源项目的快速参与

浅克隆的限制:

  • 无法查看完整提交历史
  • git blame 可能不完整
  • 某些 Git 操作可能受限(如合并跨浅克隆边界的提交)
  • 推送操作可能需要额外配置

4.2 部分克隆(Partial Clone)

部分克隆是 Git 2.19 引入的新功能,允许你在克隆时选择性地过滤某些类型的对象。与浅克隆不同,部分克隆保留完整的提交历史,但可以选择不下载某些大型文件。

# 不下载任何 blob 对象(文件内容),只下载提交和树对象
git clone --filter=blob:none https://github.com/user/repo.git

# 不下载大于指定大小的 blob 对象
git clone --filter=blob:limit=1m https://github.com/user/repo.git

# 不下载树对象(极少使用)
git clone --filter=tree:0 https://github.com/user/repo.git

# 组合过滤条件
git clone --filter=blob:limit=5m --filter=tree:0 https://github.com/user/repo.git

部分克隆的优势:

  • 克隆速度显著提升(特别是包含大量二进制文件的仓库)
  • 文件内容按需下载(lazy fetch)
  • 保留完整的提交历史
  • 支持正常的 Git 操作

按需获取文件内容:

# 克隆时不下载 blob
git clone --filter=blob:none https://github.com/user/repo.git

# 当你检出或读取某个文件时,Git 会自动从远程获取该文件的内容
# 这个过程是透明的,用户无需手动干预

# 手动预取某些目录的文件
git sparse-checkout init --cone
git sparse-checkout set src/ docs/

4.3 稀疏检出(Sparse Checkout)

稀疏检出允许你只检出仓库中的部分目录或文件,适合超大型仓库。

# 克隆仓库但不检出文件
git clone --no-checkout https://github.com/user/repo.git
cd repo

# 初始化稀疏检出
git sparse-checkout init --cone

# 只检出指定目录
git sparse-checkout set src/ packages/core/

# 查看稀疏检出配置
git sparse-checkout list

# 添加更多目录
git sparse-checkout add tests/ docs/

# 结合部分克隆使用(推荐)
git clone --filter=blob:none --sparse https://github.com/user/repo.git
cd repo
git sparse-checkout set src/ docs/

5. 克隆指定分支

5.1 基本分支克隆

# 克隆指定分支
git clone -b develop https://github.com/user/repo.git

# 等价写法
git clone --branch develop https://github.com/user/repo.git

# 克隆指定分支到指定目录
git clone -b feature/login https://github.com/user/repo.git login-feature

5.2 克隆单分支仓库

如果你只需要一个分支,可以使用 --single-branch 参数,这样可以显著减少克隆所需的时间和空间:

# 只克隆 main 分支
git clone --single-branch https://github.com/user/repo.git

# 只克隆 develop 分支
git clone -b develop --single-branch https://github.com/user/repo.git

# 后续需要获取其他分支时
git remote set-branches origin '*'
git fetch --all

5.3 克隆远程分支到本地

# 查看所有远程分支
git branch -r

# 基于远程分支创建本地分支
git checkout -b feature origin/feature

# 新版 Git 可以直接切换
git checkout feature
# Git 会自动创建跟踪远程分支的本地分支

# 查看本地分支与远程分支的跟踪关系
git branch -vv

5.4 克隆时的分支引用过滤

# 只克隆特定分支的引用
git clone -b main --single-branch --branch main https://github.com/user/repo.git

# 克隆时排除特定分支(需要手动 fetch)
git clone https://github.com/user/repo.git
cd repo
git config --add remote.origin.fetch '+refs/heads/feature/*:refs/remotes/origin/feature/*'
git fetch

6. 子模块克隆(--recurse-submodules)

6.1 什么是 Git 子模块

Git 子模块(Submodule)允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。这在管理项目依赖或组织大型项目时非常有用。

6.2 克隆包含子模块的仓库

# 方式一:克隆时自动初始化并更新子模块(推荐)
git clone --recurse-submodules https://github.com/user/repo.git

# 方式二:分步操作
git clone https://github.com/user/repo.git
cd repo
git submodule init
git submodule update

# 方式三:使用简写参数
git clone --recursive https://github.com/user/repo.git

6.3 子模块的常见操作

# 查看子模块状态
git submodule status

# 更新子模块到最新提交
git submodule update --remote

# 更新子模块并合并
git submodule update --remote --merge

# 更新子模块并变基
git submodule update --remote --rebase

# 添加新的子模块
git submodule add https://github.com/user/library.git libs/library

# 删除子模块
git submodule deinit libs/library
git rm libs/library
rm -rf .git/modules/libs/library

6.4 递归子模块操作

# 对所有子模块执行命令
git submodule foreach 'git pull origin main'

# 递归初始化所有子模块(包括嵌套的子模块)
git submodule init --recursive

# 递归更新所有子模块
git submodule update --recursive

# 克隆时递归处理所有嵌套子模块
git clone --recurse-submodules --shallow-submodules https://github.com/user/repo.git

6.5 子模块的替代方案:Git Subtree

对于某些场景,Git Subtree 可能是更好的选择:

# 添加子树
git subtree add --prefix=libs/library https://github.com/user/library.git main --squash

# 更新子树
git subtree pull --prefix=libs/library https://github.com/user/library.git main --squash

# 推送子树的修改
git subtree push --prefix=libs/library https://github.com/user/library.git main

7. Git 镜像仓库

7.1 什么是镜像仓库

镜像仓库是远程仓库的完整副本,包含所有的分支、标签、提交历史和引用。镜像仓库常用于备份、加速访问或迁移到新的托管平台。

7.2 创建镜像克隆

# 创建裸镜像仓库
git clone --mirror https://github.com/user/repo.git

# 镜像克隆的结果是一个 bare 仓库
# 目录结构为 repo.git/

7.3 镜像克隆与普通克隆的区别

特性 普通克隆 镜像克隆
工作目录 有 无(bare 仓库)
远程引用 只有指定的分支 所有分支和标签
推送更新 推送到指定分支 镜像推送所有引用
适用场景 日常开发 备份、迁移、镜像

7.4 同步镜像仓库

# 在已有的镜像仓库中获取更新
cd repo.git
git fetch --all --prune

# 推送镜像到另一个远程仓库
git push --mirror https://github.com/user/repo-backup.git

7.5 设置自动镜像同步

#!/bin/bash
# sync-mirror.sh - 同步镜像仓库脚本

SOURCE="https://github.com/user/repo.git"
MIRROR_DIR="/backup/repo.git"

if [ ! -d "$MIRROR_DIR" ]; then
    git clone --mirror "$SOURCE" "$MIRROR_DIR"
fi

cd "$MIRROR_DIR"
git fetch --all --prune
echo "Mirror synced at $(date)"

8. 国内加速克隆方案

针对中国大陆开发者的网络优化方案。由于 GitHub 服务器在国外,国内访问经常出现速度慢、连接超时等问题。

8.1 使用代理加速

如果你有代理服务,可以配置 Git 使用代理:

# 临时设置代理(当前终端会话有效)
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890

# 只对 GitHub 设置代理
git config --global http.https://github.com.proxy http://127.0.0.1:7890

# 使用 SOCKS5 代理
git config --global http.https://github.com.proxy socks5://127.0.0.1:7891

# 取消代理设置
git config --global --unset http.https://github.com.proxy

8.2 使用 ghproxy 加速

ghproxy 是一个免费的 GitHub 文件加速服务,可以显著提升克隆速度:

# 使用 ghproxy 克隆
git clone https://ghproxy.com/https://github.com/user/repo.git

# 配置 Git 别名简化操作
git config --global url."https://ghproxy.com/https://github.com/".insteadOf "https://github.com/"

# 之后正常克隆即可自动使用加速
git clone https://github.com/user/repo.git
# 实际访问 https://ghproxy.com/https://github.com/user/repo.git

# 取消加速配置
git config --global --unset url."https://ghproxy.com/https://github.com/".insteadOf

8.3 使用国内镜像站

# 配置使用 gitclone.com 镜像
git config --global url."https://gitclone.com/github.com/".insteadOf "https://github.com/"

# 配置使用 hub.fastgit.xyz 镜像
git config --global url."https://hub.fastgit.xyz/".insteadOf "https://github.com/"

# 配置使用 gitee 镜像(需要先 fork 到 Gitee)
# 访问 https://gitee.com/ 手动导入仓库

# 配置使用 kkgithub 镜像
git config --global url."https://kkgithub.com/".insteadOf "https://github.com/"

8.4 使用 SSH 加速

SSH 协议在某些网络环境下可能比 HTTPS 更稳定:

# 编辑 SSH 配置文件
# ~/.ssh/config
Host github.com
    HostName ssh.github.com
    Port 443
    User git
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
    TCPKeepAlive yes
    ServerAliveInterval 60

# 测试 SSH 连接
ssh -T git@github.com

8.5 DNS 优化

# 查看 GitHub 的 IP 地址
nslookup github.com
nslookup github.global.ssl.fastly.net

# 手动配置 hosts 文件
# /etc/hosts (Linux/macOS)
# C:\Windows\System32\drivers\etc\hosts (Windows)
# 添加以下内容(IP 地址需要自行查询确认)
# 20.205.243.166 github.com
# 140.82.114.4 github.com

# 刷新 DNS 缓存
# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
# Linux
sudo systemctl restart nscd
# Windows
ipconfig /flushdns

8.6 设置 Git 缓冲区大小

# 增大 HTTP 缓冲区(应对大仓库克隆)
git config --global http.postBuffer 524288000

# 设置低速限制(避免长时间卡住)
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999

# 设置连接超时时间
git config --global http.connectTimeout 60

8.7 综合加速配置脚本

#!/bin/bash
# github-accelerate.sh - GitHub 加速配置脚本

echo "=== GitHub 克隆加速配置 ==="

# 设置 HTTP 缓冲区
git config --global http.postBuffer 524288000

# 设置超时时间
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999

# 选择加速方式
echo "请选择加速方式:"
echo "1. ghproxy 加速"
echo "2. gitclone.com 镜像"
echo "3. kkgithub 镜像"
echo "4. 取消加速配置"

read -p "输入选项 [1-4]: " choice

case $choice in
    1)
        git config --global url."https://ghproxy.com/https://github.com/".insteadOf "https://github.com/"
        echo "已配置 ghproxy 加速"
        ;;
    2)
        git config --global url."https://gitclone.com/github.com/".insteadOf "https://github.com/"
        echo "已配置 gitclone.com 镜像"
        ;;
    3)
        git config --global url."https://kkgithub.com/".insteadOf "https://github.com/"
        echo "已配置 kkgithub 镜像"
        ;;
    4)
        git config --global --unset url."https://ghproxy.com/https://github.com/".insteadOf 2>/dev/null
        git config --global --unset url."https://gitclone.com/github.com/".insteadOf 2>/dev/null
        git config --global --unset url."https://kkgithub.com/".insteadOf 2>/dev/null
        echo "已取消所有加速配置"
        ;;
esac

echo "配置完成!"

9. 大仓库优化克隆策略

9.1 大仓库面临的挑战

大型仓库(如 Linux 内核、Chromium 等)可能有数十 GB 的数据和数百万次提交。克隆这些仓库会面临时间长、磁盘空间不足等问题。

9.2 渐进式克隆策略

第一阶段:快速获取仓库骨架

# 浅克隆 + 单分支 + 不检出
git clone --depth 1 --single-branch --no-checkout https://github.com/user/huge-repo.git
cd huge-repo

# 初始化稀疏检出
git sparse-checkout init --cone

# 只检出需要的目录
git sparse-checkout set src/ docs/
git checkout main

第二阶段:按需扩展

# 需要更多历史时
git fetch --deepen=100

# 需要更多分支时
git remote set-branches origin develop feature/*
git fetch origin develop

# 需要更多文件时
git sparse-checkout add tests/ packages/

9.3 Git 大文件存储(Git LFS)

对于包含大量二进制文件的仓库,使用 Git LFS 可以显著减小仓库体积:

# 安装 Git LFS
git lfs install

# 克隆使用了 LFS 的仓库(自动获取 LFS 文件)
git clone https://github.com/user/repo.git

# 克隆时不获取 LFS 文件
GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/user/repo.git
cd repo

# 手动获取特定 LFS 文件
git lfs pull --include="*.psd"
git lfs pull --include="assets/**"

# 排除某些 LFS 文件
git lfs pull --exclude="*.zip"

9.4 使用 Git 的 pack 文件优化

# 克隆时使用多个并行线程
git clone --jobs=8 https://github.com/user/repo.git

# 手动压缩仓库
git gc --aggressive --prune=now

# 重新打包对象
git repack -a -d --depth=250 --window=250

9.5 网络传输优化

# 使用压缩传输
git config --global core.compression 9

# 克隆时显示进度
git clone --progress https://github.com/user/repo.git

# 使用 IPv4(某些网络环境下 IPv6 较慢)
git config --global http.postBuffer 524288000

# 限制传输速度(避免占用全部带宽)
git config --global http.lowSpeedLimit 1000
git config --global http.lowSpeedTime 60

10. 仓库迁移与导入

10.1 从 SVN 迁移到 Git

Git 内置了 git svn 工具,可以方便地将 SVN 仓库迁移到 Git。

步骤一:准备作者映射文件

# authors-transform.txt 格式:
# svn-username = Git Name <git@email.com>
# 示例:
zhangsan = 张三 <zhangsan@example.com>
lisi = 李四 <lisi@example.com>
(no author) = Unknown <unknown@example.com>

步骤二:克隆 SVN 仓库

# 克隆整个 SVN 仓库(包括 trunk、branches、tags)
git svn clone https://svn.example.com/svn/project \
    --stdlayout \
    --authors-file=authors-transform.txt \
    --no-metadata \
    project-git

# 如果 SVN 仓库目录结构不同
git svn clone https://svn.example.com/svn/project \
    --trunk=main \
    --branches=branch \
    --tags=release \
    --authors-file=authors-transform.txt \
    project-git

步骤三:清理和转换

cd project-git

# 将 SVN 远程分支转换为本地 Git 分支
for branch in $(git branch -r | grep -v tags | grep -v trunk); do
    git branch $(echo $branch | sed 's/origin\///') refs/remotes/$branch
done

# 将 SVN tags 转换为 Git tags
for tag in $(git branch -r | grep tags); do
    tagname=$(echo $tag | sed 's/.*tags\///')
    git tag $tagname refs/remotes/$tag
done

# 删除 SVN 远程引用
git branch -r -d $(git branch -r)

# 推送到 GitHub
git remote add origin https://github.com/user/project.git
git push -u origin --all
git push --tags

10.2 从 Mercurial 迁移到 Git

# 安装 hg-git 扩展
pip install hg-git

# 克隆 Mercurial 仓库
hg clone https://hg.example.com/project project-hg
cd project-hg

# 转换为 Git 仓库
hg bookmark -r default master
hg gexport

# 将 Mercurial 仓库转为 Git 仓库
git clone .git project-git
cd project-git

# 推送到 GitHub
git remote add origin https://github.com/user/project.git
git push -u origin --all
git push --tags

10.3 从其他 Git 托管平台迁移

# 从 GitLab 迁移到 GitHub
git clone --mirror https://gitlab.com/user/repo.git
cd repo.git
git remote set-url origin https://github.com/user/repo.git
git push --mirror

# 从 Bitbucket 迁移到 GitHub
git clone --mirror https://bitbucket.org/user/repo.git
cd repo.git
git remote set-url origin https://github.com/user/repo.git
git push --mirror

# 从 Gitee 迁移到 GitHub
git clone --mirror https://gitee.com/user/repo.git
cd repo.git
git remote set-url origin https://github.com/user/repo.git
git push --mirror

10.4 使用 GitHub Importer

GitHub 提供了网页端的导入工具:

  1. 访问 https://github.com/new/import
  2. 输入源仓库的 URL
  3. 选择仓库的公开性
  4. 等待导入完成

支持导入的来源:Subversion、Mercurial、TFS、Git。

10.5 导入现有代码到 Git

# 方式一:直接初始化
cd existing-project
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/user/repo.git
git push -u origin main

# 方式二:保留历史记录(如果有其他版本控制系统的日志)
# 可以使用脚本将历史记录转换为 Git 提交

11. bare 仓库与镜像

11.1 什么是 bare 仓库

Bare 仓库是一个没有工作目录的 Git 仓库,只包含 .git 目录中的内容。它通常用作服务器端的中央仓库,开发者向它推送和拉取代码。

# 创建 bare 仓库
git init --bare my-project.git

# 克隆为 bare 仓库
git clone --bare https://github.com/user/repo.git

# bare 仓库的目录结构
my-project.git/
├── HEAD
├── config
├── description
├── hooks/
├── info/
├── objects/
├── packed-refs
└── refs/

11.2 bare 仓库与普通仓库的区别

特性 普通仓库 bare 仓库
工作目录 有 无
.git 目录 在 .git/ 子目录中 仓库根目录就是 .git 内容
可以直接编辑文件 可以 不可以
适合作为远程仓库 不推荐 推荐
可以执行 git commit 可以 不可以(需要手动操作)

11.3 使用 bare 仓库作为中央仓库

# 在服务器上创建 bare 仓库
ssh user@server
mkdir -p /git/repos
cd /git/repos
git init --bare project.git

# 本地开发者克隆
git clone ssh://user@server/git/repos/project.git

# 推送代码到 bare 仓库
git push origin main

# 其他开发者拉取更新
git pull origin main

11.4 将普通仓库转换为 bare 仓库

# 方式一:直接转换
cd my-project
git config --bool core.bare true

# 方式二:移动 .git 内容
cd my-project
mv .git ../my-project.git
cd ../my-project.git
git config --bool core.bare true
rm -rf ../my-project

# 方式三:克隆为 bare 仓库
git clone --bare my-project my-project.git

11.5 bare 仓库的维护

# 定期清理和压缩
cd /git/repos/project.git
git gc --aggressive --prune=now

# 检查仓库完整性
git fsck --full

# 查看仓库大小
du -sh .
git count-objects -vH

12. 常见克隆问题排查

12.1 权限问题

问题:Permission denied (publickey)

# 错误信息
# git@github.com: Permission denied (publickey).
# fatal: Could not read from remote repository.

# 排查步骤:

# 1. 检查 SSH 密钥是否存在
ls -la ~/.ssh/

# 2. 检查 ssh-agent 是否运行
eval "$(ssh-agent -s)"

# 3. 添加密钥到 ssh-agent
ssh-add ~/.ssh/id_ed25519

# 4. 测试 GitHub SSH 连接
ssh -vT git@github.com

# 5. 确认公钥已添加到 GitHub
# 访问 https://github.com/settings/keys

# 6. 检查 SSH 配置文件
cat ~/.ssh/config

问题:Repository not found

# 错误信息
# ERROR: Repository not found.
# fatal: Could not read from remote repository.

# 可能原因:
# 1. 仓库地址拼写错误
git remote -v  # 检查 URL

# 2. 仓库是私有的,没有访问权限
# 确认你有仓库的访问权限

# 3. 使用了错误的账号
# 检查当前使用的 SSH 密钥
ssh -T git@github.com

# 解决方案:
# 修正 URL
git remote set-url origin https://github.com/correct-user/repo.git

问题:HTTPS 认证失败

# 错误信息
# remote: Invalid username or password.
# fatal: Authentication failed for 'https://github.com/user/repo.git'

# 解决方案:

# 1. 使用 Personal Access Token 替代密码
# 在 GitHub Settings → Developer settings → Personal access tokens 创建

# 2. 使用 Git 凭据管理器
git config --global credential.helper manager  # Windows
git config --global credential.helper osxkeychain  # macOS

# 3. 清除已保存的错误凭据
# Windows: 凭据管理器 → Windows 凭据 → 删除 github.com
# macOS: 钥匙串访问 → 搜索 github.com → 删除

# 4. 使用新的 Token 重新认证
git clone https://<TOKEN>@github.com/user/repo.git

12.2 网络问题

问题:连接超时

# 错误信息
# fatal: unable to access 'https://github.com/user/repo.git/':
# Failed to connect to github.com port 443: Connection timed out

# 排查步骤:

# 1. 测试网络连接
ping github.com
curl -I https://github.com

# 2. 检查代理设置
git config --global --get http.proxy
git config --global --get https.proxy

# 3. 增大缓冲区和超时时间
git config --global http.postBuffer 524288000
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999

# 4. 使用代理
git config --global http.https://github.com.proxy http://127.0.0.1:7890

# 5. 使用国内镜像(参见第 8 节)

问题:SSL 证书错误

# 错误信息
# fatal: unable to access 'https://github.com/user/repo.git/':
# SSL certificate problem: unable to get local issuer certificate

# 解决方案(临时,不推荐长期使用):
git config --global http.sslVerify false

# 推荐解决方案:更新 CA 证书
# macOS: brew install ca-certificates
# Linux: sudo apt update && sudo apt install ca-certificates
# Windows: 更新 Git for Windows

问题:DNS 解析失败

# 错误信息
# fatal: unable to access 'https://github.com/user/repo.git/':
# Could not resolve host: github.com

# 排查步骤:

# 1. 测试 DNS 解析
nslookup github.com
dig github.com

# 2. 更换 DNS 服务器
# 使用公共 DNS:8.8.8.8 (Google) 或 114.114.114.114 (国内)

# 3. 手动配置 hosts 文件
# 查询 GitHub IP:https://www.ipaddress.com/
# 添加到 /etc/hosts 或 C:\Windows\System32\drivers\etc\hosts

12.3 大文件问题

问题:仓库体积过大导致克隆失败

# 错误信息
# fatal: the remote end hung up unexpectedly
# fatal: early EOF
# fatal: index-pack failed

# 解决方案:

# 1. 使用浅克隆
git clone --depth 1 https://github.com/user/repo.git

# 2. 使用部分克隆
git clone --filter=blob:none https://github.com/user/repo.git

# 3. 增大缓冲区
git config --global http.postBuffer 1048576000

# 4. 调整 Git 缓冲区大小
git config --global core.compression 0
git config --global pack.deltaCacheSize 2047m
git config --global pack.packSizeLimit 2047m
git config --global pack.windowMemory 2047m

# 5. 分步获取
git clone --depth 1 --single-branch https://github.com/user/repo.git
cd repo
git fetch --deepen=100
git fetch --unshallow

问题:文件名过长或包含特殊字符

# 错误信息
# error: unable to create file very-long-filename: Filename too long

# 解决方案:
git config --global core.longpaths true

问题:行尾符转换警告

# 警告信息
# warning: LF will be replaced by CRLF in file.txt.

# 解决方案:
# Windows 用户
git config --global core.autocrlf true
# Linux/macOS 用户
git config --global core.autocrlf input

12.4 常见错误代码速查表

错误代码 含义 常见原因
403 禁止访问 权限不足或 Token 无效
404 仓库不存在 URL 错误或仓库为私有
443 连接被拒 网络问题或防火墙
503 服务不可用 GitHub 服务器问题

13. 实战:创建你的第一个仓库完整流程

13.1 场景设定

假设你正在开发一个名为 my-awesome-app 的 Python 项目,需要创建本地仓库并推送到 GitHub。

13.2 完整操作流程

第一步:创建项目目录

# 创建项目目录
mkdir my-awesome-app
cd my-awesome-app

第二步:初始化 Git 仓库

# 初始化仓库,指定默认分支为 main
git init -b main

# 确认初始化成功
ls -la
# 你会看到 .git 目录

第三步:配置项目基本信息

# 配置用户信息(如果之前没有全局配置)
git config user.name "你的名字"
git config user.email "your_email@example.com"

# 创建 .gitignore 文件
cat > .gitignore << 'EOF'
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
.venv/
*.egg-info/
dist/
build/

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Environment
.env
.env.local
EOF

第四步:创建项目文件

# 创建 README.md
cat > README.md << 'EOF'
# My Awesome App

这是一个示例项目,用于演示 Git 仓库的创建流程。

## 功能特性

- 功能一:待添加
- 功能二:待添加

## 安装

```bash
pip install -r requirements.txt

使用方法

python main.py

贡献指南

欢迎提交 Pull Request!

许可证

MIT License EOF

创建主程序文件

cat > main.py << 'EOF' #!/usr/bin/env python3 """My Awesome App - 主程序入口"""

def main(): print("Hello, Git!")

if name == "main": main() EOF

创建依赖文件

cat > requirements.txt << 'EOF'

项目依赖

requests>=2.28.0 flask>=2.3.0 EOF

创建配置文件

cat > config.example.json << 'EOF' { "app_name": "My Awesome App", "version": "1.0.0", "debug": false } EOF


**第五步:提交代码**

```bash
# 查看当前状态
git status

# 添加所有文件到暂存区
git add .

# 查看将要提交的内容
git diff --cached

# 创建第一次提交
git commit -m "Initial commit: project setup with basic structure"

# 查看提交历史
git log --oneline

第六步:在 GitHub 上创建远程仓库

# 方式一:使用 GitHub CLI(推荐)
gh repo create my-awesome-app --public --source=. --remote=origin --push

# 方式二:手动创建
# 1. 打开 https://github.com/new
# 2. 输入仓库名 my-awesome-app
# 3. 选择公开或私有
# 4. 不要勾选 README、.gitignore、License(本地已有)
# 5. 点击 Create repository

# 方式二后续操作:关联远程仓库并推送
git remote add origin https://github.com/你的用户名/my-awesome-app.git
git push -u origin main

第七步:验证推送结果

# 查看远程仓库信息
git remote -v

# 查看分支状态
git branch -vv

# 访问 GitHub 仓库页面确认
# https://github.com/你的用户名/my-awesome-app

13.3 后续开发工作流

# 1. 创建开发分支
git checkout -b develop

# 2. 创建功能分支
git checkout -b feature/user-login

# 3. 开发完成后提交
git add .
git commit -m "feat: add user login functionality"

# 4. 推送到远程
git push -u origin feature/user-login

# 5. 在 GitHub 上创建 Pull Request

# 6. 合并后清理分支
git checkout develop
git pull origin develop
git branch -d feature/user-login
git push origin --delete feature/user-login

13.4 多人协作场景

作为仓库创建者:

# 邀请协作者
# 在 GitHub 仓库页面 → Settings → Collaborators → Add people

# 设置分支保护规则
# Settings → Branches → Add rule
# - Require pull request reviews before merging
# - Require status checks to pass before merging

作为协作者:

# 克隆仓库
git clone https://github.com/owner/my-awesome-app.git
cd my-awesome-app

# 创建自己的分支
git checkout -b feature/my-feature

# 开发并提交
git add .
git commit -m "feat: add my feature"

# 推送并创建 PR
git push -u origin feature/my-feature

13.5 推荐的仓库结构

my-awesome-app/
├── .git/
├── .gitignore
├── README.md
├── LICENSE
├── requirements.txt
├── setup.py 或 pyproject.toml
├── config.example.json
├── main.py
├── src/
│   ├── __init__.py
│   ├── models/
│   ├── views/
│   └── utils/
├── tests/
│   ├── __init__.py
│   ├── test_main.py
│   └── test_utils.py
├── docs/
│   └── getting-started.md
└── scripts/
    ├── setup.sh
    └── deploy.sh

总结

本章详细介绍了 Git 仓库的创建和克隆的各种方式与高级技巧:

主题 关键命令
初始化仓库 git init、git init -b main
克隆仓库 git clone <url>
SSH 克隆 git clone git@github.com:user/repo.git
HTTPS 克隆 git clone https://github.com/user/repo.git
浅克隆 git clone --depth 1 <url>
部分克隆 git clone --filter=blob:none <url>
分支克隆 git clone -b <branch> <url>
子模块克隆 git clone --recurse-submodules <url>
镜像克隆 git clone --mirror <url>
bare 仓库 git init --bare

掌握这些技能后,你就能高效地创建和管理 Git 仓库了。在下一章中,我们将学习如何进行文件的暂存与提交。


下一步

暂存与提交 →