-
Notifications
You must be signed in to change notification settings - Fork 0
/
tools-vcs-git.html
212 lines (210 loc) · 194 KB
/
tools-vcs-git.html
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
<!DOCTYPE html>
<html lang="zh-CN" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Git | 广度和深度</title>
<meta name="description" content="整理和记录代码学习的笔记">
<link rel="preload stylesheet" href="/assets/style.66b7dec6.css" as="style">
<script type="module" src="/assets/app.f6aa04bd.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.2ed14f66.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/framework.027d2da0.js">
<link rel="modulepreload" href="/assets/chunks/theme.98d176af.js">
<link rel="modulepreload" href="/assets/tools-vcs-git.md.f375211f.lean.js">
<link rel="icon" href="./favicon.ico">
<script id="check-dark-light">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"dark",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-8692e0c2><!--[--><!--]--><!--[--><span tabindex="-1" data-v-7da17955></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-7da17955> Skip to content </a><!--]--><!----><header class="VPNav" data-v-8692e0c2 data-v-bcf310a9><div class="VPNavBar has-sidebar" data-v-bcf310a9 data-v-7192d962><div class="container" data-v-7192d962><div class="title" data-v-7192d962><div class="VPNavBarTitle has-sidebar" data-v-7192d962 data-v-56d4391f><a class="title" href="/" data-v-56d4391f><!--[--><!--]--><!--[--><img class="VPImage logo" src="./logo.jpg" alt data-v-506001e8><!--]--><!--[-->Coder<!--]--><!--[--><!--]--></a></div></div><div class="content" data-v-7192d962><div class="curtain" data-v-7192d962></div><div class="content-body" data-v-7192d962><!--[--><!--]--><div class="VPNavBarSearch search" data-v-7192d962><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg class="DocSearch-Search-Icon" width="20" height="20" viewBox="0 0 20 20" aria-label="search icon"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-7192d962 data-v-359face2><span id="main-nav-aria-label" class="visually-hidden" data-v-359face2>Main Navigation</span><!--[--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-359face2 data-v-bb4a2dc7><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-bb4a2dc7><span class="text" data-v-bb4a2dc7><!----><span data-v-bb4a2dc7>♎语言</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-bb4a2dc7><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-bb4a2dc7><div class="VPMenu" data-v-bb4a2dc7 data-v-5d7a6046><div class="items" data-v-5d7a6046><!--[--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/lang-java.html" data-v-b6a76a69><!--[-->1️⃣ Java<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/lang-python.html" data-v-b6a76a69><!--[-->2️⃣ Python<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/lang-scala.html" data-v-b6a76a69><!--[-->3️⃣ Scala<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/lang-groovy.html" data-v-b6a76a69><!--[-->4️⃣ Groovy<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-359face2 data-v-bb4a2dc7><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-bb4a2dc7><span class="text" data-v-bb4a2dc7><!----><span data-v-bb4a2dc7>☯️算法</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-bb4a2dc7><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-bb4a2dc7><div class="VPMenu" data-v-bb4a2dc7 data-v-5d7a6046><div class="items" data-v-5d7a6046><!--[--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>算法篇</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫代码规范<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫设计模式<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫数据结构<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫源码解读<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>并发篇</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫JVM<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫并发编程<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>设计篇</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫系统设计<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫数仓理论<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>职业篇</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫方向导航<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫职业规划<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫面试准备<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-359face2 data-v-bb4a2dc7><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-bb4a2dc7><span class="text" data-v-bb4a2dc7><!----><span data-v-bb4a2dc7>♈前端</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-bb4a2dc7><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-bb4a2dc7><div class="VPMenu" data-v-bb4a2dc7 data-v-5d7a6046><div class="items" data-v-5d7a6046><!--[--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫HTML<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫CSS<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫JavaScript<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫JQuery<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫NodeJS<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Vue<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫React<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫小程序<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-359face2 data-v-bb4a2dc7><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-bb4a2dc7><span class="text" data-v-bb4a2dc7><!----><span data-v-bb4a2dc7>🔯微服务</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-bb4a2dc7><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-bb4a2dc7><div class="VPMenu" data-v-bb4a2dc7 data-v-5d7a6046><div class="items" data-v-5d7a6046><!--[--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫RPC<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Spring<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Spring MVC<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Spring Boot<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Spring Cloud<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Spring Cloud Alibaba<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Service Mesh<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-359face2 data-v-bb4a2dc7><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-bb4a2dc7><span class="text" data-v-bb4a2dc7><!----><span data-v-bb4a2dc7>⚧️数据存储</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-bb4a2dc7><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-bb4a2dc7><div class="VPMenu" data-v-bb4a2dc7 data-v-5d7a6046><div class="items" data-v-5d7a6046><!--[--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>SQL数据库</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫MySQL<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Oracle<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>NoSQL数据库</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Redis<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫MongoDB<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>NewSQL数据库</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫TiDB<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>ORM框架</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Mybatis<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Mybatis Plus<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Spring Data JPA<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>消息中间件</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Active MQ<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫RabbitMQ<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫RocketMQ<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Kafka<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>文件存储</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫FastDFS<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Ceph<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫HDFS<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>搜索引擎</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Lucene<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Solr<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫ElasticSearch<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-359face2 data-v-bb4a2dc7><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-bb4a2dc7><span class="text" data-v-bb4a2dc7><!----><span data-v-bb4a2dc7>☸️DevOps</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-bb4a2dc7><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-bb4a2dc7><div class="VPMenu" data-v-bb4a2dc7 data-v-5d7a6046><div class="items" data-v-5d7a6046><!--[--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>部署</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/devops-deploy-tomcat.html" data-v-b6a76a69><!--[-->Tomcat<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/devops-deploy-tomcat.html" data-v-b6a76a69><!--[-->🚫Linux<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/devops-deploy-shell.html" data-v-b6a76a69><!--[-->Shell<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/devops-deploy-tomcat.html" data-v-b6a76a69><!--[-->🚫Nginx<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/devops-deploy-tomcat.html" data-v-b6a76a69><!--[-->🚫Linux<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/devops-deploy-tomcat.html" data-v-b6a76a69><!--[-->🚫LVS+Keepalived<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/devops-deploy-tomcat.html" data-v-b6a76a69><!--[-->🚫OpenResty+Kong<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>容器</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Docker<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Kubernates<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>云服务器</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫IaaS<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫UCloud<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>持续集成</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Jenkins<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>监控工具</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Arthas<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Zabbix<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>链路追踪</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Sleuth+Zipkin<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫Skywalking<!--]--></a></div><!--]--><!--]--></div><!--]--><!--[--><div class="VPMenuGroup" data-v-5d7a6046 data-v-2d40012a><p class="title" data-v-2d40012a>性能压测</p><!--[--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫JMeter<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-2d40012a data-v-b6a76a69><a class="VPLink link" href="/#" data-v-b6a76a69><!--[-->🚫全链路压测<!--]--></a></div><!--]--><!--]--></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-359face2 data-v-bb4a2dc7><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-bb4a2dc7><span class="text" data-v-bb4a2dc7><!----><span data-v-bb4a2dc7>✝️工具</span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="text-icon" data-v-bb4a2dc7><path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z"></path></svg></span></button><div class="menu" data-v-bb4a2dc7><div class="VPMenu" data-v-bb4a2dc7 data-v-5d7a6046><div class="items" data-v-5d7a6046><!--[--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-soft.html" data-v-b6a76a69><!--[-->软性办公工具<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-vcs.html" data-v-b6a76a69><!--[-->版本控制工具<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-dev.html" data-v-b6a76a69><!--[-->包管理工具<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-dev.html" data-v-b6a76a69><!--[-->项目构建工具<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-dev.html" data-v-b6a76a69><!--[-->编程工具<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-dev.html" data-v-b6a76a69><!--[-->数据库管理<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-dev.html" data-v-b6a76a69><!--[-->虚拟机工具<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-dev.html" data-v-b6a76a69><!--[-->SSH工具<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-dev.html" data-v-b6a76a69><!--[-->调试工具<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-5d7a6046 data-v-b6a76a69><a class="VPLink link" href="/tools-dev.html" data-v-b6a76a69><!--[-->压测工具<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-7192d962 data-v-5c7f08f3><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-5c7f08f3 data-v-f44e5024 data-v-23c4cb6c><span class="check" data-v-23c4cb6c><span class="icon" data-v-23c4cb6c><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-f44e5024><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-f44e5024><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div><!----><div class="VPFlyout VPNavBarExtra extra" data-v-7192d962 data-v-4a4a2081 data-v-bb4a2dc7><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-bb4a2dc7><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="icon" data-v-bb4a2dc7><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle><circle cx="5" cy="12" r="2"></circle></svg></button><div class="menu" data-v-bb4a2dc7><div class="VPMenu" data-v-bb4a2dc7 data-v-5d7a6046><!----><!--[--><!--[--><!----><div class="group" data-v-4a4a2081><div class="item appearance" data-v-4a4a2081><p class="label" data-v-4a4a2081>深浅模式</p><div class="appearance-action" data-v-4a4a2081><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title="toggle dark mode" aria-checked="false" data-v-4a4a2081 data-v-f44e5024 data-v-23c4cb6c><span class="check" data-v-23c4cb6c><span class="icon" data-v-23c4cb6c><!--[--><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="sun" data-v-f44e5024><path d="M12,18c-3.3,0-6-2.7-6-6s2.7-6,6-6s6,2.7,6,6S15.3,18,12,18zM12,8c-2.2,0-4,1.8-4,4c0,2.2,1.8,4,4,4c2.2,0,4-1.8,4-4C16,9.8,14.2,8,12,8z"></path><path d="M12,4c-0.6,0-1-0.4-1-1V1c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,3.6,12.6,4,12,4z"></path><path d="M12,24c-0.6,0-1-0.4-1-1v-2c0-0.6,0.4-1,1-1s1,0.4,1,1v2C13,23.6,12.6,24,12,24z"></path><path d="M5.6,6.6c-0.3,0-0.5-0.1-0.7-0.3L3.5,4.9c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C6.2,6.5,5.9,6.6,5.6,6.6z"></path><path d="M19.8,20.8c-0.3,0-0.5-0.1-0.7-0.3l-1.4-1.4c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l1.4,1.4c0.4,0.4,0.4,1,0,1.4C20.3,20.7,20,20.8,19.8,20.8z"></path><path d="M3,13H1c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S3.6,13,3,13z"></path><path d="M23,13h-2c-0.6,0-1-0.4-1-1s0.4-1,1-1h2c0.6,0,1,0.4,1,1S23.6,13,23,13z"></path><path d="M4.2,20.8c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C4.7,20.7,4.5,20.8,4.2,20.8z"></path><path d="M18.4,6.6c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l1.4-1.4c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-1.4,1.4C18.9,6.5,18.6,6.6,18.4,6.6z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="moon" data-v-f44e5024><path d="M12.1,22c-0.3,0-0.6,0-0.9,0c-5.5-0.5-9.5-5.4-9-10.9c0.4-4.8,4.2-8.6,9-9c0.4,0,0.8,0.2,1,0.5c0.2,0.3,0.2,0.8-0.1,1.1c-2,2.7-1.4,6.4,1.3,8.4c2.1,1.6,5,1.6,7.1,0c0.3-0.2,0.7-0.3,1.1-0.1c0.3,0.2,0.5,0.6,0.5,1c-0.2,2.7-1.5,5.1-3.6,6.8C16.6,21.2,14.4,22,12.1,22zM9.3,4.4c-2.9,1-5,3.6-5.2,6.8c-0.4,4.4,2.8,8.3,7.2,8.7c2.1,0.2,4.2-0.4,5.8-1.8c1.1-0.9,1.9-2.1,2.4-3.4c-2.5,0.9-5.3,0.5-7.5-1.1C9.2,11.4,8.1,7.7,9.3,4.4z"></path></svg><!--]--></span></span></button></div></div></div><!----><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-7192d962 data-v-9cc97dbb><span class="container" data-v-9cc97dbb><span class="top" data-v-9cc97dbb></span><span class="middle" data-v-9cc97dbb></span><span class="bottom" data-v-9cc97dbb></span></span></button></div></div></div></div><!----></header><div class="VPLocalNav reached-top" data-v-8692e0c2 data-v-a8f7ff89><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-a8f7ff89><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="menu-icon" data-v-a8f7ff89><path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z"></path><path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z"></path><path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z"></path><path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z"></path></svg><span class="menu-text" data-v-a8f7ff89>菜单</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-a8f7ff89 data-v-a050d324><button data-v-a050d324>返回顶部</button><!----></div></div><aside class="VPSidebar" data-v-8692e0c2 data-v-cde32d1c><div class="curtain" data-v-cde32d1c></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-cde32d1c><span class="visually-hidden" id="sidebar-aria-label" data-v-cde32d1c> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>软性办公</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-baidupan.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>百度网盘</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-foxit.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>福昕阅读器</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-calibre.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Calibre</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-chrome.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Chrome</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-cmder.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Cmder</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-evernote.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Evernote</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-nodepad.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Nodepad</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-office.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Office</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-potplayer.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>PotPlayer</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-snipaste.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Snipaste</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-sublimetext.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>SublimeText</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-typora.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Typora</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-tizi.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>科学上网</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-xmind.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Xmind</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-7zip.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>7zip</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-windows.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Windows</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-soft-markdown.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Markdown</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>版本管理</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><section class="VPSidebarItem level-1 collapsible collapsed" data-v-1f85ec84 data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h3 class="text" data-v-1f85ec84>Git</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-2 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-vcs-git.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Git</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-vcs-gogs.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Gogs</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-vcs-gitee.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Gitee</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-vcs-github.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Github</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-vcs-gitlib.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>GitLib</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-vcs-gitflow.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>GitFlow</p><!--]--></a><!----></div><!----></div><!--]--></div></section><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-vcs-svn.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Svn</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>包管理工具</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-nvm.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>NVM</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>项目构建</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-maven.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Maven</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-gradle.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Gradle</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>编程工具</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-idea.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>IDEA</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-vscode.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>VsCode</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-pycharm.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>PyCharm</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>数据库管理</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-navicat.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Navicat</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>虚拟机工具</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-vmware.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>VMware</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>SSH工具</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-ssh.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>SSH工具</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>调试工具</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-postman.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>Postman</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="group" data-v-cde32d1c><section class="VPSidebarItem level-0 collapsible collapsed" data-v-cde32d1c data-v-1f85ec84><div class="item" role="button" tabindex="0" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><h2 class="text" data-v-1f85ec84>压测工具</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-1f85ec84><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewbox="0 0 24 24" class="caret-icon" data-v-1f85ec84><path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z"></path></svg></div></div><div class="items" data-v-1f85ec84><!--[--><div class="VPSidebarItem level-1 is-link" data-v-1f85ec84 data-v-1f85ec84><div class="item" data-v-1f85ec84><div class="indicator" data-v-1f85ec84></div><a class="VPLink link link" href="/tools-dev-jmeter.html" data-v-1f85ec84><!--[--><p class="text" data-v-1f85ec84>JMeter</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-8692e0c2 data-v-87044f80><div class="VPDoc has-sidebar has-aside" data-v-87044f80 data-v-e970bbc0><!--[--><!--]--><div class="container" data-v-e970bbc0><div class="aside" data-v-e970bbc0><div class="aside-curtain" data-v-e970bbc0></div><div class="aside-container" data-v-e970bbc0><div class="aside-content" data-v-e970bbc0><div class="VPDocAside" data-v-e970bbc0 data-v-0473afe5><!--[--><!--]--><!--[--><!--]--><div class="VPDocAsideOutline" role="navigation" data-v-0473afe5 data-v-b2f90363><div class="content" data-v-b2f90363><div class="outline-marker" data-v-b2f90363></div><div class="outline-title" role="heading" aria-level="2" data-v-b2f90363>目录</div><nav aria-labelledby="doc-outline-aria-label" data-v-b2f90363><span class="visually-hidden" id="doc-outline-aria-label" data-v-b2f90363> Table of Contents for current page </span><ul class="root" data-v-b2f90363 data-v-3d0f3048><!--[--><!--]--></ul></nav></div></div><!--[--><!--]--><div class="spacer" data-v-0473afe5></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-e970bbc0><div class="content-container" data-v-e970bbc0><!--[--><!--]--><!----><main class="main" data-v-e970bbc0><div style="position:relative;" class="vp-doc _tools-vcs-git" data-v-e970bbc0><div><h1 id="git" tabindex="-1">Git <a class="header-anchor" href="#git" aria-label="Permalink to "Git""></a></h1><div class="info custom-block"><p class="custom-block-title">INFO</p><p>Github的master分支调整为main了</p></div><h2 id="版本控制" tabindex="-1">版本控制 <a class="header-anchor" href="#版本控制" aria-label="Permalink to "版本控制""></a></h2><h3 id="什么是版本控制" tabindex="-1">什么是版本控制 <a class="header-anchor" href="#什么是版本控制" aria-label="Permalink to "什么是版本控制""></a></h3><blockquote><p>版本控制是一种在开发过程中用于管理我们对文件、目录等工程内容修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术</p></blockquote><p> 你可以把一个版本控制系统(缩写VCS)理解为一个“数据库”,在需要的时候,它可以帮你完整地保存一个项目的快照。当你需要查看一个之前的快照(称之为“版本”)时,版本控制系统可以显示出当前版本与上一个版本之间的所有改动的细节。</p><p><img src="/images/image-20230915150637390.png" alt="image-20230915150637390"></p><p>版本控制系统会记录所有对项目文件的更改。这就是版本控制,听起来很简单。</p><p>最简单的版本控制就是保存项目内容的一个备份,编号为"A",然后基于原始项目进行修改,修改后保存为版本"B",保留软件不同状态的数份copy,并且适当编号。许多大型开发案都是使用这种简单技巧。虽然这种方法能用,但是很没效率。一是因为保存的数份copy几乎完全一样,也因为这种方法要高度依靠开发者的自我纪律,从而导致错误。</p><h3 id="为什么使用版本控制" tabindex="-1">为什么使用版本控制 <a class="header-anchor" href="#为什么使用版本控制" aria-label="Permalink to "为什么使用版本控制""></a></h3><h4 id="版本存储" tabindex="-1">版本存储 <a class="header-anchor" href="#版本存储" aria-label="Permalink to "版本存储""></a></h4><p> 常见的版本存储方式就是在本地多次备份不同版本的文件,即使按照通用的命名格式保存后,还需要花费大量的时间来分析整理这些备份文件,而且这种操作很容易出错,而且经常性的不知道为什么保存,保存了什么变动的内容,因为我们很少花更多的时间去记录和观察每一个重要的变化</p><p> 版本控制系统就完美的解决了我们的问题,每当你提交一次对项目新的改动时,他会基于最原始的文件,保存每一个细节的变化到一个版本中,可以帮助我们很好地了解相邻版本间的变动关系。</p><p> 而且版本控制系统有撤销的功能,我们可以基于某个版本号,撤销所有/部分的变动信息,回到当时的文件状态。在项目的每一个重要阶段,认识和正确地使用撤销功能会让我们的工作变得非常轻松。</p><h4 id="协同合作" tabindex="-1">协同合作 <a class="header-anchor" href="#协同合作" aria-label="Permalink to "协同合作""></a></h4><p> 基于传统方式修改项目代码的时候,必须告知团队中的其他人,我在干什么,防止他们和我冲突,而这不可能的,所以当我好不容易编辑完文件后,发现该文件被人删了,感觉很不舒服。</p><p> 有了版本控制系统,团队每一个成员都可以自由的修改代码文件,进行团队的协同工作,版本控制系统可以帮我们将所有改动内容合并保存为一个版本,即使某些功能代码意外丢失,也可以通过版本系统找回。</p><h3 id="版本控制系统分类" tabindex="-1">版本控制系统分类 <a class="header-anchor" href="#版本控制系统分类" aria-label="Permalink to "版本控制系统分类""></a></h3><p> 随着互联网的发展,软件产品的更新迭代越来越快,软件产品代码的版本控制系统也发生了千变万化,既有开源的,也有商用的,而且都是针对各种不同的应用环境设计的。目前市场上出现比例较高的版本控制系统主要有三类:本地版本控制系统,集中式版本控制系统和分布式版本控制系统。</p><h4 id="本地版本控制系统-rcs" tabindex="-1">本地版本控制系统(RCS) <a class="header-anchor" href="#本地版本控制系统-rcs" aria-label="Permalink to "本地版本控制系统(RCS)""></a></h4><p> 许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别,这么做唯一的好处就是简单,但是特别容易犯错, 有时候会混淆所在的工作目录,一不小心会写错文件或者覆盖意想外的文件。</p><p> 为了解决这个问题,人们很久以前就开发了许多种本地版本控制系统,大多都是采用某种简单的数据库来记录文件的历次更新差异。</p><p><img src="/images/image-20230915150923534.png" alt="image-20230915150923534"></p><p> 其中最流行的一种叫做 RCS,现今许多计算机系统上都还看得到它的踪影。 RCS的工作原理是在硬盘上保存补丁集(补丁是指文件修订前后的变化);通过应用所有的补丁,可以重新计算出各个版本的文件内容。</p><h4 id="集中化的版本控制系统" tabindex="-1">集中化的版本控制系统 <a class="header-anchor" href="#集中化的版本控制系统" aria-label="Permalink to "集中化的版本控制系统""></a></h4><blockquote><p>接下来人们又遇到一个问题,如何让在不同系统上的开发者协同工作?</p></blockquote><p> 于是,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。 这类系统,诸如 CVS、Subversion 以及 Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。 多年以来,这已成为版本控制系统的标准做法。</p><p><img src="/images/image-20230915150943758.png" alt="image-20230915150943758"></p><p> 这种做法带来了许多好处,特别是相较于老式的本地 VCS 来说。 现在,每个人都可以在一定程度上看到项目中的其他人正在做些什么。 而管理员也可以轻松掌控每个开发者的权限,并且管理一个 CVCS 要远比在各个客户端上维护本地数据库来得轻松容易。</p><p> 事分两面,有好有坏。 这么做最显而易见的缺点是中央服务器的单点故障。 如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。</p><p> 如果中心数据库所在的磁盘发生损坏,又没有做恰当备份,毫无疑问你将丢失所有数据——包括项目的整个变更历史,只剩下人们在各自机器上保留的单独快照。 本地版本控制系统也存在类似问题,只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。</p><h4 id="分布式版本控制系统" tabindex="-1">分布式版本控制系统 <a class="header-anchor" href="#分布式版本控制系统" aria-label="Permalink to "分布式版本控制系统""></a></h4><blockquote><p>于是分布式版本控制系统(Distributed Version Control System,简称 DVCS)面世了。</p></blockquote><p> 在这类系统中,像 Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照, 而是把代码仓库完整地镜像下来,包括完整的历史记录。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。</p><p><img src="/images/image-20230915151023886.png" alt="image-20230915151023886"></p><p> 更进一步,许多这类系统都可以指定和若干不同的远端代码仓库进行交互。籍此,你就可以在同一个项目中,分别和不同工作小组的人相互协作。 你可以根据需要设定不同的协作流程,比如层次模型式的工作流,而这在以前的集中式系统中是无法实现的。</p><h4 id="集中式vs分布式" tabindex="-1">集中式VS分布式 <a class="header-anchor" href="#集中式vs分布式" aria-label="Permalink to "集中式VS分布式""></a></h4><p> 先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器,中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。</p><p><img src="/images/image-20230915151323770.png" alt="image-20230915151323770"></p><p> 集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,这还不得把人给憋死啊。</p><p> 那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上,既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。</p><p> 和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了,而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。</p><p> 在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。</p><p><img src="/images/image-20230915151412795.png" alt="image-20230915151412795"></p><h2 id="git简介" tabindex="-1">Git简介 <a class="header-anchor" href="#git简介" aria-label="Permalink to "Git简介""></a></h2><p><img src="/images/image-20230915120904428.png" alt="image-20230915120904428"></p><h3 id="git是什么" tabindex="-1">Git是什么? <a class="header-anchor" href="#git是什么" aria-label="Permalink to "Git是什么?""></a></h3><p> Git是目前世界上最先进的分布式文件版本控制系统(没有之一)。对于我们java程序员而言,管理的就是代码文件版本。</p><p> git是一个和svn一样的版本控制软件,但是与svn不同的是,git是一个分布式的高效版本控制系统。</p><p> 其实现原理跟svn也大相径庭,采取了一种以空间换时间的理论,为什么是使用分布式呢,因为git会在每个开发者的本地中都保留了一份仓库副本,即使在断网的时候,也能提交代码到各自的仓库中,等联网后,再提交到中央仓库,每个开发者的仓库都是互相不可见的。</p><h3 id="git历史" tabindex="-1">Git历史 <a class="header-anchor" href="#git历史" aria-label="Permalink to "Git历史""></a></h3><blockquote><p>Git 诞生于 Linux 内核社区对可用的 VCSs(版本控制系统)的挫败感</p></blockquote><p> Linux 内核的发展在当时是相当不寻常的:项目中有大量的贡献者而且贡献者的参与程度和对代码知识库的了解有很大的差异。由于 Linux 内核不寻常的发展状况,开发人员很难找到适合他们需求的 VCSs(版本控制系统)。于是他们选择了 BitKeeper 和并发修订系统(CVS),每个系统有一组核心开发人员去负责管理内核的开发。BitKeeper 提供分布式版本控制,而 CVS 是一个客户端-服务端版本控制系统,它可以让开发人员“签出”项目的副本,进行更改,然后将他们的改变“签入”到服务端。</p><p> 在 2005 年初期,BitKeeper 的版权持有人 Larry McVoy 宣布撤销允许免费使用 BitKeeper 软件的许可。他声称,正在创建与 BitKeeper 反向交互软件的澳大利亚程序设计师 Andrew Tridgell 反向设计了 BitKeeper 的源代码,这样违背了它的许可。许多依赖 BitKeeper 免费软件去开发 Linux 内核的 Linux 核心开发者现在已经无法继续使用它了。</p><p> Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。</p><p> Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。</p><h3 id="集中式-svn" tabindex="-1">集中式(SVN) <a class="header-anchor" href="#集中式-svn" aria-label="Permalink to "集中式(SVN)""></a></h3><p> SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就郁闷了。如果中心服务器出现问题,所有人都不能正常干活,恢复也很麻烦,因为SVN记录的是每次改动的差异,不是完整文件</p><p>下图就是标准的集中式版本控制工具管理方式:</p><p><img src="/images/image-20230915091928140.png" alt="image-20230915091928140"></p><p>集中管理方式在一定程度上看到其他开发人员在干什么,而管理员也可以很轻松掌握每个人的开发权限。</p><p>但是相较于其优点而言,集中式版本控制工具缺点很明显:</p><ul><li><p>服务器单点故障</p></li><li><p>容错性差</p></li></ul><h3 id="分布式版本控制-git" tabindex="-1"><strong>分布式版本控制</strong>(GIT) <a class="header-anchor" href="#分布式版本控制-git" aria-label="Permalink to "**分布式版本控制**(GIT)""></a></h3><p> Git是分布式版本控制系统,那么它可以没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。</p><p>下图就是分布式版本控制工具管理方式:</p><p><img src="/images/image-20230915092117316.png" alt="image-20230915092117316"></p><p>Git有什么特点?</p><h3 id="git和svn区别" tabindex="-1">Git和SVN区别 <a class="header-anchor" href="#git和svn区别" aria-label="Permalink to "Git和SVN区别""></a></h3><h4 id="直接记录快照-而非差异比较" tabindex="-1">直接记录快照,而非差异比较 <a class="header-anchor" href="#直接记录快照-而非差异比较" aria-label="Permalink to "直接记录快照,而非差异比较""></a></h4><blockquote><p>Git 和其它版本控制系统(包括 Subversion 和近似工具)的主要差别在于 Git 对待数据的方式。</p></blockquote><p> 从概念上来说,其它大部分系统以文件变更列表的方式存储信息,这类系统(CVS、Subversion、Perforce、Bazaar 等等) 将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异 (它们通常称作 <strong>基于差异(delta-based)</strong> 的版本控制)。</p><p>存储每个文件与初始版本的差异: <a href="https://git-scm.com/book/en/v2/images/deltas.png" target="_blank" rel="noreferrer">https://git-scm.com/book/en/v2/images/deltas.png</a></p><p><img src="/images/image-20230915151650388.png" alt="image-20230915151650388"></p><p> Git 不按照以上方式对待或保存数据,反之,Git 更像是把数据看作是对小型文件系统的一系列快照。 在 Git 中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。 为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件, Git 对待数据更像是一个 <strong>快照流</strong>。</p><p><img src="/images/image-20230915151713755.png" alt="image-20230915151713755"></p><p> 这是 Git 与几乎所有其它版本控制系统的重要区别, 因此 Git 重新考虑了以前每一代版本控制系统延续下来的诸多方面, Git 更像是一个小型的文件系统,提供了许多以此为基础构建的超强工具,而不只是一个简单的 VCS。</p><h4 id="近乎所有操作都是本地执行" tabindex="-1">近乎所有操作都是本地执行 <a class="header-anchor" href="#近乎所有操作都是本地执行" aria-label="Permalink to "近乎所有操作都是本地执行""></a></h4><blockquote><p>在 Git 中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。</p></blockquote><p> 如果你习惯于所有操作都有网络延时开销的集中式版本控制系统,Git 在这方面会让你感到速度之神赐给了 Git 超凡的能量, 因为你在本地磁盘上就有项目的完整历史,所以大部分操作看起来瞬间完成。</p><h4 id="小结" tabindex="-1">小结 <a class="header-anchor" href="#小结" aria-label="Permalink to "小结""></a></h4><ol><li>svn是集中式的,而git是分布式的,如果svn的中央仓库代码被删除了,那么可能代码真的就找不回来了,而git因为是分布式的,本地都有着所有代码的副本,所以即便中央仓库代码丢失,也可能通过本地代码重新恢复回来。</li><li>svn每次提交记录,都是将提交的数据之间的差异数据进行保存,而git则是对有修改的文件使用另一个新的文件来保存,即使用了更多的资源,但是现在的社会,最不缺的就是空间资源了。</li><li>svn服务器中使用了全局版本号,每次提交都会产生一个唯一的全局id,且是由顺序的。而git则是根据sha1来进行盐值加密算法获取,没有什么先后区分</li><li>分支管理的不同,svn的开辟新分支,则是将原有的分支的文件全部拷贝一份到新分支中,如果项目比较大,该过程可能会消耗点时间。而git则是通过指针的方式,非常的快速</li><li>操作的不同。svn中一般提交代码和拉取代码两步骤,而git则有一个暂存区的概念,先add,然后commit。</li><li>学习曲线的不同。svn相对简单,git学习曲线相对陡峭</li></ol><h3 id="为什么要用git" tabindex="-1">为什么要用Git <a class="header-anchor" href="#为什么要用git" aria-label="Permalink to "为什么要用Git""></a></h3><ol><li>首先git是一个比svn更加优秀的代码管理工具,已经可以说取代了svn,其区别如上</li><li>目前的很多程序中,都需要有git的支持,可能在使用一款工具时,会先检测是否安装了git,否则必须要求先安装git,可见其活跃度</li><li>由于github和码云的兴起,拉去代码都是通过git来操作完成</li></ol><h3 id="git和github" tabindex="-1"><strong>Git和GitHub</strong> <a class="header-anchor" href="#git和github" aria-label="Permalink to "**Git和GitHub**""></a></h3><p>什么是GitHub?</p><p>确切的说 GitHub 是一家公司,位于旧金山,由 Chris Wanstrath, PJ Hyett 与 Tom Preston-Werner 三位开发者在2008年4月创办。这是它的 Logo:</p><p><img src="/images/image-20230915085341568.png" alt="image-20230915085341568"></p><p>2008年4月10日,GitHub正式成立,主要提供基于git的版本托管服务。一经上线,它的发展速度惊为天人,截止目前,GitHub 已经发展成全球最大的开源社区。 所以 Git 只是 GitHub 上用来管理项目的一个工具而已,但是GitHub 的功能可远不止于此!</p><h3 id="git-github与gitlab的区别" tabindex="-1">Git,GitHub与GitLab的区别 <a class="header-anchor" href="#git-github与gitlab的区别" aria-label="Permalink to "Git,GitHub与GitLab的区别""></a></h3><ul><li>Git是一种版本控制系统,是一种工具,用于代码的存储和版本控制。</li><li>GitHub是一个基于Git实现的在线代码仓库,是目前全球最大的代码托管平台,可以帮助程序员之间互相交流和学习。</li><li>GitLab是一个基于Git实现的在线代码仓库软件,你可以用GitLab自己搭建一个类似于GitHub一样的仓库,但是GitLab有完善的管理界面和权限控制,一般用于在企业、学校等内部网络搭建Git私服。</li><li>GitHub和GiLlab两个都是基于Web的Git远程仓库,它们都提供了分享开源项目的平台,为开发团队提供了存储、分享、发布和合作开发项目的中心化云存储的场所。从代码的私有性上来看,GitLab 是一个更好的选择。但是对于开源项目而言,GitHub 依然是代码托管的首选。</li></ul><h2 id="git安装" tabindex="-1">Git安装 <a class="header-anchor" href="#git安装" aria-label="Permalink to "Git安装""></a></h2><h3 id="下载" tabindex="-1"><strong>下载</strong> <a class="header-anchor" href="#下载" aria-label="Permalink to "**下载**""></a></h3><p>下载地址:<a href="https://git-scm.com/download" target="_blank" rel="noreferrer">https://git-scm.com/download</a></p><p><img src="/images/image-20230915152057091.png" alt="image-20230915152057091"></p><h3 id="安装git-for-windows" tabindex="-1">安装git for windows <a class="header-anchor" href="#安装git-for-windows" aria-label="Permalink to "安装git for windows""></a></h3><p>双击安装:</p><p><img src="/images/image-20230915092356128.png" alt="image-20230915092356128"></p><p><img src="/images/image-20230915092206201.png" alt="image-20230915092206201"></p><p><img src="/images/image-20230915092211986.png" alt="image-20230915092211986"></p><p><img src="/images/image-20230915092217414.png" alt="image-20230915092217414"></p><p><img src="/images/image-20230915092222374.png" alt="image-20230915092222374"></p><p><img src="/images/image-20230915092231023.png" alt="image-20230915092231023"></p><p><img src="/images/image-20230915092237146.png" alt="image-20230915092237146"></p><p><img src="/images/image-20230915092250870.png" alt="image-20230915092250870"></p><p><img src="/images/image-20230915092257038.png" alt="image-20230915092257038"></p><p><img src="/images/image-20230915092301999.png" alt="image-20230915092301999"></p><p><img src="/images/image-20230915092306883.png" alt="image-20230915092306883"></p><p><img src="/images/image-20230915092311527.png" alt="image-20230915092311527"></p><p><img src="/images/image-20230915092316379.png" alt="image-20230915092316379"></p><p>基本上一路“Next”使用默认选项即可。</p><p>安装完成后,可以在任意文件夹点右键,看到如下菜单:</p><p><img src="/images/image-20230915092341059.png" alt="image-20230915092341059"></p><blockquote><p>安装好Git之后在控制台输入Git 出现以下就是安装成功了</p></blockquote><p><img src="/images/image-20230915092345517.png" alt="image-20230915092345517"></p><h3 id="安装git-for-linux" tabindex="-1">安装git for linux <a class="header-anchor" href="#安装git-for-linux" aria-label="Permalink to "安装git for linux""></a></h3><h4 id="查看是否安装了git" tabindex="-1">查看是否安装了git <a class="header-anchor" href="#查看是否安装了git" aria-label="Permalink to "查看是否安装了git""></a></h4><p>使用命令<code>rpm -qa|grep git</code></p><p><img src="/images/image-20230915092454293.png" alt="image-20230915092454293"></p><p>若已经安装,需要先卸载。卸载命令如下: rpm -e --nodeps git 或者 rpm -e git</p><p><img src="/images/image-20230915092504335.png" alt="image-20230915092504335"></p><h4 id="安装git" tabindex="-1">安装Git <a class="header-anchor" href="#安装git" aria-label="Permalink to "安装Git""></a></h4><p>输入命令:<code>yum install git</code></p><p><img src="/images/image-20230915092552024.png" alt="image-20230915092552024"></p><p>输入y回车。 确认安装</p><p><img src="/images/image-20230915092602989.png" alt="image-20230915092602989"></p><p><img src="/images/image-20230915092608399.png" alt="image-20230915092608399"></p><p>再使用 <code>rpm -qa|grep git</code> 来查看是否已经安装好了Git</p><p><img src="/images/image-20230915092623883.png" alt="image-20230915092623883"></p><h4 id="创建git库" tabindex="-1">创建Git库 <a class="header-anchor" href="#创建git库" aria-label="Permalink to "创建Git库""></a></h4><ul><li>在需要的位置创建一个裸仓库(最后以.git结尾)</li></ul><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">cd /usr/</span></span>
<span class="line"><span style="color:#e1e4e8;">mkdir git // 创建git文件夹</span></span>
<span class="line"><span style="color:#e1e4e8;">cd git // 进入到创建的git文件夹</span></span>
<span class="line"><span style="color:#e1e4e8;">groupadd git // 创建组</span></span>
<span class="line"><span style="color:#e1e4e8;">git init --bare // 初始化git仓库</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">cd /usr/</span></span>
<span class="line"><span style="color:#24292e;">mkdir git // 创建git文件夹</span></span>
<span class="line"><span style="color:#24292e;">cd git // 进入到创建的git文件夹</span></span>
<span class="line"><span style="color:#24292e;">groupadd git // 创建组</span></span>
<span class="line"><span style="color:#24292e;">git init --bare // 初始化git仓库</span></span></code></pre></div><ul><li>创建一个git用户并赋予密码</li></ul><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">useradd gituser</span></span>
<span class="line"><span style="color:#e1e4e8;">passwd gituser</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">useradd gituser</span></span>
<span class="line"><span style="color:#24292e;">passwd gituser</span></span></code></pre></div><ul><li>赋予git用户权限</li></ul><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">chown -R gituser:git /usr/git/</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">chown -R gituser:git /usr/git/</span></span></code></pre></div><p><img src="/images/image-20230915092640940.png" alt="image-20230915092640940"></p><p><img src="/images/image-20230915092646777.png" alt="image-20230915092646777"></p><h3 id="更新git-for-windows" tabindex="-1">更新git for windows <a class="header-anchor" href="#更新git-for-windows" aria-label="Permalink to "更新git for windows""></a></h3><ul><li>git版本是2.17.1之前</li></ul><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">git update</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">git update</span></span></code></pre></div><ul><li>git版本是2.17.1之后</li></ul><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">git update-git-for-windows</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">git update-git-for-windows</span></span></code></pre></div><h3 id="配置-git" tabindex="-1">配置 Git <a class="header-anchor" href="#配置-git" aria-label="Permalink to "配置 Git""></a></h3><blockquote><p>安装完成Git后还需要进行一些配置</p></blockquote><h4 id="用户信息" tabindex="-1">用户信息 <a class="header-anchor" href="#用户信息" aria-label="Permalink to "用户信息""></a></h4><blockquote><p>安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址。</p><p>这一点很重要,因为每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,并且不可更改</p></blockquote><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">git config --global user.name "John Doe"</span></span>
<span class="line"><span style="color:#e1e4e8;">git config --global user.email [email protected]</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">git config --global user.name "John Doe"</span></span>
<span class="line"><span style="color:#24292e;">git config --global user.email [email protected]</span></span></code></pre></div><p> 如果使用了 <code>--global</code> 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息,当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 <code>--global</code> 选项的命令来配置</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">git config user.name "John Doe"</span></span>
<span class="line"><span style="color:#e1e4e8;">git config user.email [email protected]</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">git config user.name "John Doe"</span></span>
<span class="line"><span style="color:#24292e;">git config user.email [email protected]</span></span></code></pre></div><h4 id="文本编辑器-可选" tabindex="-1">文本编辑器(可选) <a class="header-anchor" href="#文本编辑器-可选" aria-label="Permalink to "文本编辑器(可选)""></a></h4><blockquote><p>设置完成用户信息后,接下来就可以设置文本编辑器了,如果git需要输入相关信息就会调用该编辑器,如果未配置,Git 会使用操作系统默认的文本编辑器</p></blockquote><p> 在 Windows 系统上,如果你想要使用别的文本编辑器,那么必须指定可执行文件的完整路径</p><blockquote><p>下面是配置Git的默认编辑器是notepad++</p></blockquote><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"</span></span></code></pre></div><h4 id="查看配置信息" tabindex="-1">查看配置信息 <a class="header-anchor" href="#查看配置信息" aria-label="Permalink to "查看配置信息""></a></h4><blockquote><p>如果想要检查你的配置,可以使用 <code>git config --list</code> 命令来列出所有 Git 的相关配置</p></blockquote><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">git config --list</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">git config --list</span></span></code></pre></div><h2 id="git的基本使用" tabindex="-1">Git的基本使用 <a class="header-anchor" href="#git的基本使用" aria-label="Permalink to "Git的基本使用""></a></h2><h3 id="创建版本库" tabindex="-1">创建版本库 <a class="header-anchor" href="#创建版本库" aria-label="Permalink to "创建版本库""></a></h3><p>什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。由于git是分布式版本管理工具,所以git在不需要联网的情况下也具有完整的版本管理能力。</p><p>创建一个版本库非常简单,</p><p>1)首先,选择一个合适的地方,创建一个空目录。我在本机的<code>D:\\test</code>目录下,创建了一个Hello目录:</p><p><img src="/images/image-20230915092703207.png" alt="image-20230915092703207"></p><p>2)使用<code>git init</code>命令把这个目录变成Git可以管理的仓库:</p><p><img src="/images/image-20230915092711232.png" alt="image-20230915092711232"></p><p>命令输入后,会提示你,已经创建了一个空的Git仓库。此时你会在hello目录下发现一个隐藏目录<code>.git</code></p><p><img src="/images/image-20230915092719694.png" alt="image-20230915092719694"></p><p> 这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用<strong>ls -ah</strong>命令就可以看见。</p><p> 此处的hello目录就是我们的:<strong>工作区</strong>,存放所有当前文档。此目录下的文件才会被Git管理</p><p> hello中的<code>.git</code>目录就是我们的:<strong>本地仓库</strong>,管理并保存所有的文档变化及历史状态。</p><p>总结:创建版本库的步骤:</p><p>1) 进入需要管理的目录</p><p>2) 执行 <code>git init</code> 命令</p><h3 id="添加文件并提交" tabindex="-1">添加文件并提交 <a class="header-anchor" href="#添加文件并提交" aria-label="Permalink to "添加文件并提交""></a></h3><p> 版本控制系统,其目的就是跟踪文本文件的改动,例如我们开发时编写的<code>.java</code>、<code>.xml</code>、<code>.properties</code>本质都是文本文件。文件中每一个字符的变化都会被跟踪并且管理。</p><p>1)我们在当前的hello目录下创建一个新的文本文件:readme.txt</p><p><img src="/images/image-20230915092741022.png" alt="image-20230915092741022"></p><p>编写一段文字(注意,一定不要用windows的记事本):hello git</p><p><img src="/images/image-20230915092749888.png" alt="image-20230915092749888"></p><p>2)接下来,我们使用 <code>git add</code> 命令,将文件添加到暂存区</p><p><code>git add 文件名</code></p><p><img src="/images/image-20230915092759257.png" alt="image-20230915092759257"></p><p>没有任何的反应,证明没有问题</p><p>3)使用 <code>git commit</code> 命令,将暂存区文件提交到本地仓库</p><p><img src="/images/image-20230915092808271.png" alt="image-20230915092808271"></p><p>如果是第一次安装使用git,提交的时候需要认证用户</p><p><img src="/images/image-20230915092816352.png" alt="image-20230915092816352"></p><p>命令解释:</p><p> <strong>git commit</strong> 命令可以将暂存区的文件提交到版本库。</p><p> <strong>-m</strong> 参数,是本次提交的说明信息,用来注释本次提交做了些说明事情。</p><p><strong>总结</strong>,将一个文件添加到本地仓库,分两步:</p><p>3) 使用 <code>git add <file></code> 命令,添加文件。可以一次添加多个文件。</p><p>4) 使用 <strong>git commit</strong> 命令,提交,一次即可。</p><p>可能大家会有疑问,为什么这里不是直接commit提交,而是要经过add和commit两个步骤呢?</p><p>这就关系到Git的版本库中的 工作区 暂存区概念了。</p><h3 id="工作区-暂存区-版本库" tabindex="-1"><strong>工作区/暂存区/版本库</strong> <a class="header-anchor" href="#工作区-暂存区-版本库" aria-label="Permalink to "**工作区/暂存区/版本库**""></a></h3><p>我们先来理解下Git 工作区、暂存区和版本库概念</p><p><img src="/images/image-20230915170129080.png" alt="image-20230915170129080"></p><h4 id="工作区" tabindex="-1"><strong>工作区</strong> <a class="header-anchor" href="#工作区" aria-label="Permalink to "**工作区**""></a></h4><p>工作区就是你在电脑里能看到的、存放代码的目录。比如我们刚刚创建的hello目录:</p><p><img src="/images/image-20230915092829590.png" alt="image-20230915092829590"></p><p>其中包含了一个隐藏目录 <code>.git</code> ,其它就是我们需要被管理的文件。</p><h4 id="暂存区" tabindex="-1"><strong>暂存区</strong> <a class="header-anchor" href="#暂存区" aria-label="Permalink to "**暂存区**""></a></h4><p>暂存区:用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息</p><p>英文叫 stage 或 index,一般存放在 <strong>.git</strong> 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)</p><h4 id="版本库" tabindex="-1">版本库 <a class="header-anchor" href="#版本库" aria-label="Permalink to "版本库""></a></h4><p>工作区有一个隐藏目录 <code>.git</code>,这个不算工作区,而是Git的版本库。</p><p> 版本库就是安全存放数据的位置,这里面有你提交到所有版本的数据,其中HEAD指向最新放入仓库的版本,之所以说git 快,是因为它是分布式版本控制系统,大部分提交都是对本地仓库而言的,不依赖网络,最后一次会推送的到远程仓库</p><p>Git的版本库里存了很多东西,其中最重要的就是称为<strong>stage</strong>(或者叫<strong>index</strong>)的暂存区,还有Git为我们自动创建的第一个分支<strong>master</strong>,以及指向<strong>master</strong>的一个指针叫<strong>HEAD</strong>。</p><p><img src="/images/image-20230915170514502.png" alt="image-20230915170514502"></p><p>前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:</p><p>第一步是用<strong>git add</strong>把文件添加进去,实际上就是把文件修改添加到暂存区;</p><p>第二步是用<strong>git commit</strong>提交更改,实际上就是把暂存区的所有内容提交到当前分支。</p><p>因为我们创建Git版本库时,Git自动为我们创建了唯一一个<strong>master</strong>分支,所以,现在,<strong>git commit</strong>就是往<strong>master</strong>分支上提交更改。</p><p>你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。</p><h4 id="远程仓库" tabindex="-1">远程仓库 <a class="header-anchor" href="#远程仓库" aria-label="Permalink to "远程仓库""></a></h4><blockquote><p>托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换,比如GitHub,Gitee等</p></blockquote><h3 id="管理文件修改" tabindex="-1"><strong>管理文件修改</strong> <a class="header-anchor" href="#管理文件修改" aria-label="Permalink to "**管理文件修改**""></a></h3><p> 被版本库管理的文件不可避免的要发生修改,此时只需要直接对文件修改即可。修改完毕后需要将文件的修改提交到版本库。</p><p>我们对readme.txt文件进行修改,添加一行数据:</p><p><img src="/images/image-20230915092846574.png" alt="image-20230915092846574"></p><h4 id="差异比较" tabindex="-1">差异比较 <a class="header-anchor" href="#差异比较" aria-label="Permalink to "差异比较""></a></h4><p>用<code>git diff -- readme.txt</code>命令可以查看工作区和版本库里面最新版本的区别:</p><p><img src="/images/image-20230915092854826.png" alt="image-20230915092854826"></p><p>可以发现,与版本库中的 readme.txt相比,我们多了一行文本!</p><h4 id="查看状态-提交修改" tabindex="-1">查看状态,提交修改 <a class="header-anchor" href="#查看状态-提交修改" aria-label="Permalink to "查看状态,提交修改""></a></h4><p>我们如果不确定自己的哪些文件被修改了,可以使用<strong>git status</strong> 命令,查看当前工作区的状态:</p><p><img src="/images/image-20230915092903768.png" alt="image-20230915092903768"></p><p>可以清楚的看到:changes not staged for commit(修改没有被缓存,需要使用git add来进行添加操作)</p><p>我们使用 <code>git add</code> 命令,添加到暂存区,然后再次查看状态:</p><p><img src="/images/image-20230915092911407.png" alt="image-20230915092911407"></p><p>提示说:工作区很干净,没有任何需要提交,搞定!</p><h4 id="版本回退" tabindex="-1">版本回退 <a class="header-anchor" href="#版本回退" aria-label="Permalink to "版本回退""></a></h4><p>现在,我们再次修改readme.txt,添加一行内容:</p><p><img src="/images/image-20230915092925817.png" alt="image-20230915092925817"></p><p>然后提交到版本库:</p><p><img src="/images/image-20230915092935326.png" alt="image-20230915092935326"></p><h5 id="日志查看" tabindex="-1">日志查看 <a class="header-anchor" href="#日志查看" aria-label="Permalink to "日志查看""></a></h5><p>我们通过 <strong>git</strong> <strong>log</strong> 命令,可以查看历史的每次提交信息:</p><p><img src="/images/image-20230915092941997.png" alt="image-20230915092941997"></p><p>可以发现,目前为止,我们已经在本地仓库中提交了3次,也就是说有3个不同版本。其中,最近的这个版本有一个标示:<strong>HEAD</strong> ,这就是标记当前分支的当前版本所在位置。</p><p>本例当中,当前版本即 test version control这次提交,如果没有 <code>HEAD->MASTER</code> ,加上 <code>--decorate</code> 查看,即<code>git log --decorate</code>。</p><p><img src="/images/image-20230915092953926.png" alt="image-20230915092953926"></p><p> 另外,在log中,每一个版本的前面,都有一长串随即数字:2edf728e6fde09c9d33ce6dd96fd684ed09ebcc ,这是每次提交的<strong>commit id</strong> ,这是通过SHA1算法得到的值,Git通过这个唯一的id来区分每次提交。</p><h5 id="版本回退-1" tabindex="-1"><strong>版本回退</strong> <a class="header-anchor" href="#版本回退-1" aria-label="Permalink to "**版本回退**""></a></h5><p>现在,假设我们要回到上一级版本,该如何操作呢?</p><p>首先,Git通过<strong>HEAD</strong>来判断当前所在的版本位置。那么上一个版本,就用<strong>HEAD^<strong>标示,上上一个版本就是 <code>HEAD^^</code>,当然往上100个版本写100个 <code>^</code> 比较容易数不过来,所以写成</strong>HEAD~100</strong>。</p><p>如果要从 “test version control” 回退到 “modify readme file” ,我们可以使用 <code>git reset</code>命令</p><p><img src="/images/image-20230915093005731.png" alt="image-20230915093005731"></p><p>提示说:HEAD 现在已经被设置到 35CEB36 的版本,即 modify readme file。</p><p>我们查看readme.txt:</p><p><img src="/images/image-20230915201435169.gif" alt="img"></p><p>果然,版本已经回退了,最新添加的数据“test version control”已经没了。</p><p>此时再次查看日志,发现只剩下2次提交信息了,第三次提交的信息已经没了:</p><p><img src="/images/image-20230915093021611.png" alt="image-20230915093021611"></p><blockquote><p>假如此时我后悔了,还想回到第3次提交的版本,怎么办?</p></blockquote><h5 id="查看所有关联日志" tabindex="-1"><strong>查看所有关联日志</strong> <a class="header-anchor" href="#查看所有关联日志" aria-label="Permalink to "**查看所有关联日志**""></a></h5><p>我们可以通过<code>git reflog</code>命令,看到以前的每次执行动作:</p><p><img src="/images/image-20230915093030723.png" alt="image-20230915093030723"></p><p>其中红框内的部分,就是我们第三次提交的日志信息。前面的e498642 就是第三次提交的 commit id 的前几位数字。</p><p>我们可以通过指定commit id 的方式,来指定HEAD的位置:</p><p>指令:<code>git reset --hard {commit id}</code></p><p><img src="/images/image-20230915093040459.png" alt="image-20230915093040459"></p><p>查看日志:</p><p><img src="/images/image-20230915093048415.png" alt="image-20230915093048415"></p><p>查看文件:</p><p><img src="/images/image-20230915222134694.gif" alt="img"></p><p>数据又回来了!</p><h5 id="总结" tabindex="-1"><strong>总结</strong> <a class="header-anchor" href="#总结" aria-label="Permalink to "**总结**""></a></h5><p>如果要进行版本回退或前进,一般分两步:</p><p>1) 通过<strong>git log</strong> 或 <strong>git reflog</strong> 查看操作日志,查找版本的<strong>commit</strong> <strong>id</strong></p><p>2) 通过 <code>git reset --hard <commit id></code> 设置<strong>HEAD</strong>到指定版本</p><blockquote><p>其实版本的回退,仅仅是修改HEAD指针的位置而已,因此Git进行版本的切换,比svn要快的多!</p></blockquote><h4 id="撤销修改" tabindex="-1">撤销修改 <a class="header-anchor" href="#撤销修改" aria-label="Permalink to "撤销修改""></a></h4><blockquote><p>工作区 -> 暂存区 -> 版本库</p></blockquote><h5 id="撤销工作区修改" tabindex="-1">撤销工作区修改 <a class="header-anchor" href="#撤销工作区修改" aria-label="Permalink to "撤销工作区修改""></a></h5><p>现在我们在readme.txt中添加一行数据:</p><p><img src="/images/image-20230915093104575.png" alt="image-20230915093104575"></p><p>在你提交前,你突然发现这个修改是有问题的,你打算恢复到原来的样子。怎么办?</p><p>如果修改的并不多,我们完全可以手动恢复到原始状态。但是如果改动比较大,手动处理就很容易有遗漏,而且很麻烦。怎么办?</p><p>查看状态:</p><p><img src="/images/image-20230915093114216.png" alt="image-20230915093114216"></p><p>Git提示我们,现在文件已经修改,等待被staged(暂存)。我们有两个选择:</p><p>1) 可以使用<strong>git add</strong> 来添加到暂存区,接着去提交文件</p><p>2) 可以使 <code>git checkout -- <file></code> 来撤销修改</p><p>所以,这里我们选择第二种方案后,再次查看状态:</p><p><img src="/images/image-20230915093123184.png" alt="image-20230915093123184"></p><p><strong>工作区是干净的!修改已经被撤销了!</strong></p><p>查看文件:</p><p><img src="/images/image-20230915093138550.png" alt="image-20230915093138550"></p><h5 id="撤销staged修改" tabindex="-1">撤销staged修改 <a class="header-anchor" href="#撤销staged修改" aria-label="Permalink to "撤销staged修改""></a></h5><p>刚才的案例中,我们修改了数据,并没有add带暂存区,处理起来还算简单。如果我们已经吧数据add 到了暂存区,又该如何处理呢?</p><p>我们首先添加一行数据到readme.txt</p><p><img src="/images/image-20230915093146414.png" alt="image-20230915093146414"></p><p>并且添加到staged(暂存区),然后查看状态</p><p><img src="/images/image-20230915093154253.png" alt="image-20230915093154253"></p><p>有一个修改等待被提交,并且有一行提示:</p><p><img src="/images/image-20230915093202391.png" alt="image-20230915093202391"></p><p>可以使用 <code>git reset HEAD <file></code> 来撤销缓存修改。</p><p>我们前面说过,<strong>git reset</strong> 命令可以进行版本回退,此处reset 指定的是<strong>HEAD</strong> ,而不是其他版本,因此就有撤销缓存修改的作用:</p><p><img src="/images/image-20230915093210952.png" alt="image-20230915093210952"></p><p>查看状态:</p><p><img src="/images/image-20230915093220302.png" alt="image-20230915093220302"></p><p>发现文件的修改被撤回到了工作区,尚未添加到staged(暂存区),我们再次执行 <code>git checkout -- <file></code> 即可撤销工作区修改</p><p><img src="/images/image-20230915093228608.png" alt="image-20230915093228608"></p><p>工作区干净了!</p><p>查看文件:</p><p><img src="/images/image-20230915093235878.png" alt="image-20230915093235878"></p><p>文件也恢复了原来的状态,整个世界都清净了!</p><h5 id="总结-1" tabindex="-1">总结 <a class="header-anchor" href="#总结-1" aria-label="Permalink to "总结""></a></h5><p>撤销修改分两种情况:</p><p>1) 撤销工作区修改,使用 <code>git checkout -- <file></code></p><p>2) 撤销暂存区修改,分两步:</p><p>a) 使用<code>git reset HEAD <file></code>来撤销暂存区修改。</p><p>b) 使用<code>git checkout -- <file></code>来撤销工作区修改</p><h3 id="git-commit注释标准化" tabindex="-1">Git Commit注释标准化 <a class="header-anchor" href="#git-commit注释标准化" aria-label="Permalink to "Git Commit注释标准化""></a></h3><h4 id="前言" tabindex="-1"><strong>前言</strong> <a class="header-anchor" href="#前言" aria-label="Permalink to "**前言**""></a></h4><p>Git Commit Message 应该清晰明了,要用精简的语言说明本次提交的目的,其主要作用是为了后续的搜索、版本的回滚、合并冲突的追溯等操作。</p><p>我们在开发时一直以来对 Git Commit 格式有个约定俗称的要求,所以就没落实明确的规范。</p><p>因为没有明确的规范,就会导致提交的消息较为随意。甚至出现「“.”、”Update”」这样的消息。</p><p>直到我在 GitHub 上发现了这条 <a href="https://github.com/kvenux/kvenux.github.io/commits/master" target="_blank" rel="noreferrer">Commits</a> 时,才意识到提交信息也该规范起来。</p><p>以下图举例,当代码出现 Bug 时,应该回滚到哪个版本?</p><p>回滚到 “朕与将军解战袍,芙蓉暖帐度春宵” 吗?</p><p>这条记录所变更的内容是啥,看概要我一概不知。 ︿( ̄︶ ̄)︿</p><p><img src="/images/image-20230915093247798.png" alt="image-20230915093247798"></p><p>为了解决规范问题,我参考了一些的开源项目,当发现 <a href="https://github.com/commitizen/cz-cli" target="_blank" rel="noreferrer">commitizen</a> 库时,才知道好多大型开源(<a href="https://github.com/angular/angular" target="_blank" rel="noreferrer">AngularJS</a>、<a href="https://github.com/vuejs/vue/commits/dev" target="_blank" rel="noreferrer">VueJS</a>)项目早已使用了它。所以在接下来我会介绍一下 commitizen 工具所使用 Google AngularJS 规范。</p><h4 id="规范介绍" tabindex="-1"><strong>规范介绍</strong> <a class="header-anchor" href="#规范介绍" aria-label="Permalink to "**规范介绍**""></a></h4><p>这次主要介绍 AngularJS 的规范,它是由 Google 推出的一套提交消息规范标准,也是目前使用范围最广的规范。有一套合理的<a href="https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit" target="_blank" rel="noreferrer">手册</a>也较为<a href="https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#toc10" target="_blank" rel="noreferrer">系统化</a>;并且还有配套的工具可以供我们使用。</p><p>说白了,规范就是用工具进行强约束。单看规范比较简单,所以先让大家先看看面,知道他的大体规则后,在来讲细节。</p><p>规范执行方案如下:</p><p><img src="/images/image-20230915093257269.png" alt="image-20230915093257269"></p><p>既然有了方案,就会按照某些规则执行,以下是 Google AnguarJS 规范的要求:</p><p><strong>规范目标</strong></p><ul><li><p>允许通过脚本生成 CHANGELOG.md</p></li><li><p>可以通过范围的关键词,快速的搜索到指定版本</p></li></ul><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">git log HEAD --grep feat(package.json) # 在package.json文件里新增的特性。</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">git log HEAD --grep feat(package.json) # 在package.json文件里新增的特性。</span></span></code></pre></div><p><strong>格式要求</strong></p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;"><type>(<scope>): <subject></span></span>
<span class="line"><span style="color:#e1e4e8;"><BLANK LINE></span></span>
<span class="line"><span style="color:#e1e4e8;"><body></span></span>
<span class="line"><span style="color:#e1e4e8;"><BLANK LINE></span></span>
<span class="line"><span style="color:#e1e4e8;"><footer></span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;"><type>(<scope>): <subject></span></span>
<span class="line"><span style="color:#24292e;"><BLANK LINE></span></span>
<span class="line"><span style="color:#24292e;"><body></span></span>
<span class="line"><span style="color:#24292e;"><BLANK LINE></span></span>
<span class="line"><span style="color:#24292e;"><footer></span></span></code></pre></div><ul><li><p>消息只占用一行,任何行都不能超过 100 个字符</p></li><li><p>允许使用 GitHub 以及各种 Git 工具阅读消息</p></li><li><p>提交消息由页眉、正文和页脚组成,由空行分隔<code><type></code></p></li></ul><p>代表某次提交的类型,比如是修复一个 bug 或是增加一个 feature,类型如下:</p><p><img src="/images/image-20230915093313683.png" alt="image-20230915093313683"></p><p><code><scope></code></p><p>范围可以是指定提交更改位置的任何内容,如:</p><ul><li><p>对 package.json 文件新增依赖库,chore(package.json): 新增依赖库</p></li><li><p>或对代码进行重构,refacto(weChat.vue): 重构微信进件</p></li></ul><p><code><subject></code></p><p>如果没有更合适的范围,可以直接写提交内容</p><p></p><p><strong>Commit 实战</strong></p><p>提交一条依赖库变更,type 为 chore(增加依赖库);等提交完成后,使用 Git 工具进行搜索。</p><p>此时搜索类型是 chore(package.json),所以就能知道 package.json 文件所有的历史变更。</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;"># 新增一条 Commit 记录</span></span>
<span class="line"><span style="color:#e1e4e8;">git commit -m 'chore(package.json): 新增 AngularJS 规范,Commit 时会自动调用钩子(GitHook)来判断 Message 是否有效'</span></span>
<span class="line"><span style="color:#e1e4e8;"></span></span>
<span class="line"><span style="color:#e1e4e8;"># 搜索跟 package.json 文件相关的历史记录</span></span>
<span class="line"><span style="color:#e1e4e8;">git log HEAD --grep chore(package.json)</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;"># 新增一条 Commit 记录</span></span>
<span class="line"><span style="color:#24292e;">git commit -m 'chore(package.json): 新增 AngularJS 规范,Commit 时会自动调用钩子(GitHook)来判断 Message 是否有效'</span></span>
<span class="line"><span style="color:#24292e;"></span></span>
<span class="line"><span style="color:#24292e;"># 搜索跟 package.json 文件相关的历史记录</span></span>
<span class="line"><span style="color:#24292e;">git log HEAD --grep chore(package.json)</span></span></code></pre></div><h4 id="工具介绍" tabindex="-1"><strong>工具介绍</strong> <a class="header-anchor" href="#工具介绍" aria-label="Permalink to "**工具介绍**""></a></h4><p>因为是 Google AngularJS 的标准规范,所以提供了多种工具。如生成 CHANGELOG.md,提交工具,检查工具。</p><p>工具列表:</p><ul><li>提交工具 <a href="https://github.com/commitizen/cz-cli" target="_blank" rel="noreferrer">commitizen</a>,如果是初学者,可以使用 commitizen 帮助我们生成消息</li></ul><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">或者</span></span>
<span class="line"><span style="color:#e1e4e8;">npm install -g commitizen</span></span>
<span class="line"><span style="color:#e1e4e8;">commitizen init cz-conventional-changelog --save --save-exact</span></span>
<span class="line"><span style="color:#e1e4e8;">// 项目做些更改之后</span></span>
<span class="line"><span style="color:#e1e4e8;">git add .</span></span>
<span class="line"><span style="color:#e1e4e8;">git cz # 安装完毕之后,使用git cz来代替git commit命令即可</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">或者</span></span>
<span class="line"><span style="color:#24292e;">npm install -g commitizen</span></span>
<span class="line"><span style="color:#24292e;">commitizen init cz-conventional-changelog --save --save-exact</span></span>
<span class="line"><span style="color:#24292e;">// 项目做些更改之后</span></span>
<span class="line"><span style="color:#24292e;">git add .</span></span>
<span class="line"><span style="color:#24292e;">git cz # 安装完毕之后,使用git cz来代替git commit命令即可</span></span></code></pre></div><ul><li>生成 <a href="https://github.com/conventional-changelog/standard-version" target="_blank" rel="noreferrer">CHANGELOG.md</a>,把 Git Commit Message 的消息自动生成 CHANGELOG.md</li></ul><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">npm install -g conventional-changelog-cli</span></span>
<span class="line"><span style="color:#e1e4e8;"></span></span>
<span class="line"><span style="color:#e1e4e8;"># 在文档前面新增</span></span>
<span class="line"><span style="color:#e1e4e8;">conventional-changelog -p angular -i CHANGELOG.md -s</span></span>
<span class="line"><span style="color:#e1e4e8;"># 生成所有的log</span></span>
<span class="line"><span style="color:#e1e4e8;">conventional-changelog -p angular -i CHANGELOG.md -s -r 0</span></span>
<span class="line"><span style="color:#e1e4e8;"></span></span>
<span class="line"><span style="color:#e1e4e8;">配置到npm中</span></span>
<span class="line"><span style="color:#e1e4e8;">{</span></span>
<span class="line"><span style="color:#e1e4e8;"> "scripts": {</span></span>
<span class="line"><span style="color:#e1e4e8;"> "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s" </span></span>
<span class="line"><span style="color:#e1e4e8;"> } </span></span>
<span class="line"><span style="color:#e1e4e8;">}</span></span>
<span class="line"><span style="color:#e1e4e8;"># 要注意的是,在我们每次changelog之前,都必须要使用npm version升级版本,否则,commit一直都会有之前的记录。</span></span>
<span class="line"><span style="color:#e1e4e8;">npm run changelog即可</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">npm install -g conventional-changelog-cli</span></span>
<span class="line"><span style="color:#24292e;"></span></span>
<span class="line"><span style="color:#24292e;"># 在文档前面新增</span></span>
<span class="line"><span style="color:#24292e;">conventional-changelog -p angular -i CHANGELOG.md -s</span></span>
<span class="line"><span style="color:#24292e;"># 生成所有的log</span></span>
<span class="line"><span style="color:#24292e;">conventional-changelog -p angular -i CHANGELOG.md -s -r 0</span></span>
<span class="line"><span style="color:#24292e;"></span></span>
<span class="line"><span style="color:#24292e;">配置到npm中</span></span>
<span class="line"><span style="color:#24292e;">{</span></span>
<span class="line"><span style="color:#24292e;"> "scripts": {</span></span>
<span class="line"><span style="color:#24292e;"> "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s" </span></span>
<span class="line"><span style="color:#24292e;"> } </span></span>
<span class="line"><span style="color:#24292e;">}</span></span>
<span class="line"><span style="color:#24292e;"># 要注意的是,在我们每次changelog之前,都必须要使用npm version升级版本,否则,commit一直都会有之前的记录。</span></span>
<span class="line"><span style="color:#24292e;">npm run changelog即可</span></span></code></pre></div><ul><li>Message <a href="https://github.com/marionebl/commitlint" target="_blank" rel="noreferrer">检查</a>,是否有 “不符合” 规范的内容,可以在 GitHook 中使用</li></ul><p>提交以及检查工具相对来说简单,大家自学即可,所以我以生成 CHANGELOG.md 举例。</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;"># 安装 CHANGELOG 生成器</span></span>
<span class="line"><span style="color:#e1e4e8;">npm install standard-version -g </span></span>
<span class="line"><span style="color:#e1e4e8;">或者</span></span>
<span class="line"><span style="color:#e1e4e8;">yarn global add standard-version</span></span>
<span class="line"><span style="color:#e1e4e8;"></span></span>
<span class="line"><span style="color:#e1e4e8;"># 生成文档</span></span>
<span class="line"><span style="color:#e1e4e8;">standard-version --first-release</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;"># 安装 CHANGELOG 生成器</span></span>
<span class="line"><span style="color:#24292e;">npm install standard-version -g </span></span>
<span class="line"><span style="color:#24292e;">或者</span></span>
<span class="line"><span style="color:#24292e;">yarn global add standard-version</span></span>
<span class="line"><span style="color:#24292e;"></span></span>
<span class="line"><span style="color:#24292e;"># 生成文档</span></span>
<span class="line"><span style="color:#24292e;">standard-version --first-release</span></span></code></pre></div><p>文档生成后,当前目录下就有 CHANGELOG.md 文件了,如果是 Node 项目,也会自动更新 package.json version 的版本号</p><p><img src="/images/image-20230915093328900.png" alt="image-20230915093328900"></p><p>这是根据 Git Commit Message 历史记录所生成的 CHANGELOG.md,在也不用手写了。( ̄▽ ̄)"</p><p><img src="/images/image-20230915093337650.png" alt="image-20230915093337650"></p><h2 id="分支管理" tabindex="-1">分支管理 <a class="header-anchor" href="#分支管理" aria-label="Permalink to "分支管理""></a></h2><h3 id="分支有什么用" tabindex="-1">分支有什么用 <a class="header-anchor" href="#分支有什么用" aria-label="Permalink to "分支有什么用""></a></h3><p> 假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险.</p><p> 现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。</p><p> 其他版本控制系统如SVN等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。</p><p> 但Git的分支是与众不同的,无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。</p><h3 id="git的分支管理原理" tabindex="-1"><strong>Git的分支管理原理</strong> <a class="header-anchor" href="#git的分支管理原理" aria-label="Permalink to "**Git的分支管理原理**""></a></h3><p> 我们的每次提交,都对应一个具体的时间点,git会把这许多的时间点串起来,就形成了一条时间线,这条时间线就是一个分支。Git中默认的分支就是主分支,叫master。</p><p>我们查看当前的提交日志:</p><p><img src="/images/image-20230915093435782.png" alt="image-20230915093435782"></p><p>发现总共有3次提交,这3次提交可以串起来成一条时间线,就是master分支:</p><p><img src="/images/image-20230915093444625.png" alt="image-20230915093444625"></p><p>每次提交,<strong>master</strong>分支都会新增一个时间点,分支线也不断变长。</p><p>当我们创建新的分支,例如<strong>dev</strong>分支。Git会创建一个新的指针,叫做<strong>dev</strong>,指向跟<strong>master</strong>相同的时间点(提交点),这样分支就创建好了,你的工作区无需任何改变,创建分支的速度非常的快。</p><p>而要切换分支,只需要把<strong>HEAD</strong>指向<strong>dev</strong>即可,所以你的分支实现了光速切换!</p><p><img src="/images/image-20230915093452260.png" alt="image-20230915093452260"></p><p>不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:</p><p><img src="/images/image-20230915093501142.png" alt="image-20230915093501142"></p><p>假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:</p><p><img src="/images/image-20230915093508903.png" alt="image-20230915093508903"></p><p>所以Git合并分支也很快!就改改指针,工作区内容也不变!</p><p>合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:</p><p><img src="/images/image-20230915093603761.png" alt="image-20230915093603761"></p><p>你会发现Git的分支管理,基本就是创建新的指针,改变HEAD指向,删除指针等操作,几乎没有文件的增删。所以速度非常快!</p><h3 id="分支的创建和合并" tabindex="-1"><strong>分支的创建和合并</strong> <a class="header-anchor" href="#分支的创建和合并" aria-label="Permalink to "**分支的创建和合并**""></a></h3><h4 id="创建分支" tabindex="-1"><strong>创建分支</strong> <a class="header-anchor" href="#创建分支" aria-label="Permalink to "**创建分支**""></a></h4><p>我们可以使用 <strong>git</strong> <strong>checkout -b</strong> 分支名 来创建并切换到新的分支:</p><p><img src="/images/image-20230915093615328.png" alt="image-20230915093615328"></p><p>你会注意到我们已经切换到了dev分支。 <strong>git</strong> <strong>checkout</strong> 加上 <strong>-b</strong> 参数,就等同于创建分支,并切换分支。相当于以下两条命令:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#e1e4e8;">git branch dev # 创建分支</span></span>
<span class="line"><span style="color:#e1e4e8;"></span></span>
<span class="line"><span style="color:#e1e4e8;">git checkout dev # 切换到具体分支</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#24292e;">git branch dev # 创建分支</span></span>
<span class="line"><span style="color:#24292e;"></span></span>
<span class="line"><span style="color:#24292e;">git checkout dev # 切换到具体分支</span></span></code></pre></div><p>使用<strong>git branch</strong> 查看所有分支,当前分支前面会有一个<code>*</code>表示:</p><p><img src="/images/image-20230915093624299.png" alt="image-20230915093624299"></p><p>然后我们可以在<strong>dev</strong>分支上进行修改和提交。例如我们在readme.txt上添加一行文字:</p><p><img src="/images/image-20230915093631481.png" alt="image-20230915093631481"></p><p>提交修改:</p><p><img src="/images/image-20230915093641247.png" alt="image-20230915093641247"></p><p>此时,<strong>dev</strong>分支已经比<strong>master</strong>领先了一次提交,并且<strong>HEAD</strong>指向的是<strong>dev</strong></p><p><img src="/images/image-20230915093651135.png" alt="image-20230915093651135"></p><h4 id="合并分支" tabindex="-1">合并分支 <a class="header-anchor" href="#合并分支" aria-label="Permalink to "合并分支""></a></h4><p>我们使用<strong>git checkout master</strong>切换回<strong>master</strong>分支,查看内容:</p><p><img src="/images/image-20230915093701670.png" alt="image-20230915093701670"></p><p>发现readme并没有改变,因为刚才修改的是<strong>dev</strong>分支。此时的<strong>HEAD</strong>已经指向了<strong>master</strong>了:</p><p><img src="/images/image-20230915093710973.png" alt="image-20230915093710973"></p><p>我们使用<strong>git merge dev</strong>命令将 <strong>dev</strong>分支的修改合并到<strong>master</strong>分支:</p><p><img src="/images/image-20230915093719295.png" alt="image-20230915093719295"></p><p><strong>git merge</strong>命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和<strong>dev</strong>分支的最新提交是完全一样的。</p><h4 id="删除分支" tabindex="-1"><strong>删除分支</strong> <a class="header-anchor" href="#删除分支" aria-label="Permalink to "**删除分支**""></a></h4><p>合并完成后,就可以放心地删除<strong>dev</strong>分支了,可以使用<strong>git branch -d</strong> <strong>dev</strong> 命令删除<strong>dev</strong>分支,dev就是具体的分支名</p><p><img src="/images/image-20230915093730282.png" alt="image-20230915093730282"></p><p>再次查看分支列表:</p><p><img src="/images/image-20230915093738777.png" alt="image-20230915093738777"></p><h4 id="总结-2" tabindex="-1">总结 <a class="header-anchor" href="#总结-2" aria-label="Permalink to "总结""></a></h4><p>1) 使用<strong>git branch</strong> <strong>分支名</strong> 创建分支</p><p>2) 使用<strong>git checkout</strong> <strong>分支名</strong> 来切换分支</p><p>3) 也可以使用 <strong>git checkout -b</strong> <strong>分支名</strong> 来完成 创建并切换分支的操作</p><p>4) 使用<strong>git merge</strong> <strong>分支名</strong> 来合并分支到当前分支</p><p>5) 使用<strong>git branch -d</strong> <strong>分支名</strong> 来删除指定分支,注意:要删除一个未合并的分支。需要使用**-D**参数进行强制删除</p><h3 id="解决冲突" tabindex="-1"><strong>解决冲突</strong> <a class="header-anchor" href="#解决冲突" aria-label="Permalink to "**解决冲突**""></a></h3><h4 id="制造冲突" tabindex="-1"><strong>制造冲突</strong> <a class="header-anchor" href="#制造冲突" aria-label="Permalink to "**制造冲突**""></a></h4><p>现在我们新建一个分支:<strong>dev</strong></p><p><img src="/images/image-20230915093747776.png" alt="image-20230915093747776"></p><p>然后修改readme.txt:</p><p><img src="/images/image-20230915093756535.png" alt="image-20230915093756535"></p><p>将<strong>dev</strong>的修改提交:</p><p><img src="/images/image-20230915093805017.png" alt="image-20230915093805017"></p><p>切换到<strong>master</strong>分支:</p><p><img src="/images/image-20230915093811945.png" alt="image-20230915093811945"></p><p>并且在readme.txt最后添加内容:</p><p><img src="/images/image-20230915093818766.png" alt="image-20230915093818766"></p><p>提交数据:</p><p><img src="/images/image-20230915093825367.png" alt="image-20230915093825367"></p><p>现在,master和dev都有了各自新的提交,变成了这样:</p><p><img src="/images/image-20230915093833248.png" alt="image-20230915093833248"></p><h4 id="解决冲突-1" tabindex="-1"><strong>解决冲突</strong> <a class="header-anchor" href="#解决冲突-1" aria-label="Permalink to "**解决冲突**""></a></h4><p>这种情况下,是无法进行快速合并的。我们试一下:</p><p><img src="/images/image-20230915093840454.png" alt="image-20230915093840454"></p><p>自动合并失败,必须先解决文件冲突,才能提交。</p><p>此时查看readme.txt文件:</p><p><img src="/images/image-20230915093848712.png" alt="image-20230915093848712"></p><p>我们可以根据实际情况进行冲突解决,比如两者都保留:</p><p><img src="/images/image-20230915093856228.png" alt="image-20230915093856228"></p><p>然后再次提交:</p><p><img src="/images/image-20230915093903843.png" alt="image-20230915093903843"></p><p>工作区就干净了。此时master和dev分支线就变成了这样:</p><p><img src="/images/image-20230915093912262.png" alt="image-20230915093912262"></p><p>可以用<strong>git log --graph --decorate --pretty=oneline --abbrev-commit</strong>命令来查看:</p><p><img src="/images/image-20230915093921952.png" alt="image-20230915093921952"></p><p>接下来就可以删除dev分支了。</p><p><img src="/images/image-20230915093929299.png" alt="image-20230915093929299"></p><h2 id="客户端工具tortoisegit" tabindex="-1">客户端工具TortoiseGit <a class="header-anchor" href="#客户端工具tortoisegit" aria-label="Permalink to "客户端工具TortoiseGit""></a></h2><p>现在Git的客户端工具非常多,比较流行的例如:TortoiseGit(在svn中俗称小乌龟)、SourceTree。</p><p>SourceTree的注册需要科学上网。因此这里就不做讲解了。</p><h3 id="安装" tabindex="-1"><strong>安装</strong> <a class="header-anchor" href="#安装" aria-label="Permalink to "**安装**""></a></h3><h4 id="安装tortoisegit" tabindex="-1"><strong>安装TortoiseGit</strong> <a class="header-anchor" href="#安装tortoisegit" aria-label="Permalink to "**安装TortoiseGit**""></a></h4><p><img src="/images/image-20230915093940276.png" alt="image-20230915093940276"></p><p>双击运行安装:</p><p><img src="/images/image-20230915093948563.png" alt="image-20230915093948563"></p><p>一路“Next”使用默认选项即可。</p><p><img src="/images/image-20230915093956965.png" alt="image-20230915093956965"></p><p>默认选项下会启动配置画面:</p><p><img src="/images/image-20230915094002862.png" alt="image-20230915094002862"></p><p>由于目前只有英文语言包,默认即可继续下一步。</p><p>配置git.exe,在4.2.1中已经安装过git-for-windows了所以在此找到git.exe所在的目录。</p><p><img src="/images/image-20230915094011438.png" alt="image-20230915094011438"></p><p>配置开发者姓名及邮箱,每次提交代码时都会把此信息包含到提交的信息中。</p><p><img src="/images/image-20230915094021134.png" alt="image-20230915094021134"></p><p>使用默认配置,点击“完成”按钮完成配置。</p><p><img src="/images/image-20230915094029888.png" alt="image-20230915094029888"></p><p>完整完毕后在系统右键菜单中会出现git的菜单项。</p><p><img src="/images/image-20230915094040758.png" alt="image-20230915094040758"></p><h4 id="安装中文语言包-可选" tabindex="-1"><strong>安装中文语言包</strong>(可选) <a class="header-anchor" href="#安装中文语言包-可选" aria-label="Permalink to "**安装中文语言包**(可选)""></a></h4><p>安装中文语言包并不是必选项。可以根据个人情况来选择安装。</p><p><img src="/images/image-20230915094049416.png" alt="image-20230915094049416"></p><p>双击运行:</p><p><img src="/images/image-20230915094059104.png" alt="image-20230915094059104"></p><p>直接“下一步”完整完毕。</p><p>鼠标右键选择Settings</p><p><img src="/images/image-20230915094112470.png" alt="image-20230915094112470"></p><p>语言包安装完毕后可以在TortoiseGit的设置中调整语言</p><p><img src="/images/image-20230915094124654.png" alt="image-20230915094124654"></p><h3 id="基本使用" tabindex="-1"><strong>基本使用</strong> <a class="header-anchor" href="#基本使用" aria-label="Permalink to "**基本使用**""></a></h3><h4 id="创建本地仓库" tabindex="-1"><strong>创建本地仓库</strong> <a class="header-anchor" href="#创建本地仓库" aria-label="Permalink to "**创建本地仓库**""></a></h4><p>我们新建一个空的文件夹:</p><p><img src="/images/image-20230915094136338.png" alt="image-20230915094136338"></p><p>然后进入tortoise目录,右键操作:</p><p><img src="/images/image-20230915094144604.png" alt="image-20230915094144604"></p><p>弹出提示,不要勾选:</p><p><img src="/images/image-20230915094153496.png" alt="image-20230915094153496"></p><p>查看目录,发现生成.git文件夹:</p><p><img src="/images/image-20230915094200663.png" alt="image-20230915094200663"></p><h4 id="添加文件并提交-1" tabindex="-1"><strong>添加文件并提交</strong> <a class="header-anchor" href="#添加文件并提交-1" aria-label="Permalink to "**添加文件并提交**""></a></h4><p>创建新的文件:</p><p><img src="/images/image-20230915094208953.png" alt="image-20230915094208953"></p><p>编写内容:</p><p><img src="/images/image-20230915094219059.png" alt="image-20230915094219059"></p><p>在文件夹中右键操作:</p><p><img src="/images/image-20230915094227819.png" alt="image-20230915094227819"></p><p>提示:这一步等同于我们的 <strong>git add readme.txt</strong></p><p><img src="/images/image-20230915094237868.png" alt="image-20230915094237868"></p><p>此时直接点击提交,即可完成:git commit 操作:</p><p><img src="/images/image-20230915094245210.png" alt="image-20230915094245210"></p><p>提示:</p><p><img src="/images/image-20230915094253461.png" alt="image-20230915094253461"></p><h4 id="管理修改" tabindex="-1"><strong>管理修改</strong> <a class="header-anchor" href="#管理修改" aria-label="Permalink to "**管理修改**""></a></h4><h5 id="差异对比" tabindex="-1"><strong>差异对比</strong> <a class="header-anchor" href="#差异对比" aria-label="Permalink to "**差异对比**""></a></h5><p>修改readme.txt:</p><p><img src="/images/image-20230915094302018.png" alt="image-20230915094302018"></p><p>右键操作:</p><p><img src="/images/image-20230915094308770.png" alt="image-20230915094308770"></p><p>结果:</p><p><img src="/images/image-20230915094316405.png" alt="image-20230915094316405"></p><h5 id="提交修改" tabindex="-1"><strong>提交修改</strong> <a class="header-anchor" href="#提交修改" aria-label="Permalink to "**提交修改**""></a></h5><p>直接在文件上选择右键,提交即可(只要add过一次,后续不用add操作,直接提交):</p><p><img src="/images/image-20230915094324045.png" alt="image-20230915094324045"></p><h5 id="查看提交日志" tabindex="-1"><strong>查看提交日志</strong> <a class="header-anchor" href="#查看提交日志" aria-label="Permalink to "**查看提交日志**""></a></h5><p>选中文件,右键菜单中,选中查看日志:</p><p><img src="/images/image-20230915094333395.png" alt="image-20230915094333395"></p><p>提交的日志信息:</p><p><img src="/images/image-20230915094340846.png" alt="image-20230915094340846"></p><h5 id="版本回退-2" tabindex="-1"><strong>版本回退</strong> <a class="header-anchor" href="#版本回退-2" aria-label="Permalink to "**版本回退**""></a></h5><p>现在我们再次修改readme.txt,并且提交</p><p><img src="/images/image-20230915094349989.png" alt="image-20230915094349989"></p><p>查看日志:</p><p><img src="/images/image-20230915094356610.png" alt="image-20230915094356610"></p><p>假如我们要回到上一个版本,也就是第2次提交。</p><p>我们选中第2次提交,然后右键,选中:<strong>重置"master"到这个版本</strong></p><p><img src="/images/image-20230915094407443.png" alt="image-20230915094407443"></p><p>弹出菜单,这里选中Hard模式,然后确定:</p><p><img src="/images/image-20230915094416818.png" alt="image-20230915094416818"></p><p>再次查看日志,只剩下第1和第2次提交了。并且HEAD已经设置到了第2次提交位置</p><p><img src="/images/image-20230915094424837.png" alt="image-20230915094424837"></p><p>文件也回滚了:</p><p>如果我现在后悔了,想再次回到第3次提交怎么办?现在连日志都没有了!</p><p>此时,在空白处点击右键,选中 <strong>显示引用记录</strong>:</p><p><img src="/images/image-20230915094436476.png" alt="image-20230915094436476"></p><p>弹出所有操作的日志信息:</p><p><img src="/images/image-20230915094444072.png" alt="image-20230915094444072"></p><p>现在,我们找到第3次提交,右键,选中:<strong>重置“master”到这个版本</strong></p><p><img src="/images/image-20230915094452808.png" alt="image-20230915094452808"></p><p>结果,第3次提交又回来了!</p><p><img src="/images/image-20230915094500508.png" alt="image-20230915094500508"></p><p>文件内容回来了:</p><p><img src="/images/image-20230915094506178.png" alt="image-20230915094506178"></p><h5 id="撤销修改-1" tabindex="-1">撤销修改 <a class="header-anchor" href="#撤销修改-1" aria-label="Permalink to "撤销修改""></a></h5><p>我们现在修改文件:</p><p><img src="/images/image-20230915094517464.png" alt="image-20230915094517464"></p><p>现在后悔了,想要还原到修改以前。</p><p>我们可以选中文件,右键。然后选中菜单:还原。</p><p><img src="/images/image-20230915094528218.png" alt="image-20230915094528218"></p><p>点击确定:</p><p><img src="/images/image-20230915094536173.png" alt="image-20230915094536173"></p><p>还原成功:</p><p><img src="/images/image-20230915094543877.png" alt="image-20230915094543877"></p><p>查看文件:</p><p><img src="/images/image-20230915094552832.png" alt="image-20230915094552832"></p><h3 id="访问远程仓库" tabindex="-1">访问远程仓库 <a class="header-anchor" href="#访问远程仓库" aria-label="Permalink to "访问远程仓库""></a></h3><p>我们创建一个新的仓库:</p><p><img src="/images/image-20230915094609999.png" alt="image-20230915094609999"></p><p><img src="/images/image-20230915094615295.png" alt="image-20230915094615295"></p><h4 id="设置ssh" tabindex="-1">设置SSH <a class="header-anchor" href="#设置ssh" aria-label="Permalink to "设置SSH""></a></h4><p>由于安装时,我们并没有设定SSH信息,因此默认tortoise默认使用的ssh工具是“PuTTY”。</p><p>然而,git Bash使用的ssh工具是“openSSH”,如果想让TortoiseGit也使用刚才生成的密钥可以做如下配置:</p><p><img src="/images/image-20230915094623136.png" alt="image-20230915094623136"></p><p>找到git安装目录下的ssh.exe文件:</p><p><img src="/images/image-20230915094630103.png" alt="image-20230915094630103"></p><h4 id="关联远程仓库" tabindex="-1">关联远程仓库 <a class="header-anchor" href="#关联远程仓库" aria-label="Permalink to "关联远程仓库""></a></h4><p><img src="/images/image-20230915094647128.png" alt="image-20230915094647128"></p><p>这里的四个选项:</p><p>1) 远端仓库名称,一般叫origin</p><p>2) URL:远程仓库地址 <code>ssh://[email protected]:22/fangqyou/tortoise.git</code></p><p>3) 推送URL:同上 <code>ssh://[email protected]:22/fangqyou/tortoise.git</code></p><p>4) Putty密钥:我们用git bash 生成的私钥。</p><h4 id="推送本地仓库" tabindex="-1"><strong>推送本地仓库</strong> <a class="header-anchor" href="#推送本地仓库" aria-label="Permalink to "**推送本地仓库**""></a></h4><p>在空白处点右键,选择 “<strong>Git同步</strong>”:</p><p><img src="/images/image-20230915094707599.png" alt="image-20230915094707599"></p><p>弹出菜单中,选择将master推送到远程仓库的master:</p><p><img src="/images/image-20230915094716699.png" alt="image-20230915094716699"></p><p><img src="/images/image-20230915094727337.png" alt="image-20230915094727337"></p><p>成功:</p><p><img src="/images/image-20230915094818741.png" alt="image-20230915094818741"></p><p>私服中也显示了最新的信息:</p><p><img src="/images/image-20230915094827533.png" alt="image-20230915094827533"></p><h4 id="从远程仓库拉取" tabindex="-1"><strong>从远程仓库拉取</strong> <a class="header-anchor" href="#从远程仓库拉取" aria-label="Permalink to "**从远程仓库拉取**""></a></h4><p>现在,我们先在远程仓库修改数据:</p><p><img src="/images/image-20230915094838142.png" alt="image-20230915094838142"></p><p>然后在本地的tortise文件夹点击右键,菜单中选择:拉取:</p><p><img src="/images/image-20230915094846534.png" alt="image-20230915094846534"></p><p><img src="/images/image-20230915094852882.png" alt="image-20230915094852882"></p><p>成功:</p><p><img src="/images/image-20230915094905529.png" alt="image-20230915094905529"></p><p>查看文件:</p><p><img src="/images/image-20230915094913052.png" alt="image-20230915094913052"></p><h3 id="分支管理-1" tabindex="-1"><strong>分支管理</strong> <a class="header-anchor" href="#分支管理-1" aria-label="Permalink to "**分支管理**""></a></h3><h4 id="创建分支-1" tabindex="-1"><strong>创建分支</strong> <a class="header-anchor" href="#创建分支-1" aria-label="Permalink to "**创建分支**""></a></h4><p>在文件夹的空白处点击右键。选择创建分支:</p><p><img src="/images/image-20230915094923573.png" alt="image-20230915094923573"></p><p>填写分支名称和说明:</p><p><img src="/images/image-20230915094932820.png" alt="image-20230915094932820"></p><p>查看日志,发现已经有了dev分支:</p><p><img src="/images/image-20230915094939626.png" alt="image-20230915094939626"></p><h4 id="切换分支" tabindex="-1"><strong>切换分支</strong> <a class="header-anchor" href="#切换分支" aria-label="Permalink to "**切换分支**""></a></h4><p>在空白处选择右键,菜单中选择: <strong>切换/检出</strong></p><p><img src="/images/image-20230915094947593.png" alt="image-20230915094947593"></p><p>选择要切换的分支:</p><p><img src="/images/image-20230915095513816.png" alt="image-20230915095513816"></p><p>在dev分支中。修改readme文件:</p><p><img src="/images/image-20230915095548251.png" alt="image-20230915095548251"></p><p>提交修改。</p><p>然后切换到master:</p><p><img src="/images/image-20230915095558665.png" alt="image-20230915095558665"></p><p>查看文件内容,发现并没有变化,因为刚才的修改是在dev完成的。master没有影响。</p><p><img src="/images/image-20230915095611489.png" alt="image-20230915095611489"></p><h4 id="合并分支-1" tabindex="-1"><strong>合并分支</strong> <a class="header-anchor" href="#合并分支-1" aria-label="Permalink to "**合并分支**""></a></h4><p>空白处点击右键,选择<strong>合并</strong>菜单</p><p><img src="/images/image-20230915095619118.png" alt="image-20230915095619118"></p><p>选择将dev合并当当前分支:</p><p><img src="/images/image-20230915095625836.png" alt="image-20230915095625836"></p><p>成功:</p><p><img src="/images/image-20230915095634005.png" alt="image-20230915095634005"></p><p>查看内容:</p><p><img src="/images/image-20230915095641857.png" alt="image-20230915095641857"></p><h4 id="解决冲突-2" tabindex="-1"><strong>解决冲突</strong> <a class="header-anchor" href="#解决冲突-2" aria-label="Permalink to "**解决冲突**""></a></h4><p>切换到dev,然后进行修改</p><p><img src="/images/image-20230915095649131.png" alt="image-20230915095649131"></p><p>提交数据。</p><p>切换到master,修改readme:</p><p><img src="/images/image-20230915095656244.png" alt="image-20230915095656244"></p><p>然后提交修改</p><p>尝试用master合并dev:</p><p><img src="/images/image-20230915095708185.png" alt="image-20230915095708185"></p><p>结果失败了,因为有冲突:</p><p><img src="/images/image-20230915095717622.png" alt="image-20230915095717622"></p><p>查看文件:</p><p><img src="/images/image-20230915095758948.png" alt="image-20230915095758948"></p><p>手动解决:根据需求去处理。这里我们假设两者都保留:</p><p>标记为解决:</p><p><img src="/images/image-20230915100131731.png" alt="image-20230915100131731"></p><p><img src="/images/image-20230915100136745.png" alt="image-20230915100136745"></p><p>解决完成,直接提交:</p><p><img src="/images/image-20230915100146719.png" alt="image-20230915100146719"></p><p>提示信息:</p><p><img src="/images/image-20230915100153591.png" alt="image-20230915100153591"></p><p><img src="/images/image-20230915100202136.png" alt="image-20230915100202136"></p><p>提交成功!</p><p><img src="/images/image-20230915100211603.png" alt="image-20230915100211603"></p><p>查看日志:</p><p><img src="/images/image-20230915100219815.png" alt="image-20230915100219815"></p><h3 id="将java工程加入到版本库" tabindex="-1">将Java工程加入到版本库 <a class="header-anchor" href="#将java工程加入到版本库" aria-label="Permalink to "将Java工程加入到版本库""></a></h3><p>现在,我们有一个准备好的maven项目,一个用户管理系统:usermanage</p><p>我们要吧这个项目交给git去管理。</p><h4 id="初始化本地仓库" tabindex="-1"><strong>初始化本地仓库</strong> <a class="header-anchor" href="#初始化本地仓库" aria-label="Permalink to "**初始化本地仓库**""></a></h4><p><img src="/images/image-20230915100229207.png" alt="image-20230915100229207"></p><h4 id="忽略文件和目录" tabindex="-1"><strong>忽略文件和目录</strong> <a class="header-anchor" href="#忽略文件和目录" aria-label="Permalink to "**忽略文件和目录**""></a></h4><p>将不需要管理的文件和目录忽略,maven项目中需要提交的只有src和pom.xml,其它文件和目录都应该忽略:</p><p><img src="/images/image-20230915100240647.png" alt="image-20230915100240647"></p><p>选择递归忽略:</p><p><img src="/images/image-20230915100248127.png" alt="image-20230915100248127"></p><p>同样的方式处理target目录等其他需要忽略的文件。</p><p><img src="/images/image-20230915100257825.png" alt="image-20230915100257825"></p><p>大家会注意到,在本地仓库目录,多出了一个.gitignore文件,这里面就定义了所有的过略规则:</p><p><img src="/images/image-20230915100305842.png" alt="image-20230915100305842"></p><h4 id="所有文件添加到暂存区" tabindex="-1"><strong>所有文件添加到暂存区</strong> <a class="header-anchor" href="#所有文件添加到暂存区" aria-label="Permalink to "**所有文件添加到暂存区**""></a></h4><p>方式1:使用git bash 。 敲击命令: git add . 就会把当前目录所有文件加入暂存区</p><p>方式2:使用tortoise:</p><p><img src="/images/image-20230915100314913.png" alt="image-20230915100314913"></p><p>你会发现,待添加的文件,只有src目录下的和pom.xml,当然还有那个.gitignore文件:</p><p><img src="/images/image-20230915100323528.png" alt="image-20230915100323528"></p><p>成功:</p><p><img src="/images/image-20230915100331947.png" alt="image-20230915100331947"></p><h4 id="提交" tabindex="-1"><strong>提交</strong> <a class="header-anchor" href="#提交" aria-label="Permalink to "**提交**""></a></h4><p>然后提交即可:</p><p><img src="/images/image-20230915100340276.png" alt="image-20230915100340276"></p><p>成功</p><p><img src="/images/image-20230915100409597.png" alt="image-20230915100409597"></p><p>有必要的话,推送到远程</p><h2 id="客户端工具gitextension" tabindex="-1">客户端工具gitextension <a class="header-anchor" href="#客户端工具gitextension" aria-label="Permalink to "客户端工具gitextension""></a></h2><p>下载:<a href="http://gitextensions.github.io/" target="_blank" rel="noreferrer">http://gitextensions.github.io/</a></p><p>安装:下一步next</p><h2 id="idea客户端" tabindex="-1"><strong>Idea客户端</strong> <a class="header-anchor" href="#idea客户端" aria-label="Permalink to "**Idea客户端**""></a></h2><h3 id="在idea中配置git" tabindex="-1">在Idea中配置Git <a class="header-anchor" href="#在idea中配置git" aria-label="Permalink to "在Idea中配置Git""></a></h3><p>打开File菜单:</p><p><strong>在File --> Setting->Version Control --> Git -->Path to Git executable选择你的git安装后的git.exe文件</strong></p><p><strong>打开Setting:</strong></p><p><strong>方式一:</strong></p><p><img src="/images/image-20230915100421038.png" alt="image-20230915100421038"></p><p><strong>方式二:</strong></p><p><img src="/images/image-20230915100428846.png" alt="image-20230915100428846"></p><p>配置本地安装的Git的git.ext文件:</p><p><img src="/images/image-20230915100437268.png" alt="image-20230915100437268"></p><p><strong>然后点击Test,测试是否设置成功</strong></p><p><img src="/images/image-20230915100447230.png" alt="image-20230915100447230"></p><h3 id="创建工程" tabindex="-1"><strong>创建工程</strong> <a class="header-anchor" href="#创建工程" aria-label="Permalink to "**创建工程**""></a></h3><p>我们新建一个maven工程:</p><p><img src="/images/image-20230915100456161.png" alt="image-20230915100456161"></p><p>编写简单的代码:</p><p><img src="/images/image-20230915100506390.png" alt="image-20230915100506390"></p><h3 id="将项目创建为本地仓库" tabindex="-1"><strong>将项目创建为本地仓库</strong> <a class="header-anchor" href="#将项目创建为本地仓库" aria-label="Permalink to "**将项目创建为本地仓库**""></a></h3><p>打开VCS菜单</p><p><strong>VCS --> Import into Version Control --> Create Git Repository</strong></p><p><img src="/images/image-20230915100514351.png" alt="image-20230915100514351"></p><p>在弹框中选中项目所在的位置,<strong>点击OK</strong>。</p><p><img src="/images/image-20230915100521722.png" alt="image-20230915100521722"></p><p>此时项目文件全部变成<strong>棕色</strong>。</p><p><img src="/images/image-20230915100530070.png" alt="image-20230915100530070"></p><p>项目Git版本已经创建成功。</p><p><img src="/images/image-20230915100540283.png" alt="image-20230915100540283"></p><h3 id="忽略文件" tabindex="-1"><strong>忽略文件</strong> <a class="header-anchor" href="#忽略文件" aria-label="Permalink to "**忽略文件**""></a></h3><p>安装ignore插件,在file->settings->plugin搜索.ignore,点击Install,安装完成后就可以愉快的使用了,记得重启IDEA。</p><p>可以手动创建和修改.gitignore文件,也可以通过插件过滤。</p><p><img src="/images/image-20230915100551027.png" alt="image-20230915100551027"></p><h3 id="提交代码" tabindex="-1"><strong>提交代码</strong> <a class="header-anchor" href="#提交代码" aria-label="Permalink to "**提交代码**""></a></h3><h4 id="添加到暂存区" tabindex="-1"><strong>添加到暂存区</strong> <a class="header-anchor" href="#添加到暂存区" aria-label="Permalink to "**添加到暂存区**""></a></h4><p>项目右键选择Git --> add</p><p><img src="/images/image-20230915100558573.png" alt="image-20230915100558573"></p><p>此时项目文件全部变成绿色,此时文件只是处于暂存区,并没有真正进入到版本库中。</p><p><img src="/images/image-20230915100606924.png" alt="image-20230915100606924"></p><h4 id="提交到本地仓库" tabindex="-1"><strong>提交到本地仓库</strong> <a class="header-anchor" href="#提交到本地仓库" aria-label="Permalink to "**提交到本地仓库**""></a></h4><p>项目右键Git--> Commit Directory</p><p>在弹窗中输入Commit Message,点击commit,此时项目文件从暂存区真正进入版本库中,项目文件变成<strong>黑色</strong>。</p><p><img src="/images/image-20230915100619023.png" alt="image-20230915100619023"></p><p>编辑本次提交备注信息,然后点击commit按钮。</p><p><img src="/images/image-20230915100628294.png" alt="image-20230915100628294"></p><p>此时项目文件全部变成<strong>黑色</strong>:</p><p><img src="/images/image-20230915100637137.png" alt="image-20230915100637137"></p><h3 id="提交远程仓库" tabindex="-1"><strong>提交远程仓库</strong> <a class="header-anchor" href="#提交远程仓库" aria-label="Permalink to "**提交远程仓库**""></a></h3><h4 id="新建一个远程仓库" tabindex="-1"><strong>新建一个远程仓库</strong> <a class="header-anchor" href="#新建一个远程仓库" aria-label="Permalink to "**新建一个远程仓库**""></a></h4><p>在远程仓库创建新项目:</p><p><img src="/images/image-20230915100648939.png" alt="image-20230915100648939"></p><p>记录地址:</p><p><img src="/images/image-20230915100658535.png" alt="image-20230915100658535"></p><h4 id="推送到远程仓库" tabindex="-1"><strong>推送到远程仓库</strong> <a class="header-anchor" href="#推送到远程仓库" aria-label="Permalink to "**推送到远程仓库**""></a></h4><p>右键选择项目—> <strong>Git ->Repository -> Push</strong> ,然后填写远程仓库地址。</p><p><img src="/images/image-20230915100709494.png" alt="image-20230915100709494"></p><p>复制远程仓库的地址,并填写:</p><p><img src="/images/image-20230915100717648.png" alt="image-20230915100717648"></p><p>点击Push, 推送成功, 在Idea右下角弹出提示框:</p><p><img src="/images/image-20230915100725747.png" alt="image-20230915100725747"></p><p>查看远程仓库,推送成功。</p><p><img src="/images/image-20230915100732907.png" alt="image-20230915100732907"></p><h4 id="拉取数据" tabindex="-1"><strong>拉取数据</strong> <a class="header-anchor" href="#拉取数据" aria-label="Permalink to "**拉取数据**""></a></h4><p>在远程仓库随意修改代码:</p><p><img src="/images/image-20230915100740252.png" alt="image-20230915100740252"></p><p>在项目中,拉取代码:</p><p><img src="/images/image-20230915100747063.png" alt="image-20230915100747063"></p><p>点击Pull:</p><p><img src="/images/image-20230915100753984.png" alt="image-20230915100753984"></p><p>代码成功同步:</p><p><img src="/images/image-20230915100801300.png" alt="image-20230915100801300"></p><h3 id="克隆项目" tabindex="-1"><strong>克隆项目</strong> <a class="header-anchor" href="#克隆项目" aria-label="Permalink to "**克隆项目**""></a></h3><h4 id="删除本地项目" tabindex="-1"><strong>删除本地项目</strong> <a class="header-anchor" href="#删除本地项目" aria-label="Permalink to "**删除本地项目**""></a></h4><p>Settings->Version Control</p><p>1)断开idea与Git版本仓库的联接:</p><p><img src="/images/image-20230915100808763.png" alt="image-20230915100808763"></p><ol start="2"><li>从Idea和本地文件目录中删除项目。</li></ol><h4 id="克隆远程仓库并导入idea" tabindex="-1"><strong>克隆远程仓库并导入Idea</strong> <a class="header-anchor" href="#克隆远程仓库并导入idea" aria-label="Permalink to "**克隆远程仓库并导入Idea**""></a></h4><p>打开Idea,点击 <strong>Check out form Version Control</strong>,选中Git</p><p><img src="/images/image-20230915100815354.png" alt="image-20230915100815354"></p><p>填入远程仓库SSH地址,输入你的远程仓库地址,点击Test,测试一下地址是否正确。</p><p>点击Clone</p><p><img src="/images/image-20230915100823528.png" alt="image-20230915100823528"></p><p>点击YES:</p><p>Clone出远程仓储的工程,并且导入到idea中。</p><p><img src="/images/image-20230915100831408.png" alt="image-20230915100831408"></p><p><strong>导入成功:</strong></p><p><img src="/images/image-20230915100843267.png" alt="image-20230915100843267"></p><p>右键Git,可以与远程仓库进行push和pull代码操作了。</p><p><img src="/images/image-20230915100849621.png" alt="image-20230915100849621"></p><h3 id="解决冲突-3" tabindex="-1"><strong>解决冲突</strong> <a class="header-anchor" href="#解决冲突-3" aria-label="Permalink to "**解决冲突**""></a></h3><h4 id="制造冲突-1" tabindex="-1"><strong>制造冲突</strong> <a class="header-anchor" href="#制造冲突-1" aria-label="Permalink to "**制造冲突**""></a></h4><p>1)我们创建新的分支dev,并且在dev修改提交代码。</p><p><img src="/images/image-20230915100857473.png" alt="image-20230915100857473"></p><p><img src="/images/image-20230915100901481.png" alt="image-20230915100901481"></p><p><img src="/images/image-20230915100906271.png" alt="image-20230915100906271"></p><p>2)然后在master修改提交代码。</p><p><img src="/images/image-20230915100916315.png" alt="image-20230915100916315"></p><p><img src="/images/image-20230915100921459.png" alt="image-20230915100921459"></p><p>接下来尝试合并dev分支:</p><p><img src="/images/image-20230915100929630.png" alt="image-20230915100929630"></p><p>选择要合并的分支:</p><p><img src="/images/image-20230915100939371.png" alt="image-20230915100939371"></p><p><strong>发现合并失败</strong>,此时文件有<strong>红色标记</strong></p><p><img src="/images/image-20230915101139767.png" alt="image-20230915101139767"></p><h4 id="解决冲突-4" tabindex="-1"><strong>解决冲突</strong> <a class="header-anchor" href="#解决冲突-4" aria-label="Permalink to "**解决冲突**""></a></h4><p><strong>点击Merge合并策略</strong>**</p><p> Accept Yours:保留你自己的代码,</p><p> Accept Theirs:保留别人的,</p><p> merge:人工合并 (人工把需要的代码复制粘贴到结果集result里面比较保险)</p><p><img src="/images/image-20230915101147214.png" alt="image-20230915101147214"></p><p><strong>弹出一个对比页面</strong>:</p><p>在Result中,手动合并完成后,点击Apply按钮,完成冲突代码合并。</p><p><img src="/images/image-20230915101153943.png" alt="image-20230915101153943"></p><p><strong>此时文件的红色标记没了</strong>:</p><p><img src="/images/image-20230915101200235.png" alt="image-20230915101200235"></p><p>但是有未提交的<strong>蓝色标记</strong>。然后提交,文件变为<strong>黑色</strong>。冲突被解决!</p><p><img src="/images/image-20230915101208566.png" alt="image-20230915101208566"></p><h2 id="git命令整理" tabindex="-1">Git命令整理 <a class="header-anchor" href="#git命令整理" aria-label="Permalink to "Git命令整理""></a></h2><p><img src="/images/image-20230915101231704.png" alt="image-20230915101231704"></p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">init</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">创建一个空的仓库</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">add</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">文件名</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">(提交到暂存区)</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">commit</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">文件名</span><span style="color:#E1E4E8;"> (提交到本地仓库)</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">commit</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">-am</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">"注释"</span><span style="color:#E1E4E8;"> (直接提交到本地仓库)</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">log</span><span style="color:#E1E4E8;"> </span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">reflog</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">(看到所有的日志)</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">reset</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">--hard</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">HEAD^</span><span style="color:#E1E4E8;"> (回到上一个版本 </span><span style="color:#9ECBFF;">^^^回到第三个版本</span><span style="color:#E1E4E8;">)</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">reset</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">--hard</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">提交的id</span><span style="color:#E1E4E8;"> </span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">remote</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">add</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">别名(origin)</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">远程仓库地址</span></span>
<span class="line"><span style="color:#F97583;">***</span><span style="color:#E1E4E8;">提交之前先拉取代码(git pull origin master)</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">add</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">文件名</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">(解决冲突之后,告诉git我们解决了)</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">push</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">origin</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">master</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">config</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">credential.helper</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">store</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">免密码</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">clone</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">远程仓库地址</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">-b</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">指定分支名称</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;"># 合并代码冲突样式说明</span></span>
<span class="line"><span style="color:#F97583;"><<<</span><span style="color:#F97583;"><<<</span><span style="color:#9ECBFF;"><</span><span style="color:#E1E4E8;"> HEAD</span></span>
<span class="line"><span style="color:#B392F0;">bbb</span><span style="color:#E1E4E8;"> </span></span>
<span class="line"><span style="color:#E1E4E8;">=======</span></span>
<span class="line"><span style="color:#B392F0;">dierge</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">xiede</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">chongtudaim</span></span>
<span class="line"><span style="color:#E1E4E8;">>>>>>>> </span><span style="color:#B392F0;">a2426122f3d1e87ff27270fb1e15330426dd35f9</span></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0;">HEAD</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">和</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">=======</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">之间的代码是当前分支</span></span>
<span class="line"><span style="color:#E1E4E8;">=======和>>>>>>> </span><span style="color:#9ECBFF;">之间是别人写的代码</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">branch</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">分支名称</span><span style="color:#E1E4E8;"> (创建分支)</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">checkout</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">分支名称</span><span style="color:#E1E4E8;"> (切换分支)</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">checkout</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">-b</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">分支名称(创建分支并切换)</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">merge</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">被合并的分支名称(例如想在要将dev合并到master,那就在master分支执行</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">merge</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">dev)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;"># 工作中,用git extensions看不到别人创建的代码分支, 打开git客户端</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">fetch</span><span style="color:#E1E4E8;"> </span><span style="color:#6A737D;"># 拉取远程仓库的分支信息的更新</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">init</span><span style="color:#24292E;"> </span><span style="color:#032F62;">创建一个空的仓库</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">add</span><span style="color:#24292E;"> </span><span style="color:#032F62;">文件名</span><span style="color:#24292E;"> </span><span style="color:#032F62;">(提交到暂存区)</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">commit</span><span style="color:#24292E;"> </span><span style="color:#032F62;">文件名</span><span style="color:#24292E;"> (提交到本地仓库)</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">commit</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">-am</span><span style="color:#24292E;"> </span><span style="color:#032F62;">"注释"</span><span style="color:#24292E;"> (直接提交到本地仓库)</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">log</span><span style="color:#24292E;"> </span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">reflog</span><span style="color:#24292E;"> </span><span style="color:#032F62;">(看到所有的日志)</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">reset</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">--hard</span><span style="color:#24292E;"> </span><span style="color:#032F62;">HEAD^</span><span style="color:#24292E;"> (回到上一个版本 </span><span style="color:#032F62;">^^^回到第三个版本</span><span style="color:#24292E;">)</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">reset</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">--hard</span><span style="color:#24292E;"> </span><span style="color:#032F62;">提交的id</span><span style="color:#24292E;"> </span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">remote</span><span style="color:#24292E;"> </span><span style="color:#032F62;">add</span><span style="color:#24292E;"> </span><span style="color:#032F62;">别名(origin)</span><span style="color:#24292E;"> </span><span style="color:#032F62;">远程仓库地址</span></span>
<span class="line"><span style="color:#D73A49;">***</span><span style="color:#24292E;">提交之前先拉取代码(git pull origin master)</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">add</span><span style="color:#24292E;"> </span><span style="color:#032F62;">文件名</span><span style="color:#24292E;"> </span><span style="color:#032F62;">(解决冲突之后,告诉git我们解决了)</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">push</span><span style="color:#24292E;"> </span><span style="color:#032F62;">origin</span><span style="color:#24292E;"> </span><span style="color:#032F62;">master</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">config</span><span style="color:#24292E;"> </span><span style="color:#032F62;">credential.helper</span><span style="color:#24292E;"> </span><span style="color:#032F62;">store</span><span style="color:#24292E;"> </span><span style="color:#032F62;">免密码</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">clone</span><span style="color:#24292E;"> </span><span style="color:#032F62;">远程仓库地址</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">-b</span><span style="color:#24292E;"> </span><span style="color:#032F62;">指定分支名称</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;"># 合并代码冲突样式说明</span></span>
<span class="line"><span style="color:#D73A49;"><<<</span><span style="color:#D73A49;"><<<</span><span style="color:#032F62;"><</span><span style="color:#24292E;"> HEAD</span></span>
<span class="line"><span style="color:#6F42C1;">bbb</span><span style="color:#24292E;"> </span></span>
<span class="line"><span style="color:#24292E;">=======</span></span>
<span class="line"><span style="color:#6F42C1;">dierge</span><span style="color:#24292E;"> </span><span style="color:#032F62;">xiede</span><span style="color:#24292E;"> </span><span style="color:#032F62;">chongtudaim</span></span>
<span class="line"><span style="color:#24292E;">>>>>>>> </span><span style="color:#6F42C1;">a2426122f3d1e87ff27270fb1e15330426dd35f9</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6F42C1;">HEAD</span><span style="color:#24292E;"> </span><span style="color:#032F62;">和</span><span style="color:#24292E;"> </span><span style="color:#032F62;">=======</span><span style="color:#24292E;"> </span><span style="color:#032F62;">之间的代码是当前分支</span></span>
<span class="line"><span style="color:#24292E;">=======和>>>>>>> </span><span style="color:#032F62;">之间是别人写的代码</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">branch</span><span style="color:#24292E;"> </span><span style="color:#032F62;">分支名称</span><span style="color:#24292E;"> (创建分支)</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">checkout</span><span style="color:#24292E;"> </span><span style="color:#032F62;">分支名称</span><span style="color:#24292E;"> (切换分支)</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">checkout</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">-b</span><span style="color:#24292E;"> </span><span style="color:#032F62;">分支名称(创建分支并切换)</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">merge</span><span style="color:#24292E;"> </span><span style="color:#032F62;">被合并的分支名称(例如想在要将dev合并到master,那就在master分支执行</span><span style="color:#24292E;"> </span><span style="color:#032F62;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">merge</span><span style="color:#24292E;"> </span><span style="color:#032F62;">dev)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;"># 工作中,用git extensions看不到别人创建的代码分支, 打开git客户端</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">fetch</span><span style="color:#24292E;"> </span><span style="color:#6A737D;"># 拉取远程仓库的分支信息的更新</span></span></code></pre></div><h2 id="git-submodule" tabindex="-1">Git Submodule <a class="header-anchor" href="#git-submodule" aria-label="Permalink to "Git Submodule""></a></h2><p>有种情况我们经常会遇到:</p><p>某个工作中的项目需要包含并使用另一个项目。 也许是第三方库,或者你独立开发的,用于多个父项目的库。</p><p>现在问题来了:<strong>你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个</strong>。</p><h3 id="概念" tabindex="-1">概念 <a class="header-anchor" href="#概念" aria-label="Permalink to "概念""></a></h3><p>submodule,子模块,其实就是另一个仓库(更新子模块不会自动更新主模块的引用)</p><h3 id="基础操作" tabindex="-1">基础操作 <a class="header-anchor" href="#基础操作" aria-label="Permalink to "基础操作""></a></h3><h4 id="添加子模块" tabindex="-1">添加子模块 <a class="header-anchor" href="#添加子模块" aria-label="Permalink to "添加子模块""></a></h4><div class="language-shell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">shell</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;"># 直接clone,会在当前目录生成一个someSubmodule目录存放仓库内容</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">submodule</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">add</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">https://github.com/chaconinc/someSubmodule</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;"># 指定文件目录</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">submodule</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">add</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">https://github.com/chaconinc/someSubmodule</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">src/submodulePath</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;"># 直接clone,会在当前目录生成一个someSubmodule目录存放仓库内容</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">submodule</span><span style="color:#24292E;"> </span><span style="color:#032F62;">add</span><span style="color:#24292E;"> </span><span style="color:#032F62;">https://github.com/chaconinc/someSubmodule</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D;"># 指定文件目录</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">submodule</span><span style="color:#24292E;"> </span><span style="color:#032F62;">add</span><span style="color:#24292E;"> </span><span style="color:#032F62;">https://github.com/chaconinc/someSubmodule</span><span style="color:#24292E;"> </span><span style="color:#032F62;">src/submodulePath</span></span></code></pre></div><h4 id="clone已经包含子模块的项目" tabindex="-1">clone已经包含子模块的项目 <a class="header-anchor" href="#clone已经包含子模块的项目" aria-label="Permalink to "clone已经包含子模块的项目""></a></h4><p>正常clone包含子模块的函数之后,由于.submodule文件的存在someSubmodule已经自动生成。但是里面是空的。还需要执行2个命令。</p><div class="language-shell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">shell</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;"># 用来初始化本地配置文件</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">submodule</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">init</span></span>
<span class="line"><span style="color:#6A737D;"># 从该项目中抓取所有数据并检出父项目中列出的合适的提交(指定的提交)。</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">submodule</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">update</span></span>
<span class="line"><span style="color:#B392F0;">------------------更好的方式---------------------</span></span>
<span class="line"><span style="color:#6A737D;"># clone 父仓库的时候加上 --recursive,会自动初始化并更新仓库中的每一个子模块</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">clone</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">--recursive</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">https://github.com/chaconinc/MainProject</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;"># 用来初始化本地配置文件</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">submodule</span><span style="color:#24292E;"> </span><span style="color:#032F62;">init</span></span>
<span class="line"><span style="color:#6A737D;"># 从该项目中抓取所有数据并检出父项目中列出的合适的提交(指定的提交)。</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">submodule</span><span style="color:#24292E;"> </span><span style="color:#032F62;">update</span></span>
<span class="line"><span style="color:#6F42C1;">------------------更好的方式---------------------</span></span>
<span class="line"><span style="color:#6A737D;"># clone 父仓库的时候加上 --recursive,会自动初始化并更新仓库中的每一个子模块</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">clone</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">--recursive</span><span style="color:#24292E;"> </span><span style="color:#032F62;">https://github.com/chaconinc/MainProject</span></span></code></pre></div><h4 id="git-submodule-工作流" tabindex="-1">git submodule 工作流 <a class="header-anchor" href="#git-submodule-工作流" aria-label="Permalink to "git submodule 工作流""></a></h4><p>当一个项目里面包含子模块的时候,不仅仅需要对父仓库进行版本管理,子模块目录下也是存在版本的。那在不同的父仓库下面如何进行子模块的版本管理也成为新的问题。</p><p>最简单的办法,就是主项目只专注使用子模块的master分支上的版本,而不使用子模块内部的任何分支版本。</p><div class="language-shell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">shell</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#79B8FF;">cd</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">submodulePath</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">fetch</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">merge</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">origin/master</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#005CC5;">cd</span><span style="color:#24292E;"> </span><span style="color:#032F62;">submodulePath</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">fetch</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">merge</span><span style="color:#24292E;"> </span><span style="color:#032F62;">origin/master</span></span></code></pre></div><p>此时在主项目就能看到submodule目录已经更新了。 当然这也操作有点不方便,下面是更简便的方法</p><div class="language-shell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">shell</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;"># Git 将会进入子模块然后抓取并更新,默认更新master分支</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">submodule</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">update</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">--remote</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;"># Git 将会进入子模块然后抓取并更新,默认更新master分支</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">submodule</span><span style="color:#24292E;"> </span><span style="color:#032F62;">update</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">--remote</span></span></code></pre></div><p>如果需要更新其他分支的话,需要另外配置。</p><div class="language-shell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">shell</span><pre class="shiki github-dark vp-code-dark"><code><span class="line"><span style="color:#6A737D;"># 将git submodule update --remote 的分支设置为stable分支</span></span>
<span class="line"><span style="color:#B392F0;">git</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">config</span><span style="color:#E1E4E8;"> </span><span style="color:#79B8FF;">-f</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">.gitmodules</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">submodule.DbConnector.branch</span><span style="color:#E1E4E8;"> </span><span style="color:#9ECBFF;">stable</span></span></code></pre><pre class="shiki github-light vp-code-light"><code><span class="line"><span style="color:#6A737D;"># 将git submodule update --remote 的分支设置为stable分支</span></span>
<span class="line"><span style="color:#6F42C1;">git</span><span style="color:#24292E;"> </span><span style="color:#032F62;">config</span><span style="color:#24292E;"> </span><span style="color:#005CC5;">-f</span><span style="color:#24292E;"> </span><span style="color:#032F62;">.gitmodules</span><span style="color:#24292E;"> </span><span style="color:#032F62;">submodule.DbConnector.branch</span><span style="color:#24292E;"> </span><span style="color:#032F62;">stable</span></span></code></pre></div></div></div></main><footer class="VPDocFooter" data-v-e970bbc0 data-v-45cfeac9><!--[--><!--]--><!----><nav class="prev-next" data-v-45cfeac9><div class="pager" data-v-45cfeac9><!----></div><div class="pager" data-v-45cfeac9><a class="pager-link next" href="/tools-soft-baidupan.html" data-v-45cfeac9><span class="desc" data-v-45cfeac9>下一篇</span><span class="title" data-v-45cfeac9>百度网盘</span></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><!----><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"lang-java.md\":\"9fff46e5\",\"api-examples.md\":\"0c7bbd41\",\"lang-java-array.md\":\"9c8e9312\",\"lang-java-base.md\":\"020e1eda\",\"tools-soft-7zip.md\":\"d1e14adf\",\"tools-soft.md\":\"9c9a88a3\",\"tools-soft-windows.md\":\"70dfbaa0\",\"tools-soft-markdown.md\":\"6c5314cd\",\"docs_05_devops_01_部署_06_linux_04_linux安装.md\":\"9068ebd9\",\"tools-soft-chrome.md\":\"785c1b29\",\"tools-soft-baidupan.md\":\"d651616f\",\"tools-soft-foxit.md\":\"6d3da41e\",\"tools-soft-cmder.md\":\"b39aed2e\",\"docs_05_devops_01_部署_06_linux_01_linux概述.md\":\"83e5c414\",\"docs_05_devops_01_部署_06_linux_02_linux常用命令.md\":\"f6f08dad\",\"tools-soft-office.md\":\"0dfaede5\",\"tools-soft-potplayer.md\":\"2344cea6\",\"tools-soft-snipaste.md\":\"b65c8145\",\"tools-soft-sublimetext.md\":\"c02c7aaf\",\"tools-soft-typora.md\":\"7c7a2879\",\"tools-soft-tizi.md\":\"70132fe0\",\"tools-soft-xmind.md\":\"165042c6\",\"tools-dev-maven.md\":\"e0a81f73\",\"tools-dev-idea.md\":\"a7daced8\",\"tools-dev-pycharm.md\":\"a24889ff\",\"tools-dev-navicat.md\":\"aad3f952\",\"tools-dev-gradle.md\":\"f91af374\",\"tools-dev-ssh.md\":\"eafa7684\",\"tools-dev-postman.md\":\"4505be9e\",\"tools-dev-jmeter.md\":\"540d7cde\",\"index.md\":\"5d013929\",\"tools-vcs-svn.md\":\"cba08751\",\"tools-vcs-git.md\":\"f375211f\",\"docs_05_devops_01_部署_06_linux_03_linux下shell篇.md\":\"5e45709e\",\"devops-deploy-tomcat.md\":\"53274c1f\",\"devops-deploy-lvs.md\":\"cf468b1a\",\"devops-deploy-nginx.md\":\"775aaeab\",\"tools-dev-vmware.md\":\"7bae1f2d\",\"markdown-examples.md\":\"6e41634c\",\"tools-vcs-gitflow.md\":\"aaed74fe\",\"tools-dev-nvm.md\":\"c458444c\",\"tools-vcs-gitee.md\":\"6c9a7eac\",\"tools-vcs-github.md\":\"632499ef\",\"tools-vcs-gitlib.md\":\"39b34382\",\"tools-soft-nodepad.md\":\"3760c1d7\",\"tools-vcs-gogs.md\":\"13159221\",\"tools-soft-evernote.md\":\"83c52166\",\"tools-vcs.md\":\"9f934182\",\"tools-soft-calibre.md\":\"70835893\",\"devops-deploy-shell.md\":\"977c5588\",\"tools-dev-vscode.md\":\"560399f9\",\"devops-deploy-openresty.md\":\"316dd579\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"zh-CN\",\"dir\":\"ltr\",\"title\":\"Coder\",\"titleTemplate\":\"广度和深度\",\"description\":\"整理和记录代码学习的笔记\",\"base\":\"/\",\"head\":[],\"appearance\":\"dark\",\"themeConfig\":{\"logo\":\"./logo.jpg\",\"siteTitle\":\"Coder\",\"outline\":[2,3],\"outlineTitle\":\"目录\",\"search\":{\"provider\":\"local\"},\"darkModeSwitchLabel\":\"深浅模式\",\"sidebarMenuLabel\":\"菜单\",\"returnToTopLabel\":\"返回顶部\",\"lastUpdatedText\":\"上次更新\",\"docFooter\":{\"prev\":\"上一篇\",\"next\":\"下一篇\"},\"nav\":[{\"text\":\"♎语言\",\"items\":[{\"text\":\"1️⃣ Java\",\"link\":\"lang-java\"},{\"text\":\"2️⃣ Python\",\"link\":\"lang-python\"},{\"text\":\"3️⃣ Scala\",\"link\":\"lang-scala\"},{\"text\":\"4️⃣ Groovy\",\"link\":\"lang-groovy\"}]},{\"text\":\"☯️算法\",\"items\":[{\"text\":\"算法篇\",\"items\":[{\"text\":\"🚫代码规范\",\"link\":\"/#\"},{\"text\":\"🚫设计模式\",\"link\":\"/#\"},{\"text\":\"🚫数据结构\",\"link\":\"/#\"},{\"text\":\"🚫源码解读\",\"link\":\"/#\"}]},{\"text\":\"并发篇\",\"items\":[{\"text\":\"🚫JVM\",\"link\":\"/#\"},{\"text\":\"🚫并发编程\",\"link\":\"/#\"}]},{\"text\":\"设计篇\",\"items\":[{\"text\":\"🚫系统设计\",\"link\":\"/#\"},{\"text\":\"🚫数仓理论\",\"link\":\"/#\"}]},{\"text\":\"职业篇\",\"items\":[{\"text\":\"🚫方向导航\",\"link\":\"/#\"},{\"text\":\"🚫职业规划\",\"link\":\"/#\"},{\"text\":\"🚫面试准备\",\"link\":\"/#\"}]}]},{\"text\":\"♈前端\",\"items\":[{\"text\":\"🚫HTML\",\"link\":\"/#\"},{\"text\":\"🚫CSS\",\"link\":\"/#\"},{\"text\":\"🚫JavaScript\",\"link\":\"/#\"},{\"text\":\"🚫JQuery\",\"link\":\"/#\"},{\"text\":\"🚫NodeJS\",\"link\":\"/#\"},{\"text\":\"🚫Vue\",\"link\":\"/#\"},{\"text\":\"🚫React\",\"link\":\"/#\"},{\"text\":\"🚫小程序\",\"link\":\"/#\"}]},{\"text\":\"🔯微服务\",\"items\":[{\"text\":\"🚫RPC\",\"link\":\"/#\"},{\"text\":\"🚫Spring\",\"link\":\"/#\"},{\"text\":\"🚫Spring MVC\",\"link\":\"/#\"},{\"text\":\"🚫Spring Boot\",\"link\":\"/#\"},{\"text\":\"🚫Spring Cloud\",\"link\":\"/#\"},{\"text\":\"🚫Spring Cloud Alibaba\",\"link\":\"/#\"},{\"text\":\"🚫Service Mesh\",\"link\":\"/#\"}]},{\"text\":\"⚧️数据存储\",\"items\":[{\"text\":\"SQL数据库\",\"items\":[{\"text\":\"🚫MySQL\",\"link\":\"/#\"},{\"text\":\"🚫Oracle\",\"link\":\"/#\"}]},{\"text\":\"NoSQL数据库\",\"items\":[{\"text\":\"🚫Redis\",\"link\":\"/#\"},{\"text\":\"🚫MongoDB\",\"link\":\"/#\"}]},{\"text\":\"NewSQL数据库\",\"items\":[{\"text\":\"🚫TiDB\",\"link\":\"/#\"}]},{\"text\":\"ORM框架\",\"items\":[{\"text\":\"🚫Mybatis\",\"link\":\"/#\"},{\"text\":\"🚫Mybatis Plus\",\"link\":\"/#\"},{\"text\":\"🚫Spring Data JPA\",\"link\":\"/#\"}]},{\"text\":\"消息中间件\",\"items\":[{\"text\":\"🚫Active MQ\",\"link\":\"/#\"},{\"text\":\"🚫RabbitMQ\",\"link\":\"/#\"},{\"text\":\"🚫RocketMQ\",\"link\":\"/#\"},{\"text\":\"🚫Kafka\",\"link\":\"/#\"}]},{\"text\":\"文件存储\",\"items\":[{\"text\":\"🚫FastDFS\",\"link\":\"/#\"},{\"text\":\"🚫Ceph\",\"link\":\"/#\"},{\"text\":\"🚫HDFS\",\"link\":\"/#\"}]},{\"text\":\"搜索引擎\",\"items\":[{\"text\":\"🚫Lucene\",\"link\":\"/#\"},{\"text\":\"🚫Solr\",\"link\":\"/#\"},{\"text\":\"🚫ElasticSearch\",\"link\":\"/#\"}]}]},{\"text\":\"☸️DevOps\",\"items\":[{\"text\":\"部署\",\"items\":[{\"text\":\"Tomcat\",\"link\":\"devops-deploy-tomcat\"},{\"text\":\"🚫Linux\",\"link\":\"devops-deploy-tomcat\"},{\"text\":\"Shell\",\"link\":\"devops-deploy-shell\"},{\"text\":\"🚫Nginx\",\"link\":\"devops-deploy-tomcat\"},{\"text\":\"🚫Linux\",\"link\":\"devops-deploy-tomcat\"},{\"text\":\"🚫LVS+Keepalived\",\"link\":\"devops-deploy-tomcat\"},{\"text\":\"🚫OpenResty+Kong\",\"link\":\"devops-deploy-tomcat\"}]},{\"text\":\"容器\",\"items\":[{\"text\":\"🚫Docker\",\"link\":\"/#\"},{\"text\":\"🚫Kubernates\",\"link\":\"/#\"}]},{\"text\":\"云服务器\",\"items\":[{\"text\":\"🚫IaaS\",\"link\":\"/#\"},{\"text\":\"🚫UCloud\",\"link\":\"/#\"}]},{\"text\":\"持续集成\",\"items\":[{\"text\":\"🚫Jenkins\",\"link\":\"/#\"}]},{\"text\":\"监控工具\",\"items\":[{\"text\":\"🚫Arthas\",\"link\":\"/#\"},{\"text\":\"🚫Zabbix\",\"link\":\"/#\"}]},{\"text\":\"链路追踪\",\"items\":[{\"text\":\"🚫Sleuth+Zipkin\",\"link\":\"/#\"},{\"text\":\"🚫Skywalking\",\"link\":\"/#\"}]},{\"text\":\"性能压测\",\"items\":[{\"text\":\"🚫JMeter\",\"link\":\"/#\"},{\"text\":\"🚫全链路压测\",\"link\":\"/#\"}]}]},{\"text\":\"✝️工具\",\"items\":[{\"text\":\"软性办公工具\",\"link\":\"tools-soft\"},{\"text\":\"版本控制工具\",\"link\":\"tools-vcs\"},{\"text\":\"包管理工具\",\"link\":\"tools-dev\"},{\"text\":\"项目构建工具\",\"link\":\"tools-dev\"},{\"text\":\"编程工具\",\"link\":\"tools-dev\"},{\"text\":\"数据库管理\",\"link\":\"tools-dev\"},{\"text\":\"虚拟机工具\",\"link\":\"tools-dev\"},{\"text\":\"SSH工具\",\"link\":\"tools-dev\"},{\"text\":\"调试工具\",\"link\":\"tools-dev\"},{\"text\":\"压测工具\",\"link\":\"tools-dev\"}]}],\"sidebar\":{\"lang-java\":[{\"text\":\"01_Java\",\"collapsed\":false,\"base\":\"lang-java-\",\"items\":[{\"text\":\"基础语法\",\"link\":\"base.md\"},{\"text\":\"数组\",\"collapsed\":true,\"items\":[{\"text\":\"数组入门\",\"link\":\"02_数组.md\"},{\"text\":\"数组进阶\",\"link\":\"02_数组.md\"},{\"text\":\"数组高级\",\"link\":\"02_数组.md\"}]}]}],\"devops\":[{\"text\":\"部署\",\"collapsed\":true,\"base\":\"devops-deploy-\",\"items\":[{\"text\":\"Tomcat\",\"link\":\"tomcat.md\"},{\"text\":\"Shell\",\"link\":\"shell.md\"},{\"text\":\"LVS\",\"link\":\"lvs.md\"},{\"text\":\"Nginx\",\"link\":\"nginx.md\"},{\"text\":\"OpenResty\",\"link\":\"openresty.md\"},{\"text\":\"Evernote\",\"link\":\"evernote.md\"}]}],\"tools\":[{\"text\":\"软性办公\",\"collapsed\":true,\"base\":\"tools-soft-\",\"items\":[{\"text\":\"百度网盘\",\"link\":\"baidupan.md\"},{\"text\":\"福昕阅读器\",\"link\":\"foxit.md\"},{\"text\":\"Calibre\",\"link\":\"calibre.md\"},{\"text\":\"Chrome\",\"link\":\"chrome.md\"},{\"text\":\"Cmder\",\"link\":\"cmder.md\"},{\"text\":\"Evernote\",\"link\":\"evernote.md\"},{\"text\":\"Nodepad\",\"link\":\"nodepad.md\"},{\"text\":\"Office\",\"link\":\"office.md\"},{\"text\":\"PotPlayer\",\"link\":\"potplayer.md\"},{\"text\":\"Snipaste\",\"link\":\"snipaste.md\"},{\"text\":\"SublimeText\",\"link\":\"sublimetext.md\"},{\"text\":\"Typora\",\"link\":\"typora.md\"},{\"text\":\"科学上网\",\"link\":\"tizi.md\"},{\"text\":\"Xmind\",\"link\":\"xmind.md\"},{\"text\":\"7zip\",\"link\":\"7zip.md\"},{\"text\":\"Windows\",\"link\":\"windows.md\"},{\"text\":\"Markdown\",\"link\":\"markdown.md\"}]},{\"text\":\"版本管理\",\"collapsed\":true,\"base\":\"tools-vcs-\",\"items\":[{\"text\":\"Git\",\"collapsed\":true,\"items\":[{\"text\":\"Git\",\"link\":\"git.md\"},{\"text\":\"Gogs\",\"link\":\"gogs.md\"},{\"text\":\"Gitee\",\"link\":\"gitee.md\"},{\"text\":\"Github\",\"link\":\"github.md\"},{\"text\":\"GitLib\",\"link\":\"gitlib.md\"},{\"text\":\"GitFlow\",\"link\":\"gitflow.md\"}]},{\"text\":\"Svn\",\"link\":\"svn.md\"}]},{\"text\":\"包管理工具\",\"collapsed\":true,\"base\":\"tools-dev-\",\"items\":[{\"text\":\"NVM\",\"link\":\"nvm.md\"}]},{\"text\":\"项目构建\",\"collapsed\":true,\"base\":\"tools-dev-\",\"items\":[{\"text\":\"Maven\",\"link\":\"maven.md\"},{\"text\":\"Gradle\",\"link\":\"gradle.md\"}]},{\"text\":\"编程工具\",\"collapsed\":true,\"base\":\"tools-dev-\",\"items\":[{\"text\":\"IDEA\",\"link\":\"idea.md\"},{\"text\":\"VsCode\",\"link\":\"vscode.md\"},{\"text\":\"PyCharm\",\"link\":\"pycharm.md\"}]},{\"text\":\"数据库管理\",\"collapsed\":true,\"base\":\"tools-dev-\",\"items\":[{\"text\":\"Navicat\",\"link\":\"navicat.md\"}]},{\"text\":\"虚拟机工具\",\"collapsed\":true,\"base\":\"tools-dev-\",\"items\":[{\"text\":\"VMware\",\"link\":\"vmware.md\"}]},{\"text\":\"SSH工具\",\"collapsed\":true,\"base\":\"tools-dev-\",\"items\":[{\"text\":\"SSH工具\",\"link\":\"ssh.md\"}]},{\"text\":\"调试工具\",\"collapsed\":true,\"base\":\"tools-dev-\",\"items\":[{\"text\":\"Postman\",\"link\":\"postman.md\"}]},{\"text\":\"压测工具\",\"collapsed\":true,\"base\":\"tools-dev-\",\"items\":[{\"text\":\"JMeter\",\"link\":\"jmeter.md\"}]}]}},\"locales\":{},\"scrollOffset\":90,\"cleanUrls\":false}");</script>
</body>
</html>