引言:为什么你需要学习 Git?
Git 是目前世界上最先进的分布式版本控制系统,由 Linux 之父 Linus Torvalds 创建。无论你是程序员、设计师还是项目经理,掌握 Git 都能帮助你更好地管理项目文件、追踪修改历史、协作开发。想象一下,Git 就像是一个超级强大的”撤销”按钮,不仅能撤销你当前的修改,还能让你看到整个项目过去每一个版本的状态,甚至可以创建多个平行宇宙(分支)来尝试不同的想法。
对于新手来说,Git 的命令行界面可能看起来有些吓人,但一旦你理解了基本概念并掌握了常用命令,就会发现它其实非常直观和强大。本教程将从零开始,手把手教你安装 Git、配置环境、创建仓库、提交代码,并介绍一些实用的协作技巧。
第一部分:安装 Git
Windows 系统安装 Git
下载 Git 安装程序
访问 Git 官方网站:
https://git-scm.com/download/win
点击下载按钮,会自动下载最新版本的 Git for Windows
运行安装程序
双击下载的安装程序(通常是
Git-2.xx.x-64-bit.exe
)
按照安装向导的提示进行安装,大部分情况下可以使用默认设置
重要选项说明
:
“Select Components”(选择组件):建议保持默认,确保勾选 “Git Bash Here” 和 “Git GUI Here”
“Choosing the default editor used by Git”:建议选择 “Use Visual Studio Code as Git’s default editor” 或 “Use Nano”
“Adjusting your PATH environment”:选择 “Git from the command line and also from 3rd-party software”(推荐)
“Choosing the SSH executable”:选择 “Use bundled OpenSSH”
“Configuring the line ending conversions”:选择 “Checkout Windows-style, commit Unix-style line endings”
验证安装
在任意文件夹中右键,选择 “Git Bash Here”
在打开的终端中输入:
git –version
如果显示类似
git version 2.xx.x
,说明安装成功
macOS 系统安装 Git
通过 Homebrew 安装(推荐)
如果你没有安装 Homebrew,先安装它:
/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)”
安装 Git:
brew install git
通过 Xcode 命令行工具安装
打开终端,输入:
xcode-select –install
这会安装 Git 以及其他开发工具
从 Git 官网下载安装包
访问
https://git-scm.com/download/mac
下载适合你 macOS 版本的安装包并安装
验证安装
git –version
Linux 系统安装 Git
不同发行版的安装命令不同:
Ubuntu/Debian:
sudo apt update
sudo apt install git
CentOS/RHEL:
sudo yum install git
# 或者对于较新版本
sudo dnf install git
Fedora:
sudo dnf install git
Arch Linux:
sudo pacman -S git
验证安装:
git –version
第二部分:初始配置
安装完成后,我们需要进行一些基本配置。这些配置信息会嵌入到你的每次提交中,让其他开发者知道是谁做了这些修改。
配置用户信息
打开 Git Bash(Windows)或终端(macOS/Linux),输入以下命令:
# 设置用户名(建议使用你的真实姓名或GitHub用户名)
git config –global user.name “Your Name”
# 设置邮箱(建议使用你常用的邮箱)
git config –global user.email “your.email@example.com”
示例:
git config –global user.name “张三”
git config –global user.email “zhangsan@example.com”
重要提示
:
–global
表示这个配置对当前用户的所有仓库都有效
如果你想为特定项目设置不同的用户名和邮箱,可以在项目目录下运行不带
–global
的命令
确保邮箱与你的 GitHub/GitLab 账户邮箱一致,这样你的提交才能正确关联到你的账户
配置默认分支名称
Git 默认的分支名称是
master
,但近年来越来越多的项目改用
main
作为默认分支名称。你可以通过以下命令设置:
git config –global init.defaultBranch main
配置文本编辑器
Git 需要文本编辑器来编写提交信息。你可以配置你喜欢的编辑器:
# 使用 VS Code(推荐)
git config –global core.editor “code –wait”
# 使用 Vim
git config –global core.editor “vim”
# 使用 Nano
git config –global core.editor “nano”
配置行结束符(仅 Windows 用户)
Windows 使用 CRLF(\r\n)作为行结束符,而 Linux/macOS 使用 LF(\n)。为了避免跨平台协作时出现问题:
git config –global core.autocrlf true
这会让 Git 在提交时自动将 CRLF 转换为 LF,在检出时自动将 LF 转换为 CRLF。
配置凭证存储
为了避免每次推送代码时都输入用户名和密码,可以配置凭证存储:
git config –global credential.helper store
这样配置后,第一次输入用户名和密码后会被缓存,后续操作无需重复输入。
查看配置
配置完成后,你可以查看所有配置:
git config –list
或者查看某个特定配置:
git config user.name
git config user.email
第三部分:创建和初始化仓库
什么是仓库?
仓库(Repository,简称 Repo)是 Git 管理项目的核心。它是一个特殊的目录,Git 会在这里记录所有文件的修改历史、分支信息等。你可以把它想象成一个项目的”时光机”,记录了项目的每一个版本。
创建新仓库
方法一:在现有目录中初始化仓库
这是最常用的方法,适合已有项目代码的情况:
打开终端或 Git Bash
导航到你的项目目录:
cd /path/to/your/project
初始化 Git 仓库:
git init
示例:
# 创建一个新目录并进入
mkdir my-first-project
cd my-first-project
# 初始化 Git 仓库
git init
执行后,你会看到提示:
Initialized empty Git repository in /path/to/my-first-project/.git/
这表示 Git 已成功初始化,并在项目目录下创建了一个隐藏的
.git
目录。这个
.git
目录包含了 Git 仓库的所有元数据,
不要手动修改或删除它
。
方法二:从远程克隆现有仓库
如果你需要参与一个已有项目的开发,可以从远程仓库克隆:
git clone <远程仓库URL>
示例:
# 克隆一个公共仓库
git clone https://github.com/user/repo.git
# 克隆到指定目录
git clone https://github.com/user/repo.git my-project
# 克隆指定分支(如果只需要某个分支)
git clone -b branch-name https://github.com/user/repo.git
检查仓库状态
初始化仓库后,养成检查状态的习惯非常重要:
git status
示例输出:
On branch main
No commits yet
nothing to commit (create/copy files and use “git add” to track)
这个命令会告诉你:
当前所在的分支
是否有未跟踪的文件
是否有修改但未暂存的文件
是否有已暂存但未提交的文件
第四部分:基本工作流程
Git 的工作流程有三个核心概念:工作区、暂存区和版本库。
工作区(Working Directory)
:你实际编辑文件的地方
暂存区(Staging Area)
:临时存放你的修改,准备提交
版本库(Repository)
:
.git
目录,存储项目的完整历史
工作流程示例
让我们通过一个实际例子来理解这个流程:
# 1. 在工作区创建一个新文件
echo “# My Project” > README.md
# 2. 查看状态(文件未被跟踪)
git status
# 3. 将文件添加到暂存区
git add README.md
# 4. 再次查看状态(文件已暂存)
git status
# 5. 将暂存区的内容提交到版本库
git commit -m “Add README file”
# 6. 再次查看状态(工作区干净)
git status
第五部分:跟踪和提交文件
添加文件到暂存区
添加单个文件
git add <文件名>
示例:
git add index.html
git add styles.css
添加所有修改的文件
git add .
注意
:这个命令会添加当前目录下所有
修改和新增
的文件,但不包括被删除的文件。
添加所有修改(包括删除)
git add -A
# 或者
git add –all
添加所有已跟踪文件的修改
git add -u
这个命令只添加已经被 Git 跟踪的文件的修改,不包括新文件。
编写有意义的提交信息
提交信息是项目历史的重要组成部分,好的提交信息能帮助团队成员理解每次修改的目的。
git commit -m “提交信息”
示例:
git commit -m “修复用户登录页面的表单验证问题”
多行提交信息
对于复杂的修改,可以使用多行提交信息:
git commit
这会打开你配置的文本编辑器,让你编写更详细的提交信息。
示例:
修复用户登录页面的表单验证问题
– 修复了邮箱格式验证的正则表达式
– 添加了密码强度提示
– 优化了错误信息的显示样式
相关issue: #123
查看提交历史
git log
示例输出:
commit a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
Author: Your Name
Date: Mon Jan 15 10:30:00 2024 +0800
Add README file
commit 0z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0f
Author: Your Name
Date: Mon Jan 15 10:25:00 2024 +0800
Initial commit
简洁的提交历史
git log –oneline
输出:
a1b2c3d Add README file
0z9y8x7 Initial commit
图形化分支历史
git log –graph –oneline –all
第六部分:查看差异
查看工作区与暂存区的差异
git diff
这个命令显示工作区中
已修改但未暂存
的文件与暂存区的差异。
查看暂存区与版本库的差异
git diff –staged
# 或者
git diff –cached
这个命令显示
已暂存但未提交
的修改。
查看工作区与版本库的差异
git diff HEAD
这个命令显示工作区与最新提交之间的所有差异。
查看特定文件的差异
git diff <文件名>
示例:
git diff README.md
查看两次提交之间的差异
git diff <提交1> <提交2>
示例:
# 查看最近两次提交的差异
git diff HEAD~1 HEAD
# 查看特定提交之间的差异
git diff a1b2c3d 0z9y8x7
第七部分:忽略文件
有些文件不应该被 Git 跟踪,比如:
操作系统生成的文件(如
.DS_Store
、
Thumbs.db
)
编译生成的文件(如
*.pyc
、
*.class
)
敏感信息文件(如密码、API密钥)
依赖目录(如
node_modules
、
__pycache__
)
创建 .gitignore 文件
在项目根目录创建一个名为
.gitignore
的文件:
touch .gitignore
.gitignore 语法
# 注释:以 # 开头
# 忽略所有 .a 文件
*.a
# 但不忽略 lib.a,即使前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,不包括子目录下的 TODO 文件
/TODO
# 忽略 build 目录下的所有文件
build/
# 忽略 doc 目录下的 .txt 文件
doc/*.txt
# 忽略 doc 目录下所有子目录的 .txt 文件
doc/**/*.txt
常见项目的 .gitignore 示例
Python 项目
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
Node.js 项目
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of ‘npm pack’
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
# Gatsby files
.cache/
public
# Storybook-build
storybook-static
# rollup.js default build output
dist/
# Uncomment the public line if your project uses Gatsby
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
Java 项目
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
# Gradle
.gradle/
build/
# IntelliJ IDEA
.idea/
*.iml
*.iws
*.ipr
.out/
gen/
# Eclipse
.metadata/
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored “Eclipse launch configurations”
*.launch
# PyDev
.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
.apt_generated_test/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
#.project
忽略已跟踪的文件
如果你已经将文件添加到了 Git 跟踪(
git add
过),然后再添加到
.gitignore
,Git 仍然会跟踪这些文件。要停止跟踪:
git rm –cached <文件名>
示例:
# 假设你之前错误地提交了 .env 文件
git rm –cached .env
# 然后将 .env 添加到 .gitignore
echo “.env” >> .gitignore
# 提交这些更改
git add .gitignore
git commit -m “Stop tracking .env file”
第八部分:分支管理
什么是分支?
分支是 Git 最强大的功能之一。它允许你在同一个项目中创建多个独立的开发线,每个分支都有自己的提交历史。你可以把分支想象成项目的”平行宇宙”,在不同的分支上可以进行不同的开发工作而互不干扰。
查看分支
git branch
示例输出:
* main
*
表示当前所在的分支。
查看所有分支(包括远程)
git branch -a
创建分支
git branch <分支名>
示例:
git branch feature/user-authentication
切换分支
git checkout <分支名>
# 或者(Git 2.23+)
git switch <分支名>
示例:
git checkout feature/user-authentication
# 或者
git switch feature/user-authentication
创建并切换分支
这是最常用的方式:
git checkout -b <分支名>
# 或者
git switch -c <分支名>
示例:
git checkout -b feature/user-authentication
# 或者
git switch -c feature/user-authentication
删除分支
删除已合并的分支
git branch -d <分支名>
示例:
git branch -d feature/user-authentication
强制删除分支(未合并的分支)
git branch -D <分支名>
警告
:这个操作会永久删除分支上的所有提交,除非这些提交已经在其他分支中。
合并分支
假设你已经在
feature/user-authentication
分支上完成了开发,现在想把它合并到
main
分支:
# 1. 切换到目标分支(main)
git checkout main
# 2. 合并 feature 分支
git merge feature/user-authentication
合并冲突
当两个分支修改了同一个文件的同一部分时,会发生合并冲突。Git 会标记冲突的位置:
<<<<<<< HEAD
console.log("Hello from main");
=======
console.log("Hello from feature");
>>>>>>> feature/user-authentication
解决冲突的步骤:
打开冲突文件
,你会看到类似上面的标记
手动编辑文件
,保留需要的代码,删除标记
保存文件
标记冲突已解决
:
git add <冲突文件>
完成合并
:
git commit
变基(Rebase)
变基是另一种合并分支的方式,它会将当前分支的提交”重新播放”在目标分支的最新提交之后,产生线性的提交历史。
# 在 feature 分支上执行
git rebase main
变基 vs 合并:
合并(merge)
:保留分支历史,产生一个合并提交
变基(rebase)
:创建线性的历史,没有合并提交
使用建议
:
对于公共分支(如 main),避免使用 rebase
对于个人开发分支,可以使用 rebase 保持历史整洁
第九部分:远程仓库
什么是远程仓库?
远程仓库是托管在服务器上的 Git 仓库,团队成员可以从中拉取(pull)和推送(push)代码。最常用的远程仓库平台包括 GitHub、GitLab 和 Bitbucket。
添加远程仓库
git remote add <远程名>
示例:
git remote add origin https://github.com/username/my-project.git
说明
:
origin
是远程仓库的默认名称,你可以使用任何名字
一个本地仓库可以关联多个远程仓库
查看远程仓库
git remote -v
示例输出:
origin https://github.com/username/my-project.git (fetch)
origin https://github.com/username/my-project.git (push)
推送代码到远程仓库
git push <远程名> <分支名>
示例:
git push origin main
第一次推送
第一次推送时,可能需要设置上游分支:
git push -u origin main
-u
或
–set-upstream
会将本地分支与远程分支关联,以后可以直接使用
git push
。
从远程仓库拉取代码
git pull <远程名> <分支名>
示例:
git pull origin main
git pull
实际上是两个命令的组合:
git fetch
:从远程获取最新数据
git merge
:将远程分支合并到当前分支
推荐使用 fetch + merge
为了更清晰地了解远程变化,建议分开执行:
git fetch origin
git merge origin/main
克隆远程仓库
我们之前已经提到过克隆,这里再详细说明:
git clone
示例:
# 克隆到当前目录
git clone https://github.com/username/my-project.git
# 克隆到指定目录
git clone https://github.com/username/my-project.git my-project-folder
# 克隆指定分支
git clone -b develop https://github.com/username/my-project.git
第十部分:实际项目示例
让我们通过一个完整的例子来实践前面学到的所有知识。
场景:创建一个简单的网页项目
步骤 1:创建项目目录并初始化
# 创建项目目录
mkdir my-web-project
cd my-web-project
# 初始化 Git 仓库
git init
# 配置用户信息(如果之前没配置过)
git config user.name “Your Name”
git config user.email “your.email@example.com”
步骤 2:创建项目文件
创建
index.html
:
cat > index.html << 'EOF'
Welcome to My Project
This is a simple web project managed with Git.
EOF
创建
styles.css
:
cat > styles.css << 'EOF'
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
header {
background-color: #2c3e50;
color: white;
padding: 20px;
border-radius: 5px;
}
h1 {
margin: 0;
}
main {
background-color: white;
padding: 20px;
margin-top: 20px;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
button {
background-color: #3498db;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #2980b9;
}
EOF
创建
script.js
:
cat > script.js << 'EOF'
document.addEventListener('DOMContentLoaded', function() {
const button = document.getElementById('clickBtn');
const counter = { count: 0 };
button.addEventListener('click', function() {
counter.count++;
alert(`Button clicked ${counter.count} times!`);
});
});
EOF
创建
.gitignore
:
cat > .gitignore << 'EOF'
# macOS
.DS_Store
# Windows
Thumbs.db
# IDE
.vscode/
.idea/
# Logs
*.log
EOF
步骤 3:检查状态并添加文件
# 查看状态
git status
输出:
On branch main
No commits yet
Untracked files:
(use "git add
.gitignore
index.html
script.js
styles.css
nothing added to commit but untracked files present (use “git add” to track)
# 添加所有文件到暂存区
git add .
# 再次查看状态
git status
输出:
On branch main
No commits yet
Changes to be committed:
(use “git rm –cached
new file: .gitignore
new file: index.html
new file: script.js
new file: styles.css
步骤 4:提交代码
git commit -m “Initial commit: Create basic web project structure”
步骤 5:创建开发分支
# 创建并切换到开发分支
git checkout -b develop
# 在 index.html 中添加一些内容
cat >> index.html << 'EOF'
EOF
步骤 6:查看修改并提交
# 查看修改
git diff
# 添加并提交
git add index.html
git commit -m “Add footer to index.html”
步骤 7:切换回 main 分支并合并
# 切换回 main
git checkout main
# 合并 develop 分支
git merge develop
步骤 8:创建远程仓库并推送
假设你已经在 GitHub 上创建了一个名为
my-web-project
的空仓库。
# 添加远程仓库
git remote add origin https://github.com/your-username/my-web-project.git
# 推送到远程
git push -u origin main
步骤 9:继续开发 – 添加新功能
# 创建新分支开发新功能
git checkout -b feature/add-counter
# 修改 script.js
cat > script.js << 'EOF'
document.addEventListener('DOMContentLoaded', function() {
const button = document.getElementById('clickBtn');
const counter = { count: 0 };
const display = document.createElement('p');
display.id = 'counterDisplay';
display.textContent = 'Click count: 0';
button.parentNode.insertBefore(display, button.nextSibling);
button.addEventListener('click', function() {
counter.count++;
display.textContent = `Click count: ${counter.count}`;
});
});
EOF
# 提交
git add script.js
git commit -m "Add click counter display"
步骤 10:合并新功能
# 切换回 develop 分支
git checkout develop
# 合并 feature 分支
git merge feature/add-counter
# 切换回 main
git checkout main
# 合并 develop
git merge develop
# 推送到远程
git push origin main
步骤 11:清理已完成的分支
# 删除已合并的分支
git branch -d feature/add-counter
git branch -d develop
第十一部分:常用 Git 命令速查表
基本命令
命令
说明
git init
初始化新仓库
git clone
克隆远程仓库
git status
查看状态
git add
添加文件到暂存区
git commit -m “msg”
提交更改
git log
查看提交历史
分支命令
命令
说明
git branch
查看分支
git branch
创建分支
git checkout
切换分支
git checkout -b
创建并切换
git merge
合并分支
git branch -d
删除分支
远程命令
命令
说明
git remote -v
查看远程
git remote add
添加远程
git push
推送
git pull
拉取
git fetch
获取远程更新
撤销命令
命令
说明
git checkout —
丢弃工作区修改
git reset HEAD
取消暂存
git reset –hard HEAD
丢弃所有未提交修改
git revert
创建撤销提交
查看命令
命令
说明
git diff
查看未暂存的修改
git diff –staged
查看已暂存的修改
git log –oneline
简洁历史
git log –graph
图形化历史
git show
查看提交详情
第十二部分:最佳实践和技巧
1. 提交信息规范
好的提交信息应该:
以动词开头(如 Add, Fix, Update)
简明扼要(50字符以内)
必要时提供详细说明
示例:
Add user authentication feature
– Implement login form with email/password
– Add JWT token generation
– Create user model and database schema
– Add password hashing with bcrypt
Closes #45
2. 频繁提交
小步快跑,频繁提交:
每次提交只做一件事
提交之间逻辑独立
便于回滚和代码审查
3. 使用分支
main
分支:生产环境代码,保持稳定
develop
分支:开发分支,集成新功能
feature/*
分支:功能开发
bugfix/*
分支:修复 bug
hotfix/*
分支:紧急修复
4. 定期同步远程
# 每天开始工作前
git pull origin main
# 工作完成后
git push origin feature/your-feature
5. 使用 .gitignore
始终使用
.gitignore
忽略不必要的文件,保持仓库干净。
6. 保护主分支
不要直接在
main
分支上开发,始终使用特性分支。
7. 代码审查
在合并前进行代码审查,确保代码质量。
8. 备份重要提交
如果不确定某个操作是否会丢失数据,先创建备份分支:
git branch backup-before-reset
第十三部分:常见问题和解决方案
问题 1:提交了敏感信息(如密码)
解决方案:
# 1. 从历史中删除文件(会改变历史,慎用!)
git filter-branch –force –index-filter \
‘git rm –cached –ignore-unmatch sensitive-file.txt’ \
–prune-empty –tag-name-filter cat — –all
# 2. 强制推送
git push origin –force –all
# 3. 通知团队成员重新克隆
更好的做法
:立即更改密码,不要提交到版本控制。
问题 2:误删了分支
# 查看所有分支(包括已删除的)
git reflog
# 找到分支删除前的提交
# 然后重建分支
git branch <分支名> <提交哈希>
问题 3:合并冲突太多
预防措施
:
频繁从主分支拉取最新代码
小步提交,减少冲突范围
与团队成员保持沟通
问题 4:推送被拒绝
可能原因:
远程有本地没有的提交
分支保护规则
解决方案:
# 先拉取远程更改
git pull origin main
# 解决冲突后再次推送
git push origin main
问题 5:忘记切换分支直接开发
解决方案:
# 1. 创建新分支包含当前修改
git checkout -b new-feature
# 2. 提交修改
git add .
git commit -m “Your commit message”
# 3. 如果需要,可以删除旧分支
git branch -D old-branch-name
第十四部分:进阶技巧
1. 交互式暂存(Interactive Staging)
git add -i
# 或者
git add –interactive
这允许你:
选择性地暂存文件的某些部分
暂存文件的某些行
查看差异
2. 储藏(Stashing)
临时保存未提交的修改:
# 储藏当前修改
git stash
# 查看储藏列表
git stash list
# 恢复最近的储藏
git stash pop
# 恢复指定储藏
git stash apply stash@{1}
# 删除储藏
git stash drop
3. 重置(Reset)
# 软重置:保留工作区修改,撤销提交
git reset –soft HEAD~1
# 混合重置:保留工作区修改,撤销提交和暂存
git reset HEAD~1
# 硬重置:丢弃所有修改(危险!)
git reset –hard HEAD~1
4. 变基(Rebase)的高级用法
# 交互式变基(修改历史)
git rebase -i HEAD~3
# 变基时跳过某些提交
git rebase –skip
# 变基时中止
git rebase –abort
5. 钩子(Hooks)
Git 钩子是触发特定事件时自动运行的脚本。例如,pre-commit 钩子可以在提交前运行测试:
# 创建 pre-commit 钩子
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
# 在提交前运行测试
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Commit aborted."
exit 1
fi
EOF
# 使钩子可执行
chmod +x .git/hooks/pre-commit
6. 别名(Aliases)
创建常用命令的快捷方式:
# 创建别名
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'
# 使用别名
git co main
git st
git last
7. 子模块(Submodules)
管理项目中的其他 Git 仓库:
# 添加子模块
git submodule add https://github.com/user/repo.git path/to/submodule
# 初始化和更新子模块
git submodule update --init --recursive
# 克隆包含子模块的项目
git clone --recurse-submodules https://github.com/user/project.git
第十五部分:Git 可视化工具
虽然命令行很强大,但可视化工具可以帮助理解复杂操作。
1. Git GUI 客户端
GitHub Desktop
:简单易用,适合初学者
SourceTree
:功能强大,支持高级操作
GitKraken
:界面美观,集成 GitHub/GitLab
TortoiseGit
:Windows 资源管理器集成
2. 命令行可视化
# 简单的图形化历史
git log --graph --oneline --all
# 更详细的图形化
git log --graph --pretty=format:'%h -%d %s (%an, %ar)' --all
3. 浏览器扩展
Refined GitHub
:增强 GitHub 界面
Octotree
:在 GitHub 侧边栏显示代码树
第十六部分:总结
恭喜你!现在你已经掌握了 Git 的基础知识和常用操作。让我们回顾一下关键要点:
核心概念
仓库
:项目的版本历史存储
工作区
:你编辑文件的地方
暂存区
:准备提交的修改
分支
:独立的开发线
远程仓库
:团队协作的中心
基本工作流程
git add
- 添加到暂存区
git commit
- 提交到版本库
git push
- 推送到远程
git pull
- 从远程拉取
最佳实践
频繁提交,小步快跑
使用分支进行开发
编写清晰的提交信息
定期同步远程仓库
使用
.gitignore
管理文件
下一步学习建议
深入学习
:
Git 内部原理(对象模型、引用、索引)
高级变基操作
钩子脚本开发
团队协作
:
Pull Request 工作流
Code Review 最佳实践
分支保护规则
工具集成
:
CI/CD 与 Git 集成
自动化测试
部署流程
扩展阅读
:
Pro Git 书籍(免费在线)
Git 官方文档
GitHub/GitLab 官方教程
记住,Git 是一个工具,熟练掌握需要实践。不要害怕犯错,Git 的强大之处在于它可以让你轻松撤销错误。多在实际项目中使用,你会越来越熟练!
常用命令速记
# 开始新项目
git init
git add .
git commit -m "Initial commit"
# 日常开发
git checkout -b feature-name
# ... 编码 ...
git add .
git commit -m "Add feature"
git checkout main
git merge feature-name
git push origin main
# 保持同步
git pull origin main
现在,打开你的终端,开始使用 Git 管理你的项目吧!如果遇到问题,随时查阅本教程或使用
git help
获取帮助。祝你 Git 之旅愉快!