Write by lyc at 2020-4-9
参考教程:《廖雪峰Git教程》
Update by lyc at 2022-2-24:重新学习

git 学习笔记2:增删改查

1.创建本地仓库与提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1.git init:创建版本库
cd ${Project_Name} && git init # 切换到一个空目录下,创建一个代码库
git init ${Project_Name} # 新建一个Project_Name目录并初始化为git代码库

# 2.git add:添加工作区文件到暂存区
git add [file1] [file2] ... # 从工作区添加指定文件到暂存区
git add [dir] # 从工作区添加指定目录到暂存区,包括子目录
git add . # 添加当前目录的所有文件到暂存区

# 3.git commit:将暂存区文件提交到本地仓库
git commit [file1] -m "${MESSAGE}" # 提交暂存区的指定文件到本地仓库
git commit -m "${MESSAGE}" # 提交暂存区到本地仓库
git commit -az "${MESSAGE}" # 直接提交工作区的文件到本地仓库

## 修改 commit 的备注信息
git commit --amend # 修改最新的一次commit message,而后使用vim进行编辑保存
git rebase -i ${OLD_COMMID_ID} # 修改历史的message,${OLD_COMMID_ID} 是要改的commit的上一个commit的id

查看当前仓库状态,比较文件区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 4.git status:查看工作区文件的变化
git status # 查看变更的文件
git status -s # 查看显示较少的信息

# 5.git diff:差异比较
git diff id id
git diff HEAD HEAD^ # 本次与上一次的差别
git diff HEAD HEAD^^ # 本次与上两次的差别
git diff HEAD HEAD~1
git diff HEAD HEAD~2
git diff HEAD -- readme.txt # 本次的某个文件差别

git diff --cached # 暂存区与HEAD比较
git diff # 暂存区与工作区比较

# 比较分支
git diff temp master # 比较两个分支最近的一次提交
git diff temp master -- index.html # 精确比较某个文件
git diff commit_id commit_id

2.版本回退、回滚

GIT回退到指定版本的两种方法(reset/revert)

实现多人合作程序开发的过程中,我们有时会出现错误提交的情况,此时我们希望能撤销提交操作,让程序回到提交前的样子,以下总结了两种解决方法:reset, revert

git log 确定回滚的版本

先使用 git log 来确定想要回滚到哪一个 commit 版本

1
2
3
4
5
6
7
8
9
# 查看commit日志
git log # 显示当前分支的版本历史
git log --pretty=oneline # 每个commit仅显示一行log,方便查看
git log --oneline # 简洁的显示commit历史
git log -n2 # 显示最近两次commit历史
git log -n2 --oneline # 简洁的显示最近两次commit历史
git log --oneline --all # 所有分支的历史
git log --oneline --all --graph # 图形化
git log --graph --pretty=oneline --abbrev-commit

回滚之前,先来了解一下几个关于 HEAD 的关键字:

  • HEAD 当前版本
  • HEAD^ 上一个版本
  • HEAD^^ 上上一个版本
  • HEAD~100 上一百个版本

git reset 版本回退

该命令会强行覆盖当前版本和要回退的版本之间的其他版本(不太建议)。

1
2
3
git reset --hard HEAD^          # 回滚到上一个版本
git reset --hard HEAD^^ # 回滚到上上一个版本
git reset --hard ${COMMIT_ID} # 回滚到指定 commit id 版本

如果你忘记了回滚的某个 ${COMMIT_ID},可以用 git reflog 来查看你的每一次 git 命令记录的

1
2
3
4
5
6
7
8
9
10
11
# 查看命令历史
Administrator@DESKTOP-77SDJG0 MINGW64 /d/lyc/git/learngit (master)
$ git reflog
683d979 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^^
81222a5 HEAD@{1}: reset: moving to 81222a56
c9094e7 HEAD@{2}: reset: moving to HEAD^
81222a5 HEAD@{3}: commit: append GPL. # 这是第一个head的commit id,找到了
c9094e7 HEAD@{4}: commit: add line name
683d979 (HEAD -> master) HEAD@{5}: commit (initial): add READ.md

$ git reset --hard 81222a5

此时再推到远程仓库用 git push 会报错,需要用 -f 强推上去才可以。

1
git push -f 

git revert 版本回退

再当前版本的基础上新增一个版本,不影响以前的代码

1
2
git log --oneline
git revert -n ${COMMIT_ID}

这里可能会出现冲突,那么需要手动修改冲突的文件。就正常的提交流程就可以了,会生成一个新的版本在最新,不会影响到以前的版本。

3.撤销 commit 前的修改

对于还未添加到暂存区文件,可以直接丢弃工作区的修改:

1
2
git checkout -- <file>      # 丢弃工工作区的某个文件的丢该
git checkout -- . # 丢弃工作区的所有文件修改

对于已经添加到到暂存区,还未 commit 到仓库区:

1
2
git reset HEAD readme.txt       # 先把文件从暂存区重新放回工作区
git checkout -- readme.txt # 再丢弃文件在工作区中的丢该

git reset 命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用 HEAD 时,表示最新的版本。

在 commit 推送到远程仓库之前,都可以撤销,但是如果把 commit 推送到远程仓库,那就无法撤销了!

4.删除文件

1
2
3
4
5
6
7
8
9
10
# 首先从操作系统中删除工作区中的某个文件
rm -f 1.txt

# git 识别到工作区中的文件被删除了,git status可以查看到状态
# 情况1:确实要删除这个文件
git rm 1.txt # 提交删除动作到暂存区->提交暂存区删除动作到本地仓库区
git commit -m "rm 1.txt" # commit

# 情况2:在工作区删错文件了,要从暂存区恢复
git checkout -- 1.txt

git mv 改名文件

1
git mv [old_file] [new_file]    # 改名文件,并将这个变动放入暂存区

5.找回之前版本删除过的目录

我要找回 roles/node-exporter 这个目录。首先查看 commit_id

1
2
3
4
5
6
7
8
9
10
$ git log --oneline
bfa4f4d (HEAD -> develop, origin/develop) rabbitmq剧本编写, 支持部署单节点/三节点集群
6ed2cf7 ## 2023-10-24 更新内容
1975f96 gpgcheck: no
240fb8c 剔除ucloud配置
e5bacf5 rsync适配rockylinux9
9727376 弃用二进制node-exporter # 这次提交被删除
751b528 剔除参数CLOUD # 因此是删除的上一个版本的 commit_id
aaec767 适配rockylinux9
1b4b775 Nginx 默认安装版本提升至 1.22.1,zlib, pcre, pcre2, openssl 依赖版本更新到最新

替换 为包含被删除目录的先前提交的哈希值, 是被删除目录的路径。

1
git checkout <commit-hash> -- <directory-path>

即:

1
$ git checkout 751b528 -- roles/node_exporter

验证,该目录已添加到当前的 暂存区:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git status -s
A roles/node_exporter/CHANGELOG.md
A roles/node_exporter/README.md
A roles/node_exporter/defaults/main.yml
A roles/node_exporter/handlers/main.yml
A roles/node_exporter/meta/main.yml
A roles/node_exporter/node_exporter.yml
A roles/node_exporter/tasks/app_check.yml
A roles/node_exporter/tasks/app_install.yml
A roles/node_exporter/tasks/app_register.yml
A roles/node_exporter/tasks/app_service.yml
A roles/node_exporter/tasks/main.yml
A roles/node_exporter/templates/node_exporter.service.j2
A roles/node_exporter/templates/node_exporter.yml.j2
A roles/node_exporter/vars/main.yml