GIit

Git 是什么?

Git 是一个分布式版本控制系统

Git 是一个对项目文件管理的工具,有着版本控制等功能

git本地仓库的工作原理

git 文件管理 会 忽略 .gitignore 文件中的文件路径

命令速查

1. 初始化本地仓库

1
git init

创建.git文件夹,存放修改前后的版本信息,方便回滚以及记录

.git 是隐藏文件夹,需要设置显示隐藏文件夹才可以显示

2. 提交文件到缓冲区

1
2
3
4
5
//全部提交
git add .

// 单个文件
git add first_file.txt

3. 查看仓库状态

1
git status

4.提交暂存区文件进仓库

1
git commit -m "本次提交修改的注释,可以任意文本"

提交工作区的文件进仓库

1
2
git commit -a -m "你的提交信息"

不需要进入暂存区就提交工作区的文件,其中-a是-all 全部的意思

注意,这个方法不提交新的文件,只针对git 已追踪的文件,即已存在的文件,新文件提交仍然需要gitadd再git commit

5.查看提交日志(可查看提交人、分支、文件、时间)

1
2
3
git log


指令有其他参数git log [option],其中option的值有

  • 分支名,可单独查看分支的 修改

  • --all

显示所有分支

  • --all d

提交信息为一行

  • --abbrev-commit

让输出的commitId简短

  • --graph

以图片形式显示

1
git log --graph --all --pretty=oneline --abbrev-commit

其余更多请参考git log命令参数详解 - 知乎 (zhihu.com)


所有日志,包括回退的日志

1
git reflog

6.版本回退

1
git reset  --hard commitID

commitID 通过 git log 查看

--soft--mixed以及--hard是三个恢复等级。

  • 使用--soft就仅仅将头指针恢复,已经add的暂存区以及工作空间的所有东西都不变。
  • 如果使用--mixed,就将头恢复掉,已经add的暂存区也会丢失掉,工作空间的代码什么的是不变的。
  • 如果使用--hard,那么一切就全都恢复了,头变,aad的暂存区消失,代码什么的也恢复到以前状态。

注意!!!

使用git reset只会把git已追踪的文件回退,不会把新建立的文件删除

如果要清理新建立的文件有俩种方式

  1. git add加入追踪后回退
  2. git clean清理未追踪的文件

7. 查看分支

1
git branch

8. 创建分支

1
git branch 分支名

9. 切换分支

1
2
3
git checkout 分支名
//or
git switch 分支名

HEAD指向当前分支

切换到一个不存在的分支,即创建新分支并复制当前分支内容并切换

1
2
3
git checkout -b 分支名 
//or
git switch -c 分支名

10. 删除分支

1
2
3
4
5
git branch -d 分支名
//↑ 需要做各种检查

//不做检查强制删除
git branch -D 分支名

11.合并分支

首先使用git switch或者git checkout选择需要保留的分支上

1
git merge 分支名

合并后esc+:+wq退出合并文本编辑

处理分支

当是使用merge合并分支的时候,如果有相同的文件修改了不一样的变动,即冲突,此时git会自动合并,git并不会处理冲突,只在命令行告诉你什么地方会有冲突:

image-20240515085927238

在test.txt 文件内是这样的

image-20240515090143129

