Featured image of post Git 与版本控制实战:从入门到 GitHub 高级搜索

Git 与版本控制实战:从入门到 GitHub 高级搜索

Git 全攻略:本地仓库、GitHub 远程协作、Token 登录、Fork 同步、Git-FTP 部署、Git 常用命令速查、Git 高级搜索语法、Jenkins 集成、Git 分支管理策略

一、Git 在 2014 的地位

2014 年的 Git 已经基本统一了分布式版本控制市场。GitHub 2014 年 1 月用户突破 1000 万(2008 年成立,2013 年用户 300 万),国内 GitCafe、coding.net 同期兴起。本文整理 Git 从入门到 GitHub 高级搜索的完整工作流。

阅读建议:本文面向用过 SVN 切换到 Git 的开发者,重点在Git 概念 + 实战命令

二、Git 安装与初始配置

2.1 安装

  • Windows:https://git-scm.com/download/win(Git for Windows,带 Git Bash)
  • macOS:brew install git(或装 Xcode Command Line Tools)
  • Linux:apt install git / yum install git

2.2 全局配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 必填:用户名 + 邮箱
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

# 推荐:默认编辑器
git config --global core.editor "vim"

# 推荐:默认分支名(Git 2.28+)
git config --global init.defaultBranch main

# 推荐:换行符处理(Windows 推荐)
git config --global core.autocrlf true

2.3 SSH 密钥登录 GitHub

  1. 生成密钥对:

    1
    2
    3
    
    ssh-keygen -t ed25519 -C "you@example.com"
    # 或传统 RSA
    ssh-keygen -t rsa -b 4096 -C "you@example.com"
    
  2. 复制公钥:

    1
    2
    3
    4
    5
    6
    
    # Windows (Git Bash)
    clip < ~/.ssh/id_ed25519.pub
    # macOS
    pbcopy < ~/.ssh/id_ed25519.pub
    # Linux
    cat ~/.ssh/id_ed25519.pub
    
  3. GitHub Settings → SSH and GPG keys → New SSH key,粘贴。

  4. 验证:

    1
    2
    
    ssh -T git@github.com
    # 输出:Hi <username>! You've successfully authenticated...
    

2.4 HTTPS + Token 登录(GitHub 2021+ 强制)

