Ubuntu 22.04 Git 安装与命令参数详解
Ubuntu 22.04 下 Git 2.34.1 在线/离线安装与全部核心命令参数的真实回显详解
Ubuntu 22.04 Git 安装与命令参数详解
目标:在 Ubuntu 22.04 LTS x86_64 服务器上,从 0 到 1 完成 Git 2.34.1 的在线安装与离线安装,并对 init/clone/add/commit/status/diff/log/branch/checkout/switch/tag/merge/stash/remote/config/show/describe/reset/restore 等核心命令逐一实测,给出真实输入与真实回显。
一、环境信息
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04 LTS(jammy,内核实测 PRETTY_NAME="Ubuntu 22.04.5 LTS") |
| 架构 | x86_64 |
| 包管理器 | apt(APT 2.4 系列,dpkg 底层) |
| Git 版本 | 2.34.1(软件包版本 1:2.34.1-1ubuntu1.17) |
| 初始化默认分支 | master |
| 登录用户 | root(普通用户操作时以 sudo 前缀执行) |
首先确认系统与 Git 现状:
cat /etc/os-release | head -3
回显:
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
uname -m
回显:
x86_64
git --version
回显:
git version 2.34.1
二、工具概述
Git 是一个开源的分布式版本控制系统(Distributed Version Control System),由 Linus Torvalds 于 2005 年发起,用于高效地管理任意规模的源代码历史。与 SVN 等集中式系统不同,Git 的每个工作副本都包含完整的仓库历史,绝大部分操作都在本地完成,仅在需要协作时与远程仓库(remote)交互。
Git 的核心功能包括:
- 快照与版本历史:每次
git commit都会把暂存区(index/staging area)的内容固化为一次不可变的快照,可随时回溯任意历史版本。 - 暂存区机制:工作区(working tree)→ 暂存区(index)→ 仓库(repository)三段式提交流程,提交前可精确挑选要纳入快照的文件。
- 分支与合并:创建/切换/删除分支几乎零成本,
merge/cherry-pick/rebase支持灵活的分支整合策略。 - 分布式协作:通过
clone/fetch/pull/push与 bare 仓库(远程裸仓库)或 GitHub/Gitee 等托管平台协作。 - 数据完整性:所有对象以 SHA-1 哈希寻址,任何篡改都能被
git fsck检测。
在 Linux 开发与编译工具链中,Git 负责"源代码的版本管理",与 gcc/g++(编译)、make(构建)、gdb(调试)形成完整的开发闭环:代码托管在 Git 仓库 → 检出到工作区 → 编译 → 调试 → 提交回仓库。
典型使用场景:
- 管理个人项目代码,随时回滚出错改动。
- 团队协作:多人基于分支开发,定期合并主干。
- 与 GitHub/Gitee 等平台联动,实现代码托管、CI/CD 触发与发布打标签(
git tag)。
三、在线安装方案
Ubuntu 22.04 官方软件源(archive.ubuntu.com 的 jammy 系列)中已内置 Git 软件包,直接使用 apt 安装即可。
第 1 步:更新软件源索引
sudo apt update
回显(末尾片段):
Reading package lists...
Building dependency tree...
Reading state information...
8 packages can be upgraded. Run 'apt list --upgradable' to see them.
第 2 步:安装 Git
sudo apt install -y git
回显:
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
8 packages can be upgraded. Run 'apt list --upgradable' to see them.
Reading package lists...
Building dependency tree...
Reading state information...
git is already the newest version (1:2.34.1-1ubuntu1.17).
0 upgraded, 0 newly installed, 0 to remove and 8 not upgraded.
💡 说明:本例系统已预装 Git,因此 apt 提示
git is already the newest version。若是在全新 Ubuntu 22.04 服务器上执行,apt 会自动解析依赖(libc6、libcurl3-gnutls、perl 等)并完成下载安装,回显中会显示Get:1 http://archive.ubuntu.com/... git ...与Setting up git ...等行。
第 3 步:验证安装
git --version
回显:
git version 2.34.1
四、离线安装方案
离线安装适用于目标服务器无法访问互联网的场景:先在任一有网的 Ubuntu 22.04 机器上用 apt 把 deb 包下载到本地,再拷贝到离线服务器用 dpkg -i 安装。
第 1 步:下载 git 软件包(不安装)
使用 --download-only 只下载不安装,--reinstall 确保即使已安装也重新拉取包文件:
sudo apt install --reinstall --download-only -y git
回显:
Building dependency tree...
Reading state information...
0 upgraded, 0 newly installed, 1 reinstalled, 0 to remove and 8 not upgraded.
Need to get 3174 kB of archives.
After this operation, 0 B of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 git amd64 1:2.34.1-1ubuntu1.17 [3174 kB]
Fetched 3174 kB in 3s (1165 kB/s)
Download complete and in download only mode
第 2 步:查看下载缓存的 deb 文件
ls -lh /var/cache/apt/archives/*.deb | head
回显:
-rw-r--r-- 1 root root 3.1M Feb 27 2026 /var/cache/apt/archives/git_1%3a2.34.1-1ubuntu1.17_amd64.deb
-rw-r--r-- 1 root root 1.8M Jan 3 2022 /var/cache/apt/archives/neovim_0.6.1-3_amd64.deb
💡 说明:
/var/cache/apt/archives/是 apt 下载包的缓存目录。%3a是冒号:的 URL 编码形式,对应包版本1:2.34.1-...。缓存目录中可能残留其他历史包(如上例的 neovim),拷贝时只取 git 相关的 deb 即可。
第 3 步:拷贝 deb 到离线目录
mkdir -p /opt/devchain-demo/git-ubuntu-test/offline && cp /var/cache/apt/archives/git_*.deb /opt/devchain-demo/git-ubuntu-test/offline/
查看离线目录:
ls -lh /opt/devchain-demo/git-ubuntu-test/offline
回显:
total 3.1M
-rw-r--r-- 1 root root 3.1M Oct 6 06:34 git_1%3a2.34.1-1ubuntu1.17_amd64.deb
第 4 步:查看 deb 包元信息(可选)
用 dpkg-deb -I 读取包的依赖、描述等控制信息,确认包完整:
dpkg-deb -I /opt/devchain-demo/git-ubuntu-test/offline/git_1%3a2.34.1-1ubuntu1.17_amd64.deb | head -25
回显:
new Debian package, version 2.0.
size 3173622 bytes: control archive=15190 bytes.
34 bytes, 1 lines conffiles
1736 bytes, 29 lines control
44856 bytes, 603 lines md5sums
185 bytes, 5 lines * postinst #!/bin/sh
185 bytes, 5 lines * postrm #!/bin/sh
971 bytes, 37 lines * preinst #!/bin/sh
185 bytes, 5 lines * prerm #!/bin/sh
Package: git
Version: 1:2.34.1-1ubuntu1.17
Architecture: amd64
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Installed-Size: 18484
Depends: libc6 (>= 2.34), libcurl3-gnutls (>= 7.56.1), libexpat1 (>= 2.0.1), libpcre2-8-0 (>= 10.34), zlib1g (>= 1:1.2.0), perl, liberror-perl, git-man (>> 1:2.34.1), git-man (<< 1:2.34.1-.)
Recommends: ca-certificates, patch, less, ssh-client
Suggests: gettext-base, git-daemon-run | git-daemon-sysvinit, git-doc, git-email, git-gui, gitk, gitweb, git-cvs, git-mediawiki, git-svn
Breaks: bash-completion (<< 1:1.90-1), cogito (<= 0.18.2+), dgit (<< 5.1~), git-buildpackage (<< 0.6.5), git-el (<< 1:2.32.0~rc2-1~), gitosis (<< 0.2+20090917-7), gitpkg (<< 0.15), guilt (<< 0.33), openssh-client (<< 1:6.8), stgit (<< 0.15), stgit-contrib (<< 0.15)
Provides: git-completion, git-core
Section: vcs
Priority: optional
Multi-Arch: foreign
Homepage: https://git-scm.com/
Description: fast, scalable, distributed revision control system
第 5 步:离线安装
将 deb(及其依赖包)拷贝到离线服务器的任一目录,然后安装:
sudo dpkg -i /opt/devchain-demo/git-ubuntu-test/offline/git_1%3a2.34.1-1ubuntu1.17_amd64.deb
⚠️ 注意:git 依赖
libc6、libcurl3-gnutls、libexpat1、libpcre2-8-0、zlib1g、perl、liberror-perl、git-man等包。全新系统上这些依赖可能也需要一并离线下载(可在有网机器上用sudo apt install --download-only -y git不加--no-install-recommends时一并下载,或逐个apt download)。多数服务器基础环境已具备 libc6 等基础库,只需补充 git-man 与 liberror-perl。若dpkg -i报依赖缺失,用sudo apt -f install修复,或继续用dpkg -i按依赖顺序安装其余 deb。
安装完成后验证:
git --version
回显:
git version 2.34.1
五、命令与参数详解
以下所有命令均在测试目录 /opt/devchain-demo/git-ubuntu-test 下真实执行,回显逐行照抄。先准备测试环境:
mkdir -p /opt/devchain-demo/git-ubuntu-test
git config --global user.name "Dev User"
git config --global user.email "dev@example.com"
💡 说明:
user.name与user.email会写入提交作者信息,不配置则 commit 会失败并提示Please tell me who you are。
5.1 基础命令:--version / --help / help -a / config
git --version:查看版本号
git --version
回显:
git version 2.34.1
git --help:查看主命令用法
git --help
回显(关键片段):
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[--super-prefix=<path>] [--config-env=<name>=<envvar>]
<command> [<args>]
These are common Git commands used in various situations:
start a working area (see also: git help tutorial)
clone Clone a repository into a new directory
init Create an empty Git repository or reinitialize an existing one
work on the current change (see also: git help everyday)
add Add file contents to the index
mv Move or rename a file, a directory, or a symlink
restore Restore working tree files
rm Remove files from the working tree and from the index
examine the history and state (see also: git help revisions)
git help -a:列出所有可用子命令
git help -a | head -30
回显(关键片段):
See 'git help <command>' to read about a specific subcommand
Main Porcelain Commands
add Add file contents to the index
am Apply a series of patches from a mailbox
archive Create an archive of files from a named tree
bisect Use binary search to find the commit that introduced a bug
branch List, create, or delete branches
bundle Move objects and refs by archive
checkout Switch branches or restore working tree files
cherry-pick Apply the changes introduced by some existing commits
citool Graphical alternative to git-commit
clean Remove untracked files from the working tree
clone Clone a repository into a new directory
commit Record changes to the repository
describe Give an object a human readable name based on an available ref
diff Show changes between commits, commit and working tree, etc
fetch Download objects and refs from another repository
format-patch Prepare patches for e-mail submission
gc Cleanup unnecessary files and optimize the local repository
gitk The Git repository browser
grep Print lines matching a pattern
gui A portable graphical interface to Git
init Create an empty Git repository or reinitialize an existing one
log Show commit logs
maintenance Run tasks to optimize Git repository data
merge Join two or more development histories together
mv Move or rename a file, a directory, or a symlink
notes Add or inspect object notes
pull Fetch from and integrate with another repository or a local branch
git config:查看/设置配置
git config --list
回显:
user.name=Dev User
user.email=dev@example.com
💡 说明:
git config支持三个作用域,可用--system(/etc/gitconfig)、--global(~/.gitconfig)、--local(仓库内 .git/config)指定,优先级 local > global > system。--list列出全部生效配置。
5.2 仓库创建与快照:init / status / add / commit / log / show
git init:初始化仓库
cd /opt/devchain-demo/git-ubuntu-test && git init work
回显:
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
Initialized empty Git repository in /opt/devchain-demo/git-ubuntu-test/work/.git/
💡 说明:Git 2.34 默认初始分支名为
master,并给出 hint 提示可通过git config --global init.defaultBranch main改为main。仓库元数据存放在隐藏目录.git/中。
git status:查看工作区状态
cd /opt/devchain-demo/git-ubuntu-test/work && git status
回显:
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
创建文件后再次查看状态
echo "Hello from Git" > hello.txt && git status
回显:
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.txt
nothing added to commit but untracked files present (use "git add" to track)
💡 说明:新文件
hello.txt处于未跟踪(Untracked)状态,git 尚未记录它。
git add:加入暂存区
git add hello.txt && git status
回显:
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hello.txt
💡 说明:
git add <file>把文件从工作区加入暂存区(index)。git add .可一次添加当前目录全部改动(含新增/修改/删除),本文按文件逐个演示。
git commit:创建提交快照
git commit -m "feat: 添加 hello.txt 文件"
回显:
[master (root-commit) f59b187] feat: 添加 hello.txt 文件
1 file changed, 1 insertion(+)
create mode 100644 hello.txt
💡 说明:
-m指定提交信息(commit message)。(root-commit)表示这是仓库的第一个提交,f59b187是提交哈希前缀。100644是普通文件权限模式。
分步 add + commit:继续追加两次提交
echo "Git version: 2.34.1" >> hello.txt
git add hello.txt
git commit -m "update: 补充 Git 版本信息"
回显:
[master e40d43c] update: 补充 Git 版本信息
1 file changed, 1 insertion(+)
mkdir -p src
echo "printf(\"Hello Git\\n\");" > src/main.c
echo "# Git 使用示例" > README.md
git add src/main.c README.md
git commit -m "feat: 添加 src/main.c 与 README"
回显:
[master a488ad6] feat: 添加 src/main.c 与 README
2 files changed, 2 insertions(+)
create mode 100644 README.md
create mode 100644 src/main.c
echo "Welcome to Git" > welcome.txt
git add welcome.txt
git commit -m "feat: 添加 welcome.txt"
回显:
[master a0fc89d] feat: 添加 welcome.txt
1 file changed, 1 insertion(+)
create mode 100644 welcome.txt
git log:查看提交历史
git log
回显:
commit a0fc89d095784162c5fb101e6870f1eb748760b7
Author: Dev User <dev@example.com>
Date: Tue Oct 6 06:35:12 2026 +0000
feat: 添加 welcome.txt
commit a488ad63e40f277835bb98f6f32d0e5a2f1831e3
Author: Dev User <dev@example.com>
Date: Tue Oct 6 06:35:08 2026 +0000
feat: 添加 src/main.c 与 README
commit e40d43c55c7677f9ef9e4ddb23878395c61685ce
Author: Dev User <dev@example.com>
Date: Tue Oct 6 06:35:07 2026 +0000
update: 补充 Git 版本信息
commit f59b187f5e74438287d984ec8244d261d44fee5e
Author: Dev User <dev@example.com>
Date: Tue Oct 6 06:35:00 2026 +0000
feat: 添加 hello.txt 文件
💡 说明:
git log按时间倒序展示每次提交的完整哈希、作者、时间与提交信息。最新提交在顶部。
git log --oneline:单行精简视图
git log --oneline
回显:
a0fc89d feat: 添加 welcome.txt
a488ad6 feat: 添加 src/main.c 与 README
e40d43c update: 补充 Git 版本信息
f59b187 feat: 添加 hello.txt 文件
💡 说明:
--oneline把每次提交压缩为"短哈希 + 提交信息"一行,是日常最常用的日志视图。
git log --graph:分支图形视图
git log --graph --oneline --all
回显(初始直线历史阶段):
* a0fc89d feat: 添加 welcome.txt
* a488ad6 feat: 添加 src/main.c 与 README
* e40d43c update: 补充 Git 版本信息
* f59b187 feat: 添加 hello.txt 文件
💡 说明:
--graph用*、|、\等字符绘制提交图;--all覆盖所有分支(含远程跟踪分支)。当存在分支合并时,图形会呈现分叉与合流(见 5.9 节 merge 后回显)。
git log --stat:每次提交的文件变更统计
git log --stat -1
回显:
commit a0fc89d095784162c5fb101e6870f1eb748760b7
Author: Dev User <dev@example.com>
Date: Tue Oct 6 06:35:12 2026 +0000
feat: 添加 welcome.txt
welcome.txt | 1 +
1 file changed, 1 insertion(+)
💡 说明:
--stat显示每次提交涉及的文件及增删行数;-1限定只显示最近 1 条。
git log -p:完整补丁视图
git log -p -1 | head -30
回显:
commit a0fc89d095784162c5fb101e6870f1eb748760b7
Author: Dev User <dev@example.com>
Date: Tue Oct 6 06:35:12 2026 +0000
feat: 添加 welcome.txt
diff --git a/welcome.txt b/welcome.txt
new file mode 100644
index 0000000..6b7935a
--- /dev/null
+++ b/welcome.txt
@@ -0,0 +1 @@
+Welcome to Git
💡 说明:
-p(patch 模式)展示每次提交的完整代码差异:+开头为新增行,-开头为删除行。
git show:查看指定提交详情
git show HEAD
回显:
commit a0fc89d095784162c5fb101e6870f1eb748760b7
Author: Dev User <dev@example.com>
Date: Tue Oct 6 06:35:12 2026 +0000
feat: 添加 welcome.txt
diff --git a/welcome.txt b/welcome.txt
new file mode 100644
index 0000000..6b7935a
--- /dev/null
+++ b/welcome.txt
@@ -0,0 +1 @@
+Welcome to Git
git show --stat:只看文件统计
git show --stat HEAD
回显:
commit a0fc89d095784162c5fb101e6870f1eb748760b7
Author: Dev User <dev@example.com>
Date: Tue Oct 6 06:35:12 2026 +0000
feat: 添加 welcome.txt
welcome.txt | 1 +
1 file changed, 1 insertion(+)
💡 说明:
HEAD指向当前分支最新提交;git show也可接提交哈希、分支名、标签名(如git show v1.0)。
5.3 分支管理:branch / checkout / switch
git branch:列出本地分支
git branch
回显:
* master
💡 说明:
*标记当前所在分支。
git branch dev:创建分支
git branch dev && git branch -a
回显:
* master
dev
💡 说明:
git branch <name>仅创建分支指针,不切换。-a列出全部分支(含远程跟踪分支)。
git checkout dev:切换分支
git checkout dev && git branch
回显:
Switched to branch 'dev'
* dev
master
git switch -c feature:创建并切换分支
git switch -c feature && git branch
回显:
Switched to a new branch 'feature'
dev
* feature
master
💡 说明:
git switch是 Git 2.23 起新增的专用于分支切换的命令,-c等价于"创建并切换",即checkout -b的现代替代。功能上二者等价。
git checkout -b temp:创建并切换(旧式)
git checkout master
git checkout -b temp
回显:
Switched to branch 'master'
Switched to a new branch 'temp'
在 temp 分支上提交一次后切回 master:
echo "temp" > temp.txt
git add temp.txt
git commit -m "temp: 临时分支提交"
git checkout master
回显:
[temp 6c9640a] temp: 临时分支提交
1 file changed, 1 insertion(+)
create mode 100644 temp.txt
Switched to branch 'master'
git branch -d:删除已合并分支
git branch -d temp
回显:
error: The branch 'temp' is not fully merged.
If you are sure you want to delete it, run 'git branch -D temp'.
⚠️ 注意:
-d只允许删除已被合并(改动已并入其他分支)的分支,防止误删未合并的工作;确认要丢弃该分支的全部提交时用-D强制删除:
git branch -D temp
回显:
Deleted branch temp (was 6c9640a).
git branch -a:查看含远程跟踪分支的完整列表
在后续配置远程仓库(5.8 节)之后执行:
git branch -a
回显:
dev
feature
* master
temp
remotes/origin/master
💡 说明:
remotes/origin/master是远程跟踪分支,记录本地最后一次与origin/master同步的位置。
5.4 差异查看:diff
在 master 分支对 hello.txt 追加一行(不提交):
echo "Add a new line to hello" >> hello.txt
git diff:工作区 vs 暂存区
git diff
回显:
diff --git a/hello.txt b/hello.txt
index a4143c7..f978ceb 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,2 +1,3 @@
Hello from Git
Git version: 2.34.1
+Add a new line to hello
💡 说明:
git diff默认比较工作区与暂存区,展示尚未git add的改动。
git add 后再看三种 diff
git add hello.txt
git diff --cached:暂存区 vs HEAD
git diff --cached
回显:
diff --git a/hello.txt b/hello.txt
index a4143c7..f978ceb 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,2 +1,3 @@
Hello from Git
Git version: 2.34.1
+Add a new line to hello
git diff HEAD:工作区 vs HEAD(含已暂存与未暂存全部改动)
git diff HEAD
回显:
diff --git a/hello.txt b/hello.txt
index a4143c7..f978ceb 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,2 +1,3 @@
Hello from Git
Git version: 2.34.1
+Add a new line to hello
💡 说明:此时暂存区与 HEAD 差异即当前全部差异;若工作区还有未暂存改动,
git diff HEAD会包含它们而git diff只显示未暂存部分。
git diff --stat:差异统计
再追加一行未暂存改动后:
echo "Second uncommitted line" >> hello.txt
git diff --stat
回显:
hello.txt | 1 +
1 file changed, 1 insertion(+)
💡 说明:
--stat只统计每个文件的增删行数,不显示具体内容;若工作区与暂存区无差异则无输出。
随后提交该改动,保持仓库干净:
git add hello.txt
git commit -m "update: hello.txt 增加两行说明"
回显:
[master 881a161] update: hello.txt 增加两行说明
1 file changed, 2 insertions(+)
5.5 回滚与修复:reset / restore
git reset --soft:软回退(保留暂存区)
echo "soft data" > soft.txt
git add soft.txt
git commit -m "wip: 临时提交 soft.txt"
回显:
[master 96b402d] wip: 临时提交 soft.txt
1 file changed, 1 insertion(+)
create mode 100644 soft.txt
git reset --soft HEAD~1
git status
回显:
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: soft.txt
💡 说明:
reset --soft仅移动 HEAD 指针、撤销提交,不改动暂存区与工作区——soft.txt 仍处于暂存状态,可重新 commit 或取消暂存。
git restore --staged:取消暂存
git restore --staged soft.txt
git status --short
回显:
?? soft.txt
💡 说明:
restore --staged <file>把文件从暂存区移回工作区(即反git add),??表示文件回到未跟踪状态。git 2.23 起推荐用restore替代git reset HEAD <file>的旧写法。
git restore:还原工作区文件
echo "temporary edit" >> hello.txt
git status --short
回显:
M hello.txt
?? soft.txt
git restore hello.txt
git status --short
回显:
?? soft.txt
💡 说明:
git restore <file>用暂存区/HEAD 内容覆盖工作区,丢弃未提交的修改。⚠️ 该操作不可撤销,误改的本地内容会永久丢失。
git reset --hard:硬回退(丢弃提交与工作区改动)
echo "precious data" > keep.txt
git add keep.txt
git commit -m "wip: keep.txt 提交"
回显:
[master 0ef0e2a] wip: keep.txt 提交
1 file changed, 1 insertion(+)
create mode 100644 keep.txt
此时对 keep.txt 再追加一行"脏"修改,然后硬回退:
echo "dirty change" >> keep.txt
git reset --hard HEAD~1
git status --short
git log --oneline -2
回显:
HEAD is now at 507e0e2 update: welcome.txt 增加说明
?? soft.txt
507e0e2 update: welcome.txt 增加说明
881a161 update: hello.txt 增加两行说明
⚠️ 注意:
reset --hard会把 HEAD、暂存区、工作区三处全部回退到目标提交——本次提交的 keep.txt 及其后追加的 dirty change 全部消失,且不可通过 git 正常途径找回(只能借助git reflog恢复,见 5.10 节)。执行前务必确认工作区没有需要保留的未提交内容。
5.6 标签:tag / tag -l / describe
先提交当前 stash 恢复的内容,使 HEAD 处于可打标签的位置:
git add welcome.txt
git commit -m "update: welcome.txt 增加说明"
回显:
[master 507e0e2] update: welcome.txt 增加说明
1 file changed, 1 insertion(+)
git tag:创建轻量标签
git tag v1.0
💡 说明:
git tag <name>创建轻量标签(仅指向当前提交的引用),无额外信息,无回显输出。
git tag -a -m:创建附注标签
git tag -a v1.1 -m "发布候选版本 v1.1"
💡 说明:
-a创建附注标签(annotated tag,含打标签者、时间与说明,存储为独立对象),-m指定标签说明。
git tag / git tag -l:列出标签
git tag
回显:
v1.0
v1.1
git tag -l
回显:
v1.0
v1.1
💡 说明:
git tag与git tag -l均列出全部标签;-l支持通配过滤,如git tag -l "v1.*"。
git describe:为提交生成可读名称
git describe
回显:
v1.1
💡 说明:
git describe返回离当前 HEAD 最近的标签名;若 HEAD 位于标签后的若干提交,会输出如v1.1-3-gabc1234(距离标签 3 个提交)的格式,常用于生成版本号。
5.7 暂存工作:stash
git stash:暂存未提交改动
echo "uncommitted work" >> welcome.txt
git status --short
git stash
回显:
M welcome.txt
Saved working directory and index state WIP on master: 881a161 update: hello.txt 增加两行说明
💡 说明:
git stash把工作区与暂存区的未提交改动临时保存,并还原为干净状态,适合临时切换分支处理紧急事务。此时git status应为空。
git stash list:列出暂存栈
git stash list
回显:
stash@{0}: WIP on master: 881a161 update: hello.txt 增加两行说明
git stash pop:恢复暂存改动
git stash pop
回显:
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: welcome.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (88dcf8326e1cdab8b504e7f771811b454e0769fb)
💡 说明:
git stash pop把最近一次 stash 恢复回工作区并从栈中移除(回显末尾Dropped refs/stash@{0})。若想保留栈中记录,用git stash apply。
5.8 远程协作:bare 仓库 + clone / remote / push / pull
远程协作需要一台"裸仓库"(bare repository,不含工作区的纯对象库,通常以 .git 结尾)。以下用本机路径模拟远程服务器仓库,完成 clone → push → pull 完整闭环。
git init --bare:创建裸仓库
cd /opt/devchain-demo/git-ubuntu-test && git init --bare repo.git
回显:
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
Initialized empty Git repository in /opt/devchain-demo/git-ubuntu-test/repo.git/
git clone:克隆仓库
git clone /opt/devchain-demo/git-ubuntu-test/repo.git clone1
回显:
Cloning into 'clone1'...
warning: You appear to have cloned an empty repository.
done.
💡 说明:克隆空仓库时会出现
You appear to have cloned an empty repository警告,属正常现象。克隆完成后,远程地址会自动以origin命名保存。
git remote -v:查看远程地址
cd clone1 && git remote -v
回显:
origin /opt/devchain-demo/git-ubuntu-test/repo.git (fetch)
origin /opt/devchain-demo/git-ubuntu-test/repo.git (push)
💡 说明:
git remote -v列出所有远程仓库及其 fetch/push 地址。克隆产生的默认远程名为origin。
在 clone1 中提交并推送
echo "shared content" > shared.txt
git add shared.txt
git commit -m "feat: clone1 提交 shared.txt"
git push origin master
回显:
[master (root-commit) 02e3b5b] feat: clone1 提交 shared.txt
1 file changed, 1 insertion(+)
create mode 100644 shared.txt
To /opt/devchain-demo/git-ubuntu-test/repo.git
* [new branch] master -> master
💡 说明:
git push origin master把本地 master 推送到远程 origin 的 master,首次推送输出* [new branch] master -> master。
在 work 仓库添加远程地址
cd /opt/devchain-demo/git-ubuntu-test/work
git remote add origin /opt/devchain-demo/git-ubuntu-test/repo.git
git remote -v
回显:
origin /opt/devchain-demo/git-ubuntu-test/repo.git (fetch)
origin /opt/devchain-demo/git-ubuntu-test/repo.git (push)
💡 说明:
git remote add origin <url>为本地仓库注册一个名为 origin 的远程地址(仅本地记录,不回显输出)。
git pull:拉取远程改动(分叉场景)
work 仓库与裸仓库历史无关(各自独立 root commit),首次拉取会因分支分叉报错:
git pull origin master
回显:
From /opt/devchain-demo/git-ubuntu-test/repo
* branch master -> FETCH_HEAD
* [new branch] master -> origin/master
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge (the default strategy)
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.
💡 说明:Git 2.27+ 在本地分支与远程分支分叉且未配置拉取策略时会拒绝自动合并,要求显式指定
--rebase(变基)或--no-rebase(合并)。
先按默认合并策略拉取,因两段历史完全无关,git 会拒绝合并:
git pull --no-rebase origin master
回显(末尾片段):
From /opt/devchain-demo/git-ubuntu-test/repo
* branch master -> FETCH_HEAD
fatal: refusing to merge unrelated histories
⚠️ 注意:
refusing to merge unrelated histories说明本地与远程没有共同祖先提交。正常协作场景中两个仓库源自同一祖先,不会出现此问题;本例因两仓库是各自独立初始化的,故需显式允许:
git pull origin master --no-rebase --allow-unrelated-histories
回显:
From /opt/devchain-demo/git-ubuntu-test/repo
* branch master -> FETCH_HEAD
Merge made by the 'ort' strategy.
shared.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 shared.txt
💡 说明:
--allow-unrelated-histories允许合并无共同祖先的历史,本次合并采用默认的ort合并策略,拉入 clone1 提交的 shared.txt。
git push:推送本地提交到远程
git push origin master
回显:
To /opt/devchain-demo/git-ubuntu-test/repo.git
02e3b5b..b57ac05 master -> master
💡 说明:
02e3b5b..b57ac05表示远程 master 从 02e3b5b 前进到 b57ac05,work 仓库的完整历史已推送到裸仓库。
git pull:远程跟踪 + 快进合并(Fast-forward)
推送一个新提交后,在 clone1 拉取:
echo "v2 note" > note.txt
git add note.txt
git commit -m "docs: 添加 note.txt"
git push origin master
回显:
[master 55fb781] docs: 添加 note.txt
1 file changed, 1 insertion(+)
create mode 100644 note.txt
To /opt/devchain-demo/git-ubuntu-test/repo.git
b57ac05..55fb781 master -> master
cd /opt/devchain-demo/git-ubuntu-test/clone1
git pull origin master
回显:
From /opt/devchain-demo/git-ubuntu-test/repo
* branch master -> FETCH_HEAD
b57ac05..55fb781 master -> origin/master
Updating b57ac05..55fb781
Fast-forward
note.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 note.txt
💡 说明:
Fast-forward快进合并——远程 master 是本地 master 的直接后继提交,无需产生合并提交,直接前移指针。至此 clone → push → pull 完整闭环验证通过。
5.9 合并与挑选:merge / cherry-pick
git merge:合并分支(含冲突解决)
先在 dev 分支修改 hello.txt 并提交,再切回 master 合并:
git checkout dev
echo "dev branch feature line" >> hello.txt
git add hello.txt
git commit -m "dev: 在 hello.txt 增加开发分支内容"
git checkout master
git merge dev
回显:
Switched to branch 'dev'
[dev 9dc2ecb] dev: 在 hello.txt 增加开发分支内容
1 file changed, 1 insertion(+)
Switched to branch 'master'
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.
💡 说明:dev 与 master 在同一文件同一区域做了不同修改,git 无法自动合并,产生内容冲突(CONFLICT)。查看冲突文件:
git status --short
cat hello.txt
回显:
UU hello.txt
Hello from Git
Git version: 2.34.1
<<<<<<< HEAD
Add a new line to hello
Second uncommitted line
=======
dev branch feature line
>>>>>>> dev
💡 说明:
<<<<<<< HEAD与=======之间是当前分支(master)内容,=======与>>>>>>> dev之间是待合并分支(dev)内容。手动编辑文件,保留需要的行,删除冲突标记后重新提交:
printf "Hello from Git\nGit version: 2.34.1\nAdd a new line to hello\nSecond uncommitted line\ndev branch feature line\n" > hello.txt
git add hello.txt
git commit -m "merge: 合并 dev 分支并解决 hello.txt 冲突"
git log --graph --oneline -6
回显:
[master 6e6ca04] merge: 合并 dev 分支并解决 hello.txt 冲突
* 6e6ca04 merge: 合并 dev 分支并解决 hello.txt 冲突
|\
| * 9dc2ecb dev: 在 hello.txt 增加开发分支内容
* | 507e0e2 update: welcome.txt 增加说明
* | 881a161 update: hello.txt 增加两行说明
|/
* a0fc89d feat: 添加 welcome.txt
* a488ad6 feat: 添加 src/main.c 与 README
💡 说明:冲突解决并提交后即生成合并提交
6e6ca04,git log --graph清晰展示两分支分叉(|\)再合流(|/)的图形。
git cherry-pick:挑选应用其他分支的单个提交
在 feature 分支创建提交,然后在 master 上只挑选这一个提交:
git checkout feature
echo "feature content" > feature.txt
git add feature.txt
git commit -m "feat: feature 分支新增 feature.txt"
git checkout master
git cherry-pick daab805
回显:
Switched to branch 'feature'
[feature daab805] feat: feature 分支新增 feature.txt
1 file changed, 1 insertion(+)
create mode 100644 feature.txt
Switched to branch 'master'
[master 04ed974] feat: feature 分支新增 feature.txt
Date: Tue Oct 6 06:37:21 2026 +0000
1 file changed, 1 insertion(+)
create mode 100644 feature.txt
💡 说明:
git cherry-pick <commit>把指定提交的改动以"新提交"形式应用到当前分支(新提交哈希与源提交不同),常用于把某个修复单独移植到发布分支。
5.10 文件与对象管理:rm / mv / blame / grep / ls-files / clean / fsck / reflog
git rm:删除文件并记录删除
git rm src/main.c
git status --short
回显:
rm 'src/main.c'
D src/main.c
💡 说明:
git rm同时删除工作区与暂存区中的文件,D表示删除待提交。若误删,可先git restore --staged src/main.c取消暂存,再git restore src/main.c恢复工作区文件:
git restore --staged src/main.c
git restore src/main.c
ls src/
回显:
main.c
git mv:重命名/移动文件
git mv welcome.txt welcome.md
git status --short
回显:
R welcome.txt -> welcome.md
💡 说明:
R表示重命名(rename),git 通过内容相似度自动识别。改回原名:
git mv welcome.md welcome.txt
git blame:逐行溯源
git blame hello.txt | head -8
回显:
^f59b187 (Dev User 2026-10-06 06:35:00 +0000 1) Hello from Git
e40d43c5 (Dev User 2026-10-06 06:35:07 +0000 2) Git version: 2.34.1
881a161a (Dev User 2026-10-06 06:36:01 +0000 3) Add a new line to hello
881a161a (Dev User 2026-10-06 06:36:01 +0000 4) Second uncommitted line
💡 说明:
git blame <file>逐行显示"提交哈希 + 作者 + 时间 + 行号 + 内容",用于定位某行代码的引入者与引入时机。
git grep:在受版本控制的文件中搜索
git grep -n "Git"
回显:
README.md:1:# Git 使用示例
hello.txt:1:Hello from Git
hello.txt:2:Git version: 2.34.1
src/main.c:1:printf("Hello Git\n");
welcome.txt:1:Welcome to Git
💡 说明:
git grep只搜索已纳入版本控制的文件(不回显未跟踪/忽略文件),-n显示行号。
git ls-files:列出暂存区(已跟踪)文件
git ls-files
回显:
README.md
hello.txt
src/main.c
welcome.txt
git clean -n / -f:清理未跟踪文件
git clean -n
回显:
Would remove soft.txt
git clean -f
回显:
Removing soft.txt
⚠️ 注意:
git clean删除未跟踪文件,-n(dry-run)先预览将被删除的文件,-f才真正执行。删除不可恢复,务必先用-n确认。
git fsck:检查仓库对象完整性
git fsck
回显:
dangling commit 88dcf8326e1cdab8b504e7f771811b454e0769fb
dangling blob f978ceb30d355dcb72b7aff7436a7528d443cf2c
💡 说明:
dangling(悬空)对象是曾被引用、后被丢弃的对象(如git stash pop弹出的 stash 提交),属于正常现象,可定期用git gc清理。
git reflog:查看 HEAD 移动日志
git reflog | head -10
回显:
507e0e2 HEAD@{0}: reset: moving to HEAD~1
0ef0e2a HEAD@{1}: commit: wip: keep.txt 提交
507e0e2 HEAD@{2}: reset: moving to HEAD~1
96b402d HEAD@{3}: commit: wip: 临时提交 soft.txt
507e0e2 HEAD@{4}: commit: update: welcome.txt 增加说明
881a161 HEAD@{5}: reset: moving to HEAD
881a161 HEAD@{6}: commit: update: hello.txt 增加两行说明
a0fc89d HEAD@{7}: checkout: moving from temp to master
6c9640a HEAD@{8}: commit: temp: 临时分支提交
a0fc89d HEAD@{9}: checkout: moving from master to temp
💡 说明:
git reflog记录 HEAD 的每一次移动(commit/reset/checkout 等),是误操作后的"后悔药"。例如git reset --hard误删提交后,可依据 reflog 中的哈希用git reset --hard <hash>恢复。
六、配置说明
Git 配置分三个层级,git config --list 汇总显示全部生效配置:
git config --list
回显:
user.name=Dev User
user.email=dev@example.com
常用配置项:
| 配置项 | 说明 | 示例 |
|---|---|---|
user.name | 提交作者姓名 | git config --global user.name "Dev User" |
user.email | 提交作者邮箱 | git config --global user.email "dev@example.com" |
init.defaultBranch | 新仓库默认分支名 | git config --global init.defaultBranch main |
core.editor | 提交信息默认编辑器 | git config --global core.editor vim |
pull.rebase | 拉取时默认变基(true)/合并(false) | git config --global pull.rebase false |
core.autocrlf | 行尾符转换(Windows 协作时常用 input) | git config --global core.autocrlf input |
alias.* | 命令别名 | git config --global alias.co checkout |
💡 说明:
--global写入~/.gitconfig,--system写入/etc/gitconfig,不带参数写入当前仓库.git/config(local 优先级最高)。
七、常见问题(FAQ)
Q1:git pull 报 Need to specify how to reconcile divergent branches?
本地与远程分支分叉且未配置拉取策略所致。解决:显式指定策略,git pull --rebase origin master(变基)或 git pull --no-rebase origin master(合并);或执行 git config pull.rebase false(默认合并)永久解决。
Q2:git pull 报 fatal: refusing to merge unrelated histories?
本地与远程没有共同祖先提交,常见于两仓库独立初始化后强行关联。确认安全后加 --allow-unrelated-histories:git pull origin master --allow-unrelated-histories。正常从同一仓库 clone 的场景不会遇到。
Q3:git branch -d 报 The branch 'xxx' is not fully merged?
该分支还有未合并进其他分支的提交。若确认丢弃这些提交,用 git branch -D xxx 强制删除。
Q4:git commit 报 Please tell me who you are?
未配置作者身份。执行 git config --global user.name "你的名字" 与 git config --global user.email "你的邮箱" 后重试。
Q5:误执行 git reset --hard 丢了代码?
先用 git reflog 找到误操作前的提交哈希(如 HEAD@{3}),再 git reset --hard <hash> 恢复;或 git cherry-pick <hash> 只恢复某个提交。
Q6:文件显示 CRLF/LF 行尾警告?
跨平台协作常见。执行 git config --global core.autocrlf input(Linux/macOS 提交时转 LF)或按项目规范统一配置。
Q7:删除文件却不想从工作区移除(仅取消跟踪)?
git rm --cached <file> 只把文件移出版本控制,保留本地文件。
八、卸载与清理
查看安装的 git 软件包
dpkg -l git
回显:
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-====================-============-===================================================
ii git 1:2.34.1-1ubuntu1.17 amd64 fast, scalable, distributed revision control system
💡 说明:第一列
ii表示已安装且配置正常(Desired=install、Status=installed)。
卸载 Git
sudo apt remove -y git
💡 说明:
apt remove删除程序本体,保留全局配置文件(如 ~/.gitconfig);如需连配置一并清除:
sudo apt purge -y git
清理 apt 缓存与依赖
sudo apt autoremove -y
sudo apt clean
💡 说明:
autoremove卸载不再需要的依赖包,clean清空 /var/cache/apt/archives 下的 deb 缓存(含离线安装方案下载的包文件)。
九、参考链接
- Git 官方文档:https://git-scm.com/doc
- Pro Git 中文版(免费在线书):https://git-scm.com/book/zh/v2
- Git 参考手册:https://git-scm.com/docs
- Ubuntu 软件包页面(git):https://packages.ubuntu.com/jammy/git