其中`HEAD=====分割线是你所合并的主分支内容,等号分割线下到hello是被我合并的分支(hello 是我合并的分支名)

之后手动修改需要解决的冲突内容,可以选择都保留,也可以选择留下一部分,git add+git commit上传本地仓库,以下是项目流程结构图

image-20240515094404470

禁用Fast forward

默认的快速合并的结果:

image-20240522143722591

其中新建用户是dev的commit ,快速合并中HEAD直接指向dev,导致dev的提交信息被遗失了

以下是 禁用快速合并的结果

image-20240522144153222

如图所示,合并后的commit信息还在

1
git merge --no-ff feature-branch
squash

如果分支commit太多太乱,可以使用

1
2
git merge --squash feature-branch

这项指令会让所有的提交合并为一个提交进行合并,并且不保留合并信息


变基

1
git rebase 

交换commit的顺序,重写commit的顺序,让提交历史更加简洁易懂

具体待续…


12. 远程仓库

先要关联远程仓库

1
git remote add origin 远程仓库地址
  • origin的作用是给远程仓库地址起一个别名为origin,这是一个默认名字,可以替换,相当于c语言的typedef以及#define,origin作为远程仓库的地址添加到本地仓库,在之后的拉取代码,推送代码的过程中就不需要每次都打一大串的远程仓库地址

查看绑定的远程仓库地址

1
git remote -v

有多少个远程仓库

建议使用上面的指令查看,包含关系关系如下图

image-20240518203302693

1
git remote 

推送到远程仓库

最常用的指令

1
git push -u origin main
  • 命令为推送文件夹的所有不被忽略的文件到origin所指的仓库地址的main分支上
  • -u--set-upstream的缩写

用于关联远程仓库与本地仓库的指定分支,关联后不需要指定分支名就可以使用git push以及git pull指令

查看本地分支以及远程仓库分支的跟踪状态

1
git branch -vv

image-20240518204251921

修改关联分支仓库

1
git branch -u origin/new-branch old-branch-name

完全指令

1
git push [-f] [--set-upstream][远端名称[本地分支名][:远端分支名]]
  • -f ,即--force如果指令加入,则是不理会推送冲突(即他人的提交或者在远程仓库的修改),强制覆盖
  • --set-upstream也就是-u上面有详细解释
  • 远端名称,即远程仓库地址,可用别名替代,也就是默认设置的origin
  • 如果远程仓库和本地仓库一致,则省略[:远程分支]
  • 推送到不同的名称的的分支示例git push -u origin main:yuan_branch ,本地的main分支推送到了远程的yuan_branch分支

克隆 远程仓库

clone,和词意相当,也就是把远程仓库的全部文件下载到本地

1
2
3
git clone 远程仓库地址 [本地文件夹名称]
//例如
git clone https://github.com/用户名/仓库名.git repo
  • 本地文件夹名称可省略,会在当前自动创建一个远程仓库名的文件夹。并把所有的文件下载到这个文件夹里面

设置了文件夹名则是在目录下创建文件夹名的文件夹,并把所有的文件下载到这个文件夹里面。


连接远程仓库

除了push时连接远程仓库外还可以通过以下方法

git checkout --track origin/dev

作用:

  1. 创建一个名为 dev 的本地分支(假设远程分支是 origin/dev)。
  2. 切换到这个新创建的本地分支。
  3. 配置这个本地分支以跟踪远程分支 origin/dev

1
2
git checkout -b dev origin/dev  # 创建并切换到本地分支 dev,从 origin/dev 的当前提交开始
git branch --set-upstream-to=origin/dev # 配置本地分支 dev 以跟踪 origin/dev

将这两个步骤合并为一步

1
2
git checkout -b dev --track origin/dev


13.抓取和拉取远程仓库

抓取:fetch,获取远程仓库的最新修改,创造一个origin/分支名的新分支,不会自动合并需要你手动合并

以下是使用方法:

  • 获取所有分支
1
git fetch origin
  • 获取远程仓库的某个分支
1
git fetch  origin main

抓取最新变化以后,需要你手动去合并分支,更新你的本地仓库的代码

拉取:full,获取远程仓库的修改,并且合并这个修改的代码到你的本地仓库,此时可能产生冲突,这时候就需要

也就是说,full其实是fetch+merge


14. 标签 tag

标签是git版本自定义文本的功能,让人更好的区分不同版本,而不是一串无规律的数字字母编号

可以理解为 给不同的 commit版本 起别名,或是一个 死指针 固定的指向那个 commit

git tag查看所有标签

git tag <tagname>创建一个标签,默认以当前分支的最新commit为基本

git tag <tagname> <commitID>给指定commitId进行打标签

git show <tagname>展示标签详细信息

git tag -a v0.1 -m "version 0.1 released" 1094adb给标签设置详细信息

git push origin <tagname>上传标签到远程仓库

git push origin master --tags上传全部标签到远程仓库

git tag -d <tagname>删除标签

git push origin --delete <tagname>远程仓库的标签删除

git push origin :refs/tags/<tagname>同上

Git - 打标签 (git-scm.com)


15. 贮藏 stash

当我在一个分支中,已经完成了一部分的开发,但是还不能提交,这时候我需要切换到另一个分支(例如有紧急bug),这个时候切换分支未提交的文件就会一起带到另一个分支上,

这个时候我们就需要冷藏这个分支上未提交的工作区。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ git status
On branch hello
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: "\345\210\206\346\224\257.txt"

no changes added to commit (use "git add" and/or "git commit -a")

Yee@Yee MINGW64 ~/Desktop/gitdome (hello)
$ git stash
Saved working directory and index state WIP on hello: 336d4e3 Merge branch 'dev2'

Yee@Yee MINGW64 ~/Desktop/gitdome (hello)
$ git status
On branch hello
nothing to commit, working tree clean

这个时候工作区就干净了,可以任意切换分支了

git stash贮藏

git stash list查看所有的贮藏

1
2
3
$ git stash list
stash@{0}: WIP on hello: 336d4e3 Merge branch 'dev2'

可以通过下述命令来标记此次储藏,以便后期查看

1
git stash save [stashMessage]

解封/恢复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git stash apply
On branch dev
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: "\346\226\260\345\273\272\347\224\250\346\210\267.txt"

no changes added to commit (use "git add" and/or "git commit -a")

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git stash list
stash@{0}: WIP on dev: fc958c7 新建用户
stash@{1}: WIP on dev: fc958c7 新建用户
stash@{2}: WIP on hello: 336d4e3 Merge branch 'dev2'

通过git stash apply可以解封,但是还存在在stash list中,通过git stash drop删除,可以看出,stash是一个栈结构

git stash drop
1
2
3
4
5
6
7
git stash drop
Dropped refs/stash@{0} (f4c2dafa4382f0d70657cf4c713bf39e336ef0e0)

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git stash list
stash@{0}: WIP on dev: fc958c7 新建用户
stash@{1}: WIP on hello: 336d4e3 Merge branch 'dev2'

git stash pop通过这个可以一键删除并恢复

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
$ git stash
Saved working directory and index state WIP on dev: fc958c7 新建用户

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git stash list
stash@{0}: WIP on dev: fc958c7 新建用户
stash@{1}: WIP on dev: fc958c7 新建用户
stash@{2}: WIP on hello: 336d4e3 Merge branch 'dev2'

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git stash pop
On branch dev
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: "\346\226\260\345\273\272\347\224\250\346\210\267.txt"

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (72215c233f434ebd7e98eac7421ccf26d8b626b1)

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git stash list
stash@{0}: WIP on dev: fc958c7 新建用户
stash@{1}: WIP on hello: 336d4e3 Merge branch 'dev2'

假如我有多个贮藏

1
2
3
4
 git stash list
stash@{0}: WIP on dev: fc958c7 新建用户
stash@{1}: WIP on hello: 336d4e3 Merge branch 'dev2'

我可以选择一个git stash apply stash@{0}指定的编号去恢复


16. 工作区回退/暂存区回退 checkout / reset/restore

checkout

工作区的文件在修改后可以执行两种操作:

  • git add

    确认工作无误后,把文件上传到暂存区,再commit一个新版本

  • git checkout -- 文件名

    发现工作有错误,回退到修改之前

  • git restore

    git 2.23 版本后出现的回退指令

首先,使用git status查看仓库状态,这是一个干净无修改的工作区

我们修改一个test.txt,添加一行字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git status
On branch main
nothing to commit, working tree clean

//添加一行字符串后
$ git status
On branch main
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: test.txt

no changes added to commit (use "git add" and/or "git commit -a")

git restore是git 2.23出现的新指令,用于清晰语义,因为checkout是切换分支有歧义…

先使用git checkout -- 文件名测试

1
2
3
4
5
6
7
$ git checkout -- test.txt

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
nothing to commit, working tree clean

这样做就回退test.txt文件到了commit-->HEAD的状态


restore

现在使用git restore测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
nothing to commit, working tree clean

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
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: test.txt

no changes added to commit (use "git add" and/or "git commit -a")

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git restore test.txt

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
nothing to commit, working tree clean

一样可以完成结果,回复到暂存区的状态

如果想回退到HEAD-->,那么指令是git restore --source=HEAD example.txt


在查资料的时候看见git restore --staged <file>

这个是清空暂存区中的文件(仅从暂存区移除,不影响工作区)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
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: hello.txt
modified: test.txt

no changes added to commit (use "git add" and/or "git commit -a")

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git add .

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.txt
modified: test.txt

//再修改工作区的test

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.txt
modified: test.txt

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: test.txt



Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git restore --staged test.txt

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.txt

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: test.txt

我们可以看到暂存区的文件被退回了,但是工作区已经修改的文件仍然还在


reset

如果是想仅仅是把暂存区的文件放回工作区可以使用:git reset HEAD <file>

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
31
Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.txt

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: test.txt
modified: "\350\277\231\346\230\257hello2.txt"


Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git reset HEAD hello.txt
Unstaged changes after reset:
M hello.txt
M test.txt
M 这是hello2.txt

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
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: hello.txt
modified: test.txt
modified: "\350\277\231\346\230\257hello2.txt"

以下是gpt的介绍

git reset 是一个非常强大的 Git 命令,用于撤销更改和移动 HEAD 指针。它可以用于重置暂存区的文件、更改当前分支的提交历史,甚至更新工作目录。以下是详细的用法和示例:

基本用法:

1
2
3
sh
复制代码
git reset [<mode>] [<commit>]

模式:

  1. —soft:仅移动 HEAD 指针,不改变暂存区和工作区的内容。
  2. —mixed(默认模式):移动 HEAD 指针,并重置暂存区为指定的 commit,但不改变工作区的内容。
  3. —hard:移动 HEAD 指针,重置暂存区,并更新工作区,使其与指定的 commit 一致。

用法和示例:

  1. --soft 模式

仅重置 HEAD 指针,不改变暂存区和工作区。这种模式适合想保留更改但移动提交历史的情况。

1
2
sh复制代码# 移动 HEAD 指针到指定的提交,但保留暂存区和工作区的更改
git reset --soft <commit>

示例:

1
2
3
sh
复制代码
git reset --soft HEAD~1

这个命令会把 HEAD 指针移到上一个提交,保留当前的所有更改为已暂存状态。

  1. --mixed 模式(默认)

重置 HEAD 指针和暂存区,但保留工作区的更改。这是默认模式,适合想保留更改但从暂存区移除的情况。

1
2
sh复制代码# 移动 HEAD 指针到指定的提交,并重置暂存区,但保留工作区的更改
git reset --mixed <commit>

示例:

1
2
3
sh
复制代码
git reset --mixed HEAD~1

这个命令会把 HEAD 指针移到上一个提交,并将当前的更改从暂存区移除,但保留在工作区。

  1. --hard 模式

重置 HEAD 指针、暂存区和工作区,使其全部与指定的 commit 一致。这会丢失所有未提交的更改。

1
2
sh复制代码# 移动 HEAD 指针到指定的提交,并重置暂存区和工作区,使它们与该提交一致
git reset --hard <commit>

示例:

1
2
3
sh
复制代码
git reset --hard HEAD~1

这个命令会把 HEAD 指针移到上一个提交,并丢弃所有未提交的更改。


其他示例

  1. 重置单个文件

如果只想重置暂存区中的某个文件,可以使用:

1
2
3

复制代码
git reset <file>

这个命令会把指定文件从暂存区移除,但保留在工作区。

  1. 移动到特定提交
1
2
3
sh
复制代码
git reset --hard <commit_hash>

这个命令会把 HEAD、暂存区和工作区都重置到指定的提交。

  1. 撤销最近的提交但保留更改
1
2
3
sh
复制代码
git reset --soft HEAD~1

这个命令会撤销最近的提交,但保留所有更改为已暂存状态。

git reset 是一个功能强大且多用途的命令,可以用来修改提交历史、重置暂存区和工作区。根据不同的模式,可以选择适合当前需求的操作方式:

  • —soft 保留所有更改,但移动 HEAD 指针。
  • —mixed 重置暂存区,但保留工作区更改。
  • —hard 丢弃所有未提交的更改,并重置到指定的提交。

ps.reset偷个懒用的gpt的介绍

总结

回退分为三种

  1. 回退工作区
  • git checkout <file>
  • git restore <file>
  1. 文件从暂存区到工作区,不影响工作区
  • git reset HEAD <file>
  • git restore --staged <file>
  1. commit、暂存区、工作区都变为commit一个版本
  • `git reset --hard commit_id

