Git常用功能总结
1 基础概念
1.1 工作区 / 暂存区 / 本地仓库 / 远程仓库
首先,先了解一下 Git 的构成部分可以帮助我们在后面使用 Git 指令时容易理解其实现原理。
- Workspace:工作区:项目文件所在目录,可能包含一个 .git(本地仓库) 子目录
- Staging Area:暂存区:也称为索引,其中所存储的是我们为下一次提交准备的内容,它以快照的形式保存了相关的文件内容
- Local Repository:本地仓库:本机,通常驻留在项目的 .git 目录中
- Remote Repository:远程仓库,非本机上的 Git 仓库,一般会是 GitHub
1.2 相关的 Git 命令
clone 远程仓库的代码到本地:
1 | git clone <远程仓库地址> |
把工作区修改的代码提交到暂存区:
1 | git add . |
把暂存区内容提交到本地仓库:
1 | git commit -m "feat: 提交说明" |
把本机仓库内容 push 到远程仓库上:
1 | git push origin <分支名> |
fetch 相关指令:
将某个远程主机的更新,全部取回本地:
1 | git fetch <远程主机名> |
取回特定分支的更新,可以指定分支名:
1 | git fetch <远程主机名> <分支名> |
pull 和 fetch 的区别:
pull 相当于 fetch 和 merge 的这两步操作:
1 | git fetch origin master // 从远程主机的 master 分支拉取最新内容 |
2 基础配置
2.1 设置提交用户
每个机器都必须自报家门:你的名字和 Email 地址。
1 | git config --global user.name "杨静" |
2.2 设置合并方式
为了能够让每一次提交都有明确的记录,统一使用 rebase 方式提交代码。在 Git Bash 中执行:
1 | git config --global pull.rebase true |
2.3 设置换行符
Windows 使用回车和换行两个字符来结束一行,而 Mac 和 Linux 只使用换行一个字符。Windows 系统可以在提交代码前输入命令:
1 | git config --global core.autocrlf false |
Windows 系统如果不设置换行符的话,项目代码拉取运行后可能会报下面的错误:
2.4 查看 Git 配置信息
用户名和账号配置好后查看下最终配置信息:
1 | git config --list |
3 撤销修改
3.1 撤销工作区内容
场景: 自从上次代码提交后,我们写了一些测试时用的代码例如 debugger、console.log() 等等。等我们测试完后我们并不想保存这些代码,想把他们从工作区删除掉,这个时候我们就可以使用 Git 的撤销功能。
3.1.1 使用 git checkout 撤销工作区修改
撤销指定文件在工作区的修改:
1 | git checkout -- <file> |
撤销所有文件在工作区的修改:
1 | git checkout -- . |
注意:git checkout -- file
命令中的 – 很重要,没有 --
就变成了 切换到另一个分支 的命令,我们在后面的分支管理中会再次遇到 git checkout
命令。
3.1.2 使用 git restore 撤销工作区修改
可能是因为 Git 版本不一样,我的电脑执行 git status 后是提示我使用 git restore 命令进行撤销的。
1 | git restore <file>... |
所以也就是说你在执行 git status 命令后,你可以使用 Git 提示的那个命令进行撤销操作。
3.1.3 使用小乌龟撤销工作区修改
使用小乌龟撤销工作区修改内容:
第一步: 选择 Revert 功能
第二步:选中你要撤销修改的文件点确定。
3.2 撤销暂存区内容
场景:假使自从上次提交代码后你写了一些测试代码,由于加班到凌晨三点脑子已经不好使了,习惯之下进行了 git add . 操作,庆幸的是在 commit 之前发现了这个问题,执行 git status 看一下,修改只是存到了暂存区,并没有提交。
3.2.1 使用 git reset 撤销暂存区内容
撤销指定文件暂存区的修改,重新放回工作区:
1 | git reset HEAD <file> // HEAD 也可以用 commitid 代替 |
撤销所有文件暂存区的修改,重新放回工作区:
1 | git reset HEAD . |
撤销所有文件暂存区的修改,直接撤销掉,不会重新放回工作区:
1 | git reset --hard HEAD // --hard 在这有一步到位的意思 |
已经执行 git add . 提交了暂存区,但是没有 commit:
可以使用 git reset HEAD
3.2.2 使用 git restore 撤销暂存区内容
可能是因为 Git 版本的问题,同样,我的电脑执行 git status 命令后,Git 提示我使用 git restore 进行回退。
3.3 撤销本地仓库内容(版本回退)
场景:git reset –hard 适合我们提交了错误的内容后进行回退的命令,因为执行这个命令后 Git 并不会将代码重新放回工作区。
Git 实现版本回退的原理是通过让 HEAD 这个指针指向其它版本来完成版本回退。
3.3.1 使用 git reset 实现版本回退
如果我们已经把内容 commit 到了本地仓库里,那么如果想撤销的话可以按照以下步骤:
第一步:查看历史提交记录,找到你想回退到那个版本的 commitid,copy 下来备用。
1 | git log |
第二步:执行 git reset 实现版本回退
1 | git reset --hard commitid |
注意:执行 git reset –hard 进行版本回退后,并不会重新把你提交为 commitid 的内容重新放回工作区。
拓展 1:在第二个步骤中如果你想回退至上一个版本,也可以用命令 git reset --hard HEAD^
来实现,因为在 Git 中,使用 HEAD
表示当前版本,那上一个版本就是 HEAD^
,上上个版本就是 HEAD^^
,当然往上 100 个版本写 100个 ^
比较容易数不过来,所以写成 HEAD~100
。
拓展 2:现在,你已经成功回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commitid
怎么办?
在 Git 中,总是有后悔药可以吃的:
- 使用
git reflog
查看每次的提交命令。 - 执行 git reset –hard commitid
4 分支管理
下图中的 HEAD 可以理解为指向 commit 对象的可变指针。
4.1 分支说明
为了避免代码合并经常会出现的冲突,保证随时拥有可发布的版本,使得持续集成和持续部署成为可能,我们采用基于主干的开发方式。分支可包含以下类型:
- master:主干分支,唯一一个长期存在的分支。所有的开发人员基于此分支进行开发,无特殊情况,提交直接 push 到这个分支上。
- release:发布分支,紧急情况下需要进行版本发布的时候,从 master 创建发布分支,进行测试完善,最终修改代码要合并回 master 分支。非特殊情况均通过 master 分支进行发布。
如无特殊情况,原则上禁止以下分支的创建。如想使用可以在本地按如下规范创建:
- feature/*:特性(功能)分支,用于开发新的功能,不同的功能创建不同的功能分支,功能分支开发完成并自测通过之后,需要合并到 master 分支,之后删除该分支。
- bugfix/*:bug 修复分支,用于修复不紧急的 bug,开发完成自测没问题合并进 master 分支后,删除该分支。
- hotfix/*:紧急 bug 修复分支,该分支只有在紧急情况下使用,从 release 分支创建,修复完成后,需要合并该分支到 release 分支,同时需要再合并回 master 分支。
4.2 创建与合并分支
说明:使用 Git 命令在本地新建的分支都属于本地分支,push 到远程之后远程仓库上才有此分支。
4.2.1 原理
我们在切换分支,和新建分支的时候,有没有想过,这些操作背后的工作原理是怎样的呢?最大的功臣就是 .git 目录下的 HEAD 引用,它从一个分支跳到另一个分支,虽无声无息,却精准无比。
下面一块来看一下 Git 是如何通过改变 HEAD 指向来实现创建、合并分支的。
一开始的时候,master 分支是一条线,Git 用 master 指向最新的提交,再用 HEAD 指向 master,就能确定当前分支,以及当前分支的提交点:
当我们创建新的分支,例如 dev 时,Git 新建了一个指针叫 dev,指向 master 相同的提交,再把 HEAD 指向 dev,就表示当前分支在 dev 上:
你看,Git创建一个分支很快,因为除了增加一个 dev 指针,改改 HEAD 的指向,工作区的文件都没有任何变化!
从现在开始,对工作区的修改和提交就是针对 dev 分支了,比如新提交一次后,dev 指针往前移动一步,而 master 指针不变:
当我们在 dev 上的工作完成了之后,就可以进行分支合并了,把 dev 分支合并到 master 分支上,其实 Git 的做法就是改变一下指针指向,把 master 分支指向 dev 的当前提交,就完成了合并。
完成了分支合并后,就可以把本地的 dev 分支给删除掉了,删除后就又剩下一个 master 分支。
**总结**:
4.2.2 实战
首先,我们创建 dev 分支,然后切换到 dev 分支:
1 | $ git checkout -b dev |
git checkout 命令加上 -b 参数表示创建并切换,相当于以下两条命令:
1 | $ git branch dev |
然后,用 git branch 命令查看当前分支:
1 | $ git branch |
git branch 命令会列出所有分支,当前分支前面会标一个 * 号。
然后,我们就可以在 dev 分支上正常提交,比如对 readme.txt 做个修改,加上一行:
1 | ## 这是 dev 分支的内容 |
把上方内容提交之后,执行 git checkout master
切换回 master 分支,这时候发现刚才提交的内容不见了,这是因为 master 分支此刻的提交点并没有改变:
现在,我们把 dev 分支的工作成果合并到 master 分支上:
1 | $ git merge dev |
git merge 命令用于合并指定分支到当前分支。合并后,再查看 readme.txt 的内容,就可以看到,和 dev 分支的最新提交是完全一样的。
拓展:注意到上面的 Fast-forward 信息,Git 告诉我们,这次合并是“快进模式”,也就是直接把 master 指向 dev 的当前提交,所以合并速度非常快。当然,也不是每次合并都能 Fast-forward,我们后面会讲其他方式的合并。
合并完成后,就可以放心地删除 dev 分支了:
1 | $ git branch -d dev |
删除后,查看 branch,就只剩下 master 分支了:
1 | $ git branch |
因为创建、合并和删除分支非常快,所以 Git 鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在 master 分支上工作效果是一样的,但过程更安全。但是分支合并时很可能要解决冲突,很可能要花时间解决冲突,所以虽然 Git 鼓励你使用分支来完成某个任务,但是要不要新建分支还是需要你视情况而定。
4.2.3 拓展内容
4.2.3.1 使用 switch 命令切换分支
刚才我们知道使用
git checkout <branch>
命令可以切换分支,前面讲撤销工作区内容的时候是使用git checkout -- <file>
。这两种方式很容易让人弄混git checkout
的用法。所以 Git 新版本就使用git switch
分支来切换分支,更语义化。
创建并切换到新的 dev 分支:
1 | git switch -c 分支名 |
直接切换到已有分支:
1 | git switch 分支名 |
4.2.3.2 git merge 和 git merge –no-ff 的区别
Fast-forward 方式就是当条件允许的时候,Git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit。如果要强制禁用 Fast forward模式,Git 就会在 merge 时生成一个新的 commit,这样,从分支历史上就可以看出分支信息。
下面我们一起看一下使用–no-ff 禁用掉 Fast-forward 模式的 git merge 合并方式:
首先,仍然创建并切换 dev 分支:
1 | $ git switch -c dev |
修改 readme.txt 文件,并提交一个新的 commit:
1 | $ git add readme.txt |
现在,我们切换回 master:
1 | $ git switch master |
准备合并 dev 分支,请注意 –no-ff 参数,表示禁用 Fast forward:
1 | $ git merge --no-ff -m "merge with no-ff" dev |
因为本次合并要创建一个新的 commit,所以加上 -m 参数,把 commit 描述写进去。
合并后,我们用 git log 看看分支历史:
1 | $ git log --graph --pretty=oneline --abbrev-commit |
可以看到,不使用 Fast forward 模式,merge 后就像这样:
之前使用 Fast forward 模式合并, merge 后是这样子的:
4.2.4 总结
- 查看分支:git branch
- 创建分支:git branch
- 切换分支:git checkout
或者 git switch - 创建+切换分支:git checkout -b
或者 git switch -c - 合并某分支到当前分支:git merge
或者 git merge –no-ff -m “提交说明” <分支名> - 删除已被合并过的分支:git branch -d
- 删除还未被合并的分支:git branch -D
- 分支合并时 –no-ff 的作用: 合并分支时,加上–no-ff 参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而 Fast forward 合并就看不出来曾经做过合并。
4.3 解决冲突
前面我们合并分支时 Git 输出的信息有一个
Fast-forward
Git 告诉我们,这次合并是“快进模式”,也就是直接把 master 指向 dev 的当前提交。但是合并操作并不总是简单的改变指针指向的这种 “快进模式”的。当 Git 无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
先来制造一个冲突的场景
新建 feature1 本地分支:
1 | $ git switch -c feature1 |
修改 readme.txt 最后一行,改为下方文字后执行 git add . 和 git commit 提交。
1 | Creating a new branch is quick AND simple. |
切换到 master 分支并修改 readme.txt 文件最后一样为下方文字并进行提交:
1 | Creating a new branch is quick & simple. |
现在,master 分支和 feature1 分支各自都分别有新的提交,变成了这样:
这种情况下,Git 无法执行“快速合并”,因为 HEAD 指针简单的指向谁都不能完成最终的合并,只能试图把各自的修改合并起来,但这种合并就可能会有冲突。
我们切换到 master 分支后把 feature1 分支合并到 master 分支:
1 | $ git merge feature1 |
这个时候我们就需要手动解决冲突,冲突解决后再进行提交。
解决冲突时你要清楚的知道 Current Change 和 Incoming Change 的代码都来自哪里。
最后就是删除掉 feature1 本地临时分支:
1 | $ git branch -d feature1 |
拓展:使用 git log --graph --pretty=oneline --abbrev-commit
指令也可以看到分支的合并情况:
总结:
- 当 Git 无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
- 解决冲突就是把 Git 合并失败的文件手动编辑为我们希望的内容,再提交。
- 用 git log –graph 命令可以看到分支合并图。
4.4 分支使用时常遇问题
4.4.1 使用 git stash 解决问题
场景1:当你正在开发一个功能 A 时,刚开发到一半突然接到需要在一小时内修复一个 bug,但是功能 A 的工作预计还要一天才能开发完,当时在 dev 分支开发的一一部分功能 A 功能也还没有提交,并不是你不想提交,而是工作只进行到一半,还没法提交,但是又必须在 1 小时内修复 bug 该怎么办?
这个时候就可以用到 Git 提供的 stash 功能了:
先把当前工作现场“储藏”起来(相当于还原到和服务器上一样的代码,当前工作区是干净状态)。
1 | $ git stash |
现在,用 git status 查看工作区,git 显示工作区是干净的,现在可以放心的修改 bug 了。
现在修复 bug,需要把“现在存在一个 bug”改为“bug 修复完成”,然后提交。
1 | $ git add readme.txt |
bug 修复后,提交代码后使用 git status 发现当前工作区是干净的,刚才的工作现场存到哪去了?用 git stash list命令看看
1 | git stash list |
是时候把存储起来的功能 A 代码恢复回来继续工作了,有两种恢复方式。
- 一是用 git stash apply 恢复,但是恢复后,stash 内容并不删除,你需要用 git stash drop 来删除。
- 用 git stash pop,恢复的同时把 stash 内容也删了
1 | git stash pop |
再用 git stash list 查看,就看不到任何 stash 内容了:
你可以多次 stash,恢复的时候,先用 git stash list 查看,然后恢复指定的 stash,用命令:
1 | git stash apply <stash的索引值> |
删除保存的 stash:
1 | git stash drop |
场景 2:当你往远程仓库 push 代码时,本地版本 < 远程版本时,并且你本地还有未 add 的代码时,Git 就会提示你 The current working tree is not clean。
如果使用的是小乌龟的话它会这样提示:
这个时候你也可以先把本地为提交的代码使用 stash 功能给存储起来,把代码 push 到远程后再使用 git stash pop 或 git stash apply 把存储的代码给恢复。
场景 3:平常我们新开发一个功能要建个分支,修改个 bug 也要建个分支,我们经常要对不同分支进行操作,然而原本我是想在 feature 分支开发一个新功能,但是代码却写在了 test 分支上了。
- 在 test 分支上执行 git stash,先把代码存储起来。
1 | git stash |
- 执行 git switch feature 切换到 feature 分支。
1 | git switch feature |
- 执行 git stash pop 把存储的代码释放出来,并清空 stash 存储的代码。
1 | git stash pop |
4.4.2 使用 cherry-pick 解决问题
场景1:假如我们要在 master 分支上修复 bug,bug 修复好后,我们一想 dev 是开发分支,如果 master 分支上存在 bug,那 dev 分支上肯定也有这样的一个 bug,那么我们要怎么做呢,难道要把修复 bug 的代码一行一行复制过去吗?
我们有更简单的方法:
- 我们找到并修复 bug A 提交的 commitid
- 然后切换到 dev 分支
- 使用 git cherry-pick commitid 命令去复制提交为 commitid 的那次代码到 dev 分支
用 git cherry-pick,我们就不需要在 dev 分支上手动再把修改 bug 的过程重复一遍。
场景 2:release 分支是项目的预发布环境,平时我们只能把 main 分支上的代码整个全部给合并到 release 分支上,这时候需求问现在需要给客户演示刚才小明同事新增的地图功能,但是现在 main 分支上的代码还没经过测试,不能完全合并过去,呃……
这个时候也可以使用 git cherry-pick 来实现上诉需求。具体做法可以参考下面步骤:
- 在 main 分支上通过 git log 查看日志,将自己提交的该功能对应的 commitid 值整理出来。
- 如果本地没有 release 分支,需要先将 release 分支从远程仓库拉到本地仓库(如果本地有 release 分支,并且已与远程对应的 release 分支已关联,无需这一步,直接到下一步)
1 | git checkout --track origin/release |
- 切换到 release 分支
1 | git checkout release |
- 在 release 分支上操作:通过 git cherry-pick <commit 对应的 hash 值>将当前 hash 对应提交的代码合并到 release 分支上去。
1 | git cherry-pick <commitid> |
- 最后将本地合并好的 release 分支 push 到远程的 release 分支上去。
1 | git push origin release |
场景 3:在 main 分支上开发了 A、B、C、D 等功能,现在只需把 main 分支上的 A 功能合并到 release 分支,B、C、D 功能不做合并。
比如说我这个时候功能 A 的代码提交次数有多次 commitid3~commitid10 都是功能 A 的开发提交,或则是提交次数有多次但是 commitid 不是连续的,中间也有其它人提交。那么这两种情况下如果和功能 A 相关的开发有 10 次提交,那么我们需要执行 10 次 git cherry-pick commitid 吗?
答案肯定是没有必要的,下面再来介绍一下有关 git cherry-pick 的拓展知识:
拓展:
- 单个 commit 合并
1 | git cherry-pick commitid |
- 多个分开的 commit 一起合并
1 | git cherry-pick commit-id1 commit-id3 commit-id6 |
- 多个连续的 commit 合并, 将 commitid1到 commitid8 之间的所有提交合并到 release 分支上(不包含第一个 commitid)
1 | git cherry-pick commitid1..commitid8 |
每一次合并都可能会产生冲突,如果产生冲突,先解决冲突,然后将代码 commit 到本地仓库即可。
注意:测试无误之后,再将合并后的代码push到远程仓库。切记!
4.4.3 如何丢弃没有被合并过的分支
场景:我们正在开发一个庞大的功能 B,为了不影响主分支上的功能,就新建了一个 feature-vulcan 分支来开发功能 B,功能开发完了,准备合并,接到领导通知说客户改变想法了,不想要此功能了,此功能又涉及到保密工作,所以客户要求要立即销毁。
所以我们执行 git branch -d feature-vulcan
,
1 | $ git branch -d feature-vulcan |
销毁失败。Git友情提醒,feature-vulcan 分支还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用大写的 -D 参数。。
现在我们强行删除:
1 | $ git branch -D feature-vulcan |
4.4.4 本地分支是否到 push 到远程仓库
本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?
- master 分支是主分支,因此要时刻与远程同步
- dev 分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步
- bug 分支只用于在本地修复 bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个 bug
- feature 分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发
总之,就是在 Git 中,分支完全可以在本地自己藏着玩,是否推送,视你的心情而定。
4.4.5 总结
- 修复 bug 时,我们会通过创建新的 bug 分支进行修复,然后合并,最后删除
- 当手头工作没有完成时,先把工作现场 git stash 一下,然后去修复 bug,修复后,再 git stash pop,回到工作现场
- 在 master 分支上修复的 bug,想要合并到当前 dev 分支,可以用 git cherry-pick
命令,把 bug提交的修改“复制”到当前分支,避免重复劳动 - 如果要丢弃一个没有被合并过的分支,可以通过 git branch -D
强行删除
5 git 常用操作
5.1 如何把本地项目推送到远程仓库
场景:想把本地的一个项目文件存到 github 远程仓库。
操作步骤:
1 | 1. 在本地建一个文件夹,例如 git-study-demo 作为本机工作区。 |
说明:
git push -u origin main 命令中的 -u 参数其实就相当于记录了 push 到远端分支的默认值,这样当下次我们还想要继续 push 的这个远端分支的时候推送命令就可以简写成 git push 即可。
5.2 git log 退出方法
使用 git log 命令之后,无法回到主页面,然后只能用暴力的方法解决,直接关闭命令窗口。
5.3 删除分支
删除已经合并过的分支:
1 | git branch -b feature-1 |
强行删除没有合并过的分支:
1 | git branch -D feature-1 |
5.4 在本地创建和远程分支对应的分支
1 | git checkout -b branch-name origin/branch-name |
5.5 建立本地分支和远程分支的关联
1 | git branch --set-upstream-to=origin/<branch> dev |
5.6 撤销合并操作
场景1:需求说要把综合查询合并到 release 分支,目的是发布到预发布环境,代码合并后发现有 bug,说是要撤销这次的代码合并。
release 分支是远程分支,肯定不能直接对远程分支进行撤销操作,可以在本地进行撤销后再 push 到远程上去:
1 | git reset HEAD^ |
6 个人使用习惯
6.1 查看提交日志
查看提交日志喜欢使用界面化工具——例如小乌龟
因为界面化工具不仅可以很方便的看出提交记录,还可以看出每次提交记录都修改了哪些文件,以及文件的修改内容。
6.2 撤销工作区的修改
撤销工作区修改喜欢用界面化工具——例如小乌龟
6.3 提交代码
提交代码喜欢用界面化工具——例如小乌龟
为了防止提交错误的代码或无用的代码,所以每次提交代码时都习惯看一下修改的内容都有哪些,如果发现有一些测试代码如 console.log 或 debugger 之类的。就删除掉后再提交。
7 记录工作中遇到的问题
7.1 git 源换了之后应该怎么处理
场景说明:
公司代码库迁移到另外的服务器,个人需要重新更新本地代码库,重新拉代码显然效率低,这时候只需要更换git源就可以轻松搞定
前提:本地代码已经更新到最新的 commit,更换源之后拉代码才不会出现冲突。
方法一:
- 进入本地仓库路径,进入 .git 目录
- 修改 config 文件,将 url 换成现在的 git 仓库地址
方法二:
第一步查看源地址:
1 | git remote -v |
第二步删除源地址:
1 | git remote rm origin |
第三步添加源地址:
1 | git remote add origin git@git..gitxxx.com:fei/stic.git |
这就行了,然后git pull 拉取代码看有没有问题。
最后可以关联起来本地的分支(可忽略):
1 | git branch --set-upstream master origin/master |
7.2 git 绿色、红色图标不显示问题的解决方案
问题:在使用git的过程当中发现,项目文件上没有绿色图标,即便修改文件也没有红色图标显示git
绿色图标是指提交成功的,红色图标是指修改后还未提交的。没有图标显示,可是能够正常上传下载,在文件比较多的时候,不知道本身修改了哪些,容易出现错误。
解决步骤:
- win+r,regedit.exe,打开注册表 按照文件的层次关系依次找到blog
HKEY_LOCAL_MACHINE\Software\Microsoft\windows\CurrentVersion\Explorer;排序
修改键名 Max Cached Icons (最大缓存图标) 的值为 2000 (没有这个键,能够新建)资源
重启电脑
- 打开后找到“HKEY_LOCAL_MACHINE–>SOFTWARE–>Microsoft–>Windows–>CurrentVersion–>Explorer–>ShellIconOverlayIdentifiers”这一项。将 Tortoise 相关的项都提到靠前的位置(重命名,在名称以前加几个空格)
- 重启电脑或重启资源管理器后,绿色和红色图标就显示出来了。