2021-08 GitHub 取消密码推送,必须用 Personal Access Token (PAT)

  1. GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token
  2. 勾选 repogistread:orgworkflow
  3. 复制 token(只显示一次
  4. 克隆时用 token:
    1
    
    git clone https://<TOKEN>@github.com/username/repo.git
    
  5. IDEA 中:登录 GitHub 时填 token,不要用账户密码

三、Git 核心命令

3.1 本地仓库

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 初始化
git init
git init my-project
git clone https://github.com/xxx/repo.git

# 查看状态
git status
git log --oneline --graph --decorate --all

# 暂存与提交
git add <file>
git add .              # 当前目录所有
git add -p             # 交互式分块
git commit -m "msg"
git commit -am "msg"   # add tracked files + commit

# 撤销
git checkout -- <file>           # 丢弃工作区修改
git reset HEAD <file>            # 取消暂存
git reset --soft HEAD~1          # 撤销 commit,保留暂存
git reset --hard HEAD~1          # 撤销 commit,丢弃修改(危险)
git revert <commit>              # 反向 commit(安全)

3.2 分支

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 创建与切换
git branch <name>          # 创建
git checkout <name>        # 切换
git checkout -b <name>     # 创建并切换
git switch <name>          # Git 2.23+
git switch -c <name>       # 创建并切换

# 推送与拉取
git push origin <branch>
git pull origin <branch>
git pull --rebase origin <branch>   # 拉取后变基

# 合并
git merge <branch>
git merge --no-ff <branch>          # 保留分支历史
git rebase <branch>                 # 变基(线性历史)

3.3 远程

1
2
3
4
5
git remote -v
git remote add origin https://github.com/xxx/repo.git
git remote set-url origin <new-url>
git fetch origin
git fetch --all

3.4 标签

1
2
3
4
5
6
git tag                    # 列出本地标签
git tag v1.0.0             # 轻量标签
git tag -a v1.0.0 -m "msg" # 附注标签
git push origin v1.0.0     # 推送单个
git push origin --tags     # 推送所有
git checkout v1.0.0        # 切到标签

3.5 Stash(暂存工作区)

1
2
3
4
git stash                  # 暂存当前修改
git stash pop              # 恢复
git stash list             # 列出
git stash apply stash@{0}  # 应用指定

四、.gitignore 模板

4.1 Java 项目

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 编译产物
target/
build/
out/
*.class
*.jar
*.war

# IDE
.idea/
.vscode/
*.iml
*.iws
*.ipr
.project
.classpath
.settings/

# 日志
*.log
logs/

# 系统
.DS_Store
Thumbs.db

# 密钥
*.pem
*.key
secrets.yaml

4.2 Node 项目

1
2
3
4
5
6
7
node_modules/
npm-debug.log
.env
.env.local
dist/
.next/
.nuxt/

4.3 Python 项目

1
2
3
4
5
6
7
__pycache__/
*.pyc
.venv/
venv/
*.egg-info/
.pytest_cache/
.mypy_cache/

五、分支管理策略

5.1 Git Flow(2010 年 Vincent Driessen 提出)

1
2
3
4
5
master(生产)
  └── hotfix-*(紧急修复)
develop(开发)
  ├── feature-*(功能)
  └── release-*(预发布)
  • master:每个 commit 都是稳定版本,打 tag
  • develop:日常开发主分支
  • feature/*:功能分支,开发完 merge 回 develop
  • release/*:预发布分支,测试通过后 merge 到 master + develop
  • hotfix/*:紧急修复,直接从 master 拉,修完 merge 回 master + develop

5.2 GitHub Flow(2011 年 GitHub 提出)

只有 main + feature 分支

  1. 从 main 拉 feature 分支
  2. 提交 + 推送到 GitHub
  3. 开 Pull Request
  4. CI/CD 自动跑
  5. Code Review
  6. 合并到 main
  7. main 自动部署

适合:持续部署、单一版本的产品。

5.3 Trunk-Based Development(主干开发)

所有人在 main 上开发短期分支(< 1 天):

  • Feature flag:用代码开关控制新功能
  • 每提交必测:CI 跑全量测试
  • 每日合并:避免长寿命分支

适合:超大规模团队(Google、Facebook)。

六、GitHub 高级搜索

GitHub 搜索语法 2013 年就成熟了,对找开源项目、找开发者极有用

6.1 关键词

语法含义
in:name xxx仓库名含 xxx
in:description xxx描述含 xxx
in:readme xxxREADME 含 xxx

6.2 数量

语法含义
stars:>xxxstar > xxx
stars:xx..xxstar 在范围内
forks:>xxxfork > xxx

6.3 地区/语言

语法含义
location:china地区
language:javascript主语言

6.4 大小/日期

语法含义
size:>=5000仓库大小(KB)
pushed:>2020-01-01最后 push 时间
created:>2020-01-01创建时间

6.5 找组织/开发者

语法含义
user:xxx找用户
org:xxx找组织
followers:>=xxx关注者数量

6.6 License

语法含义
license:apache-2.0Apache 2.0
license:mitMIT
license:gpl-3.0GPL 3.0

6.7 实战示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 找 Java 写的、star > 10k 的 Spring Boot 项目
language:java spring boot stars:>10000

# 找 2020 年后更新的 Python 机器学习项目
language:python machine learning pushed:>2020-01-01

# 找 Apache 2.0 协议的 React 组件
react license:apache-2.0 in:readme

# 找来自中国的 JavaScript 全栈开发者
language:javascript location:china followers:>100

七、常用 Git 工作流

7.1 Fork 同步上游

Fork 别人的仓库后,怎么同步上游更新

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 1. 关联上游仓库
git remote add upstream https://github.com/original-owner/repo.git
git remote -v

# 2. 拉取上游更新
git fetch upstream
git checkout main
git merge upstream/main

# 3. 推到自己 Fork
git push origin main

7.2 Git-FTP:用 FTP 部署静态站点

git-ftp 工具(https://github.com/git-ftp/git-ftp)让 Git 管理 FTP 部署:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 安装
# Windows: scoop install git-ftp
# macOS: brew install git-ftp

# 初始化
git ftp init --user <USER> --passwd <PASS> ftp://host/

# 部署
git ftp push --user <USER> --passwd <PASS> ftp://host/

# 只部署 master
git ftp push --syncroot . --user <USER> --passwd <PASS> ftp://host/

适用:没有 CI/CD 的小项目,纯 FTP 部署

7.3 Git 配合 Jenkins

Jenkinsfile 经典写法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main',
                    url: 'https://github.com/xxx/repo.git',
                    credentialsId: 'github-token'
            }
        }
        stage('Build') {
            steps {
                sh 'mvn clean package -DskipTests'
            }
        }
        stage('Test') {
            steps {
                sh 'mvn test'
            }
        }
        stage('Deploy') {
            when { branch 'main' }
            steps {
                sh 'mvn deploy'
            }
        }
    }
}

7.4 Git 标签发版

1
2
3
4
5
6
7
8
# 发版流程
git checkout main
git pull
# 写 CHANGELOG
git tag -a v1.5.0 -m "Release 1.5.0"
git push origin v1.5.0

# GitHub 上:Releases → Draft a new release → 选 tag → 写变更

八、Git 内部原理

8.1 三个区

1
2
3
4
5
6
7
工作区(Working Directory)
   ↓ git add
暂存区(Staging / Index)
   ↓ git commit
本地仓库(Repository / .git)
   ↓ git push
远程仓库(Remote)

8.2 Git 对象

  • blob:文件内容
  • tree:目录结构
  • commit:一次提交(含 tree + parent + author + message)
  • tag:标签对象

每个对象都有 SHA-1 hash,git cat-file -p <hash> 看内容

8.3 分支本质

分支是 commit 的指针.git/refs/heads/main 文件里就一个 40 字符的 hash。

1
2
3
# 查看分支指向
cat .git/refs/heads/main
# 输出:a1b2c3d4e5f6...

九、常见问题

9.1 “Failed to connect to github.com port 443: Timed out”

1
2
3
4
5
6
7
# 设代理
git config --global http.proxy http://127.0.0.1:1081
git config --global https.proxy http://127.0.0.1:1081

# 取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy

9.2 “Could not resolve host: github.com”

1
2
3
4
# 改 hosts(Windows 路径:C:\Windows\System32\drivers\etc\hosts)
# 注意:先去掉"只读"属性
140.82.112.4 github.com
140.82.112.3 github.com

或者用 SwitchHosts 工具可视化编辑。

9.3 “Your branch is ahead of ‘origin/main’ by N commits”

1
git push origin main

9.4 合并冲突

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 1. 拉取冲突代码
git pull origin main
# 输出:CONFLICT (content): Merge conflict in <file>

# 2. 打开文件,找到冲突标记
<<<<<<< HEAD
你的代码
=======
别人的代码
>>>>>>> branch-name

# 3. 手动编辑(保留你想要的)

# 4. 标记为已解决
git add <file>
git commit -m "resolve conflict"

9.5 “Permission denied (publickey)”

1
2
3
4
5
6
7
8
# 检查 SSH key 是否加载
ssh-add -l

# 如果没加载
ssh-add ~/.ssh/id_ed25519

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

9.6 误删分支恢复

1
2
3
4
5
# 1. 找到最后一次 commit hash
git reflog

# 2. 重建分支
git checkout -b <branch> <hash>

9.7 .git 占用空间过大

1
2
3
4
5
6
# 清理大文件历史
git gc --aggressive --prune=now
# 或用 BFG Repo-Cleaner
bfg --delete-files "*.jar" --no-blob-protection
git reflog expire --expire=now --all
git gc --prune=now --aggressive

十、下一步

  • 想看 Java 主力 IDE:[2014-04-15 IntelliJ IDEA 全攻略]
  • 想看 CI/CD:项目全流程 章节中的 Jenkins 实战
  • 想看 Git 托管平台对比:[2021-05-10 开源生态观察]

本文写于 2014 年,回看当时:Git 2.1 是当时最新版,git switch / git restore 还没出来(2019 年 2.23 才发布);GitHub 高级搜索语法至今未大变;Git Flow 在 2014 已是行业事实,但 2017 年后 Trunk-Based 越来越流行——Git 工作流的演化反映了 CI/CD 文化的演进

使用 Hugo 构建
主题 StackJimmy 设计