17. 删除文件

git rm <file>

暂存区和工作区都删除文件,只需要commit,相当于手动删除+git add

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

$ git rm hello.txt
rm 'hello.txt'

Yee@Yee MINGW64 ~/Desktop/gitdome (main)
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: hello.txt

$ git commit -m "删除hello"
[main f979439] 删除hello
1 file changed, 1 deletion(-)
delete mode 100644 hello.txt



18.版本差异

git diff 是一个用于显示未提交更改的 Git 命令。它可以显示工作区和暂存区之间的差异、暂存区和最近一次提交之间的差异,以及其他特定的比较。以下是 git diff 的详细用法和一些常见示例:

基本用法

1
git diff

显示工作区中未暂存的更改。

常见示例

  1. 查看工作区和暂存区之间的差异
1
git diff

这个命令会显示工作区中未暂存的更改。

  1. 查看暂存区和最近一次提交之间的差异
1
git diff --cached

这个命令(或者 git diff --staged)会显示已暂存但还未提交的更改。

  1. 查看工作区和最近一次提交之间的差异
1
git diff HEAD

这个命令会显示工作区中所有未提交的更改,无论它们是否已经暂存。

  1. 查看两个分支之间的差异
1
git diff branch1 branch2

这个命令会显示 branch1branch2 之间的差异。

  1. 查看两个提交之间的差异
1
git diff commit1 commit2

这个命令会显示 commit1commit2 之间的差异。

  1. 查看特定文件的差异
1
git diff HEAD <file>

这个命令会显示当前工作区中的特定文件和最近一次提交之间的差异。

  1. 查看特定目录的差异
1
git diff HEAD <directory>/

这个命令会显示当前工作区中的特定目录和最近一次提交之间的差异。

其他有用的选项

  • 显示简洁的差异

    1
    git diff --stat

    这个命令会以简洁的统计方式显示更改。

  • 忽略空白字符的差异

    1
    git diff --ignore-all-space

    这个命令会忽略空白字符的更改。

  • 显示统一格式的差异(默认格式)

    1
    git diff --unified

    这个命令会以统一格式显示更改,默认情况下 git diff 就是使用这种格式。

  • 仅显示名称的差异

    1
    git diff --name-only

    这个命令会仅显示文件名称,而不显示具体的更改内容。

例子

假设你有一个项目目录,修改了 file1.txtfile2.txt 文件,现在想查看这些修改:

  1. 查看未暂存的更改:

    1
    git diff
  2. 暂存更改:

    1
    git add file1.txt
  3. 查看已暂存的更改:

    1
    git diff --cached
  4. 提交更改:

    1
    git commit -m "修改了 file1.txt 和 file2.txt"

    总结

git diff 是一个非常强大的工具,用于比较文件的不同版本。它可以帮助你在提交更改之前了解具体的修改内容,并且可以在多个不同的上下文中使用,从而提供灵活的比较方式。

19. 复制其他分支的提交到当前分支 cherry-pick

git cherry-pick <commit>

应用场景:我在bug修改提交或者main提交后,我想在我当前dev分支获取main提交的时候,就可以使用这个,不需要合并。

20. 忽略文件

在git仓库根目录中,命名一个.gitignore

在这个目录中的目录或者文件名都不会出现在git的提交中,隐私信息或者配置信息就不会发出去

也就是说git不再追踪.gitignore写入的文件

如果你忽略了,但是你确实想提交git add -f App.class

如果你发现你的目录写错了,但是找不到问题,git check-ignore -v App.class会提醒你哪里出了问题

如果想添加不被排除的文件

例如

1
2
3
*.class
但是我想要文件 App.class
!App.class

就可以实现不排除App.class了


21. 清理未追踪的文件

未追踪的文件指:

  • 未通过add 添加到暂存区的文件
  • .gitignore 文件写入的目录文件

通过git clean可以清除未追踪的文件

git clean -n显示哪些文件将被删除,并不是删除,而是删除前查看将删除的文件同git clean --dry-run

git clean -f强制删除。git clean --force

git clean -f -d删除未追踪的目录,git clean一般只删除文件,不删除目录,需要删除目录则使用这个

git clean -f -X仅删除忽略掉的文件。即.gitignore指定的文件

git clean -f -x删除所有未追踪的文件和忽略的文件。这个选项会删除所有未追踪的文件,包括那些在 .gitignore 文件中指定的文件。

22 .撤销提交的revert

相比reset的重置,把新的commit删除,revert会新建一个提交把旧的版本逆转,并保留原先的commit,保留提交历史的完整性

git revert <commitid>

image-20240522192833426

1
2
3
4
5
* c778266 qevert "revert_test_2"
* b39474d revert_test_3
* 2ce70d9 revert_test_2
* d029a3d revert_test_1

会发现原来的commit依旧存在,并且还添加了一个commit,显示逆转到了revert

允许多个撤销git revert <commit> <commit> <commit>....,会一个一个撤销/逆转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ git revert  e90405d   4e41599 c778266
[dev 13b68aa] Revert "cs5"
1 file changed, 1 deletion(-)
[dev f53dff4] Revert "revert_test_4"
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 asa.txt
[dev 504f1d3] Revert "qevert "revert_test_2""
1 file changed, 4 deletions(-)

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git log --graph --all --pretty=oneline --abbrev-commit
* 504f1d3 (HEAD -> dev) Revert "qevert "revert_test_2""
* f53dff4 Revert "revert_test_4"
* 13b68aa Revert "cs5"
* ff40ccb cs6
* e90405d cs5
* 4e41599 revert_test_4

1
2
3
4
5
6
7
8
9
10
11
 git revert 2ce70d9
Auto-merging revert.txt
CONFLICT (content): Merge conflict in revert.txt
error: could not revert 2ce70d9... revert_test_2
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git revert --continue".
hint: You can instead skip this commit with "git revert --skip".
hint: To abort and get back to the state before "git revert",
hint: run "git revert --abort".

出现冲突时

在提示的文件中修改冲突后,可以选择git add/rm <pathspec>,添加到暂存区,再git revert --continue继续还原

当有多个逆转提交时可以使用git revert --skip跳过这个改变提交,而执行其他的逆转,比如git revert A B C D,C出现了冲突,我选择git revert --skip,这个时候ABD仍然逆转,C的修改不变。

git revert --abort逆转过程中,有冲突的时候使用这个语句将中止当前所有逆转,并返回到git revert

23. 检索

git grep [options] pattern [-- [pathspec...]]

  • pattern

    字符串或者正则表达式

  • [不同的模式]

  • pathspec

    搜索的文件或者目录

常用选项

  • -i:忽略大小写。

    1
    git grep -i "pattern"
  • -n:显示匹配行的行号。

    1
    git grep -n "pattern"
  • -v:反向匹配,显示不包含匹配模式的行。

    1
    git grep -v "pattern"
  • -c:只显示匹配的行数。

    1
    git grep -c "pattern"
  • -l:只显示包含匹配模式的文件名。

    1
    git grep -l "pattern"
  • --cached:在索引(暂存区)中搜索。

    1
    git grep --cached "pattern"
  • <commit>:在指定提交中搜索。

    1
    2
    git grep "pattern" HEAD
    git grep "pattern" commit_hash
  • <branch>:在指定分支中搜索。

    1
    git grep "pattern" branch_name
  • --:分隔符,用于区分路径和模式。

    1
    git grep "pattern" -- path/to/file_or_directory

例子:

1
2
3
4
5
6
7
8
9
10
11
$ git grep 测试
revert.txt:测试1
revert.txt:测试2
revert.txt:测试3

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git grep -n 测试
revert.txt:1:测试1
revert.txt:3:测试2
revert.txt:5:测试3

24. 溯源 blame

git blame [options] <file>

查看文件被谁修改以及提交信息等等

例子:

1
2
3
4
5
6
7
8
9
10
11
$ git blame test.txt
86960c55 (yee1819 2024-05-15 08:53:55 +0800 1) 25616515
86960c55 (yee1819 2024-05-15 08:53:55 +0800 2)
074914c1 (yee1819 2024-05-15 09:37:42 +0800 3)
074914c1 (yee1819 2024-05-15 09:37:42 +0800 4) 这是在main分支输入的内容
336c576f (yee1819 2024-05-15 08:55:38 +0800 5) 这里是hello 分支的内容
074914c1 (yee1819 2024-05-15 09:37:42 +0800 6)
133c7fd3 (yee1819 2024-05-22 10:14:54 +0800 7) ttttt
133c7fd3 (yee1819 2024-05-22 10:14:54 +0800 8)
133c7fd3 (yee1819 2024-05-22 10:14:54 +0800 9) 6666

选项:

  • -L <start>,<end>:限制只显示特定范围的行。

    1
    git blame -L 10,20 <file>

    只显示从第 10 行到第 20 行的修改记录。

  • -c:使用简短的提交哈希。

    1
    git blame -c <file>
  • -e:显示作者的 email 地址。

    1
    git blame -e <file>
  • -f:显示完整的文件名和行号。

    1
    git blame -f <file>
  • -l:显示包含换行符的行。

    1
    git blame -l <file>
  • -p:显示更详细的原始信息。

    1
    git blame -p <file>
  • --since=<date>--until=<date>:限制显示从某个日期开始或截止的修改。

    1
    2
    3
    git blame --since=2.weeks <file>
    例如:
    $ git blame --since="2023-01-01" test.txt
  • -C:检测代码搬移(跨文件)。

    1
    git blame -C <file>

25. flow 分支管理系统

一套详细的分支管理策略主要分为

  1. 主分支(master):始终保持可发布状态,包含已经发布的版本。
  2. 开发分支(develop):包含即将发布的功能,作为功能分支的集成分支。
  3. 功能分支(feature):用于开发新功能,基于 develop 创建,完成后合并回 develop
  4. 发布分支(release):用于准备新版本的发布,基于 develop 创建,完成后合并回 masterdevelop
  5. 热修复分支(hotfix):用于修复紧急问题,基于 master 创建,完成后合并回 masterdevelop

需要先置安装,有独特的一套指令,以及良好的结构化规范,不过多了解。

26. worktree 仓库

当工作中需要频繁切换分支的时候,可以创建一个新的工作目录,相当于复制一个仓库来方便切换

git worktree add <path> [branch]

  • <path>为路径

  • [branch] 可选的分支名,如果不填写,则自动创建一个与路径目录名相同的分支。如果该分支已存在则切换到同名分支。

    如果没有这个分支则需要加一个-b

例子:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

填写分支且不存在该分支
$ git worktree add ../my-feature-branch -b feature-branch
Preparing worktree (new branch 'feature-branch')
HEAD is now at 504f1d3 Revert "qevert "revert_test_2""


不填写分支且不存在该分支
$ git worktree add ../my-feature-branch2
Preparing worktree (new branch 'my-feature-branch2')
HEAD is now at 504f1d3 Revert "qevert "revert_test_2""


$ git branch
ck_ts
* dev
dev2
+ feature-branch
hello
hello2
main
+ my-feature-branch2


$ git worktree list
C:/Users/Yee/Desktop/gitdome 504f1d3 [dev]
C:/Users/Yee/Desktop/my-feature-branch 504f1d3 [feature-branch]
C:/Users/Yee/Desktop/my-feature-branch2 504f1d3 [my-feature-branch2]


填写分支且存在该分支
$ git worktree add ../dev2
Preparing worktree (checking out 'dev2')
HEAD is now at 7ff7fe3 登录功能


Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git branch
ck_ts
* dev
+ dev2
+ feature-branch
hello
hello2
main
+ my-feature-branch2


image-20240522201614876

删除工作目录

git worktree remove <path>

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ git worktree remove ../my-feature-branch

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git worktree remove ../dev2

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git worktree list
C:/Users/Yee/Desktop/gitdome 504f1d3 [dev]
C:/Users/Yee/Desktop/my-feature-branch2 504f1d3 [my-feature-branch2]

Yee@Yee MINGW64 ~/Desktop/gitdome (dev)
$ git branch
ck_ts
* dev
dev2
feature-branch
hello
hello2
main
+ my-feature-branch2

可以发现,工作目录虽然删除了,但是分支依旧还在。

特点:

  • 共享同一个 Git 仓库:所有工作目录共享同一个 Git 仓库,因此对象存储和引用(如提交、分支、标签)是共享的。

  • 独立的工作树和索引:每个工作目录都有自己的工作树和索引,因此在一个工作目录中的未提交更改不会影响其他工作目录。

    类似贮藏和切换分支

  • 适用于并行开发:使用 git worktree 可以同时在多个分支上进行开发,而不需要频繁切换分支。


999.给命令起别名

一些指令需要配置一堆参数,每次打的话会浪费很多时间例如查看日志`git log一般都会带以下参数:git log --graph --all --pretty=oneline --abbrev-commit

每次都打会很麻烦,这个时候就需要起个别名,每次只要需要打一点指令就可以执行一长串的命令

alias

998.Git - Git 钩子 (git-scm.com)

不同方式本地连接github的方法

git bash 命令行

github 桌面版

github GUI

待续计划

  • [ ] 变基 rebase