forked from wkevin/GitChat
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgitchat.html
More file actions
2319 lines (2182 loc) · 126 KB
/
gitchat.html
File metadata and controls
2319 lines (2182 loc) · 126 KB
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html><html><head><meta charset="utf-8"><style>/* RESET
=============================================================================*/
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
}
/* BODY
=============================================================================*/
body {
font-family: Source Han Sans CN, Helvetica, arial, freesans, clean, sans-serif;
font-size: 14px;
line-height: 1.6;
color: #333;
background-color: #fff;
padding: 20px;
max-width: 900px;
margin: 0 auto;
}
body>*:first-child {
margin-top: 0 !important;
}
body>*:last-child {
margin-bottom: 0 !important;
}
/* BLOCKS
=============================================================================*/
p, blockquote, ul, ol, dl, table, pre {
margin: 15px 0;
}
/* HEADERS
=============================================================================*/
h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
font-size: inherit;
}
h1, h2, h3, h4, h5, h6 {
/*margin: 0px 0px 0px 0px;*/
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
}
h1 {
/*border-bottom: 3px solid #ccc;*/
/*border-top: 1px solid #ccc;*/
background-color: #AEDD81;
padding: 10px 0px 10px 0px;
font-size: 28px;
color: #000;
text-align: center;
}
h2 {
background-color: #B2C8BB;
padding: 5px 0px 5px 10px;
font-size: 24px;
color: #000;
}
h3 {
background-color: #99ccff;
padding: 5px 0px 5px 20px;
font-size: 18px;
color: #000;
}
h4 {
font-size: 16px;
}
h5 {
font-size: 14px;
}
h6 {
color: #777;
font-size: 14px;
}
body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
margin-top: 0;
padding-top: 0;
}
a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0;
}
h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
margin-top: 10px;
}
/* LINKS
=============================================================================*/
a {
color: #4183C4;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* LISTS
=============================================================================*/
ul, ol {
padding-left: 30px;
}
ul li > :first-child,
ol li > :first-child,
ul li ul:first-of-type,
ol li ol:first-of-type,
ul li ol:first-of-type,
ol li ul:first-of-type {
margin-top: 0px;
}
ul ul, ul ol, ol ol, ol ul {
margin-bottom: 0;
}
dl {
padding: 0;
}
dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px;
}
dl dt:first-child {
padding: 0;
}
dl dt>:first-child {
margin-top: 0px;
}
dl dt>:last-child {
margin-bottom: 0px;
}
dl dd {
margin: 0 0 15px;
padding: 0 15px;
}
dl dd>:first-child {
margin-top: 0px;
}
dl dd>:last-child {
margin-bottom: 0px;
}
/* CODE
=============================================================================*/
pre, code, tt {
font-size: 13px;
font-family: Consolas, "Liberation Mono", Courier, monospace;
font-weight: bold;
}
pre {
background-color: #1a181f;
border: 1px solid #ccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
font-weight: normal;
}
pre code, pre tt {
color: #00ff00;
background-color: transparent;
border: none;
}
pre code.cmd {
color: #ffff00;
background-color: transparent;
border: none;
}
kbd {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #DDDDDD;
background-image: linear-gradient(#F1F1F1, #DDDDDD);
background-repeat: repeat-x;
border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
border-image: none;
border-radius: 2px 2px 2px 2px;
border-style: solid;
border-width: 1px;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
line-height: 10px;
padding: 1px 4px;
}
/* QUOTES
=============================================================================*/
blockquote {
border-left: 4px solid #DDD;
padding: 0 15px;
color: #777;
}
blockquote>:first-child {
margin-top: 0px;
}
blockquote>:last-child {
margin-bottom: 0px;
}
/* HORIZONTAL RULES
=============================================================================*/
hr {
clear: both;
margin: 15px 0;
height: 0px;
overflow: hidden;
border: none;
background: transparent;
border-bottom: 4px solid #ddd;
padding: 0;
}
/* TABLES
=============================================================================*/
table {
margin: 0 auto;
border-collapse:collapse; /* 关键属性:合并表格内外边框(其实表格边框有2px,外面1px,里面还有1px哦) */
border:solid #999; /* 设置边框属性;样式(solid=实线)、颜色(#999=灰) */
border-width:1px 0 0 1px; /* 设置边框状粗细:上 右 下 左 = 对应:1px 0 0 1px */
}
table th {
font-weight: bold;
}
table th, table td {
border: 1px solid #ccc;
padding: 6px 13px;
}
table tr {
border-top: 1px solid #ccc;
background-color: #fff;
}
/* IMAGES
=============================================================================*/
img {
max-width: 95%;
clear: both;
display: block;
margin:auto;
margin-top:5px;
margin-bottom:30px;
/*
border-top:1px solid #ccc;
border-right:1px solid #666;
border-bottom:2px solid #999;
border-left:1px solid #ccc;
padding: 4px;
*/
}
.alignleft {
display: inline;
float: left;
}
.alignright {
display: inline;
float: right;
}
.aligncenter {
clear: both;
display: block;
margin:auto;
}
</style><title>gitchat</title></head><body><article class="markdown-body"><h1>Git 聊天入门</h1>
<p><strong>序</strong></p>
<p>读一本Git的书和读一篇Git的文章给人的知识含量是不同的,但给人的愉悦感也是迥异的。本文不想让您有读书的感觉、不追求知识全面、架构完整,但也不想只罗列一些git的知识点,搞的像一个Tip集。本文会从实际使用的角度,以聊天问答的形式,从浅入深,逐步展露git的若干方面。</p>
<p>本文分Round进行,每局并不以git命令的逻辑来分类,而是以<strong>使用git完成任务的水平来分解阶段</strong>。一些问题原本来自于我和朋友们的聊天,闲聊之余,记录成集,不要期待有什么高深的理论,让你每读完一个Round,可以小试牛刀,然后烹茶小饮、若有所思……是我最想要的。</p>
<p>git 有自己的 <a href="https://www.kernel.org/pub/software/scm/git/docs/user-manual.html">user manunal</a>,和官方宝书(<a href="http://git-scm.com/book/en/v2">英文版</a>、<a href="http://git-scm.com/book/zh/v2">中文版</a>、<a href="http://www.kancloud.cn/kancloud/progit">国内备份</a>),如果你读来无碍,请忽视本文,本文与它们相比只是个小人书、连环画,或者作为它们的一个补充。我在写每个Topic的时候也都在想:是不是书里已经有了?我是不是重复了?是不是删掉算了?—— 经常在知识点完整和拾遗之间反复权衡,但想到碎片化阅读越来越普及、学东西主要靠百度的今天,我写点东西发出来应该也是有益的。</p>
<hr />
<!-- MarkdownTOC depth=2 -->
<ul>
<li><a href="#round-1">Round 1 : 起步</a><ul>
<li><a href="#git">git在哪里</a></li>
<li><a href="#git-for-windows">Git for Windows 咋用</a></li>
<li><a href="#git_1">先单机玩玩还是先弄来个别人的git库</a></li>
<li><a href="#git_2">如何在本机git我的日记</a></li>
</ul>
</li>
<li><a href="#round-2">Round 2 : 优雅</a><ul>
<li><a href="#addcommitstatus">每次都要敲add、commit、status,嫌累了</a></li>
<li><a href="#git_3">有些文件不希望被git管理</a></li>
<li><a href="#git-log">我要筛选 git log</a></li>
<li><a href="#git-log_1">觉得 git log 中的时间看着困难,精简下呗</a></li>
<li><a href="#git-log_2">我要定制 git log,不想一页看不了几条</a></li>
<li><a href="#onelinehashauthordatemessage">oneline太简陋了,我想一行里面看到hash、author、date、message</a></li>
<li><a href="#git-log_3">git log 已经很好了,但好像还是缺点啥</a></li>
<li><a href="#git-log-fuller-author-commit">git log –fuller 中的 author 和 commit 啥关系</a></li>
<li><a href="#log">看log的时候能否把修改了哪些文件也列出来</a></li>
<li><a href="#tortoisesvndiff">我要能像TortoiseSVN那样左右两栏对比看diff</a></li>
<li><a href="#git-add">修改完了为什么不是直接提交,而是git add</a></li>
<li><a href="#ubuntugit-commit">我用ubuntu,我要修改git commit时的默认编辑器</a></li>
</ul>
</li>
<li><a href="#round-3">Round 3 : 并发</a><ul>
<li><a href="#branch">我想使用个分支(branch),怎么做</a></li>
<li><a href="#_1">如何在分支间来回切换</a></li>
<li><a href="#git-branch-delete">删除分支总是想用git branch delete</a></li>
<li><a href="#git-merge">分支的合并(git merge)有哪几种场景</a></li>
<li><a href="#log_1">合并时如何处理分支中的“垃圾”log</a></li>
<li><a href="#_2">“把特性分支合入主干”和“把主干合入特性分支”有什么区别</a></li>
<li><a href="#git-merge_1">git merge 有没有图形化的工具</a></li>
<li><a href="#git_4">git分支之间的关系能否图示</a></li>
</ul>
</li>
<li><a href="#round-4">Round 4 : 协作</a><ul>
<li><a href="#git_5">想看看别人的git库了</a></li>
<li><a href="#_3">到哪里找开源项目</a></li>
<li><a href="#github">为什么github成了程序员的麦加圣地</a></li>
<li><a href="#proxygithub">公司内如何穿过Proxy访问github</a></li>
<li><a href="#remoteproxy">定义了外网和内网两个remote,proxy怎么同时支持</a></li>
<li><a href="#sshremote">SSH访问remote的通常步骤是啥</a></li>
<li><a href="#_4">如何与别人合作</a></li>
<li><a href="#github_1">如何在github上与别人合作</a></li>
<li><a href="#git_6">怎样才能第一时间得知git上有提交和更新</a></li>
<li><a href="#git-pullgit-fetch-git-merge">为什么说不要用git pull,而是用git fetch + git merge代替</a></li>
<li><a href="#clonefetchremote-repolog">如何不clone/fetch到本地看remote repo的log?</a></li>
<li><a href="#commitpush">程序猿如何频繁地commit,但又低调地push</a></li>
<li><a href="#http-pushnamepassword">通过http push时每次都要求输入name/password,能否避开</a></li>
<li><a href="#_5">如何删除远程分支</a></li>
<li><a href="#tag">如何删除远程tag</a></li>
<li><a href="#_6">别人把远程分支删除了,我本地的对应分支怎么还在</a></li>
<li><a href="#_7">维持树的整洁</a></li>
<li><a href="#git_7">Git多用户间协作还有什么引人入胜之处</a></li>
</ul>
</li>
<li><a href="#round-5">Round 5 : 整理</a><ul>
<li><a href="#git_8">git从何而来</a></li>
<li><a href="#git_9">git去往何处</a></li>
<li><a href="#git_10">git有哪些好的入门的资料</a></li>
<li><a href="#git_11">git命令我掌握的七七八八了,怎么整理一下</a></li>
<li><a href="#git_12">重新梳理git的软件</a></li>
<li><a href="#git_13">整理git的外网托管网站</a></li>
</ul>
</li>
<li><a href="#round-6">Round 6 : 奇技淫巧</a><ul>
<li><a href="#committag">从当前库中快速导出一个节点(commit、tag)另作他用</a></li>
<li><a href="#logrepo">导出某个子目录及其log成为一个新的repo</a></li>
<li><a href="#2bug1commit">分支2需改bug,但我正在分支1上编码并不想commit怎么办</a></li>
<li><a href="#git-add_1">git add错了,我要丢弃暂存区的修改</a></li>
<li><a href="#modify">modify 错了,我要丢弃本地目录中的修改</a></li>
<li><a href="#git-commitcommit">git commit错了,我要丢弃某个commit节点</a></li>
<li><a href="#_8">暂存一个文件的部分改动</a></li>
<li><a href="#_9">能否从不同的分支里选择某次提交并且把它合并到当前的分支</a></li>
</ul>
</li>
<li><a href="#round-7">Round 7 : 原理拾趣</a><ul>
<li><a href="#gitsvn">git和SVN在元数据存储上有什么区别</a></li>
<li><a href="#git-object">git 的对象(object)</a></li>
<li><a href="#git_14">git 的快照存储有点不可思议,如何做到好又多的</a></li>
<li><a href="#git-addcommit">git add/commit 原理图</a></li>
<li><a href="#git-checkout">git checkout 原理图</a></li>
<li><a href="#git-fetchpull">git fetch/pull 原理图</a></li>
<li><a href="#git-reset">git reset 原理图</a></li>
</ul>
</li>
<li><a href="#round-8-gitphabricator">Round 8 : git与phabricator</a><ul>
<li><a href="#arc">arc 为何物</a></li>
<li><a href="#arc_1">arc的安装和配置</a></li>
<li><a href="#arc-diff">arc diff 初步</a></li>
<li><a href="#arc-diff-commit-log">arc diff 为什么把我已有的commit log修改了</a></li>
<li><a href="#arc-diff_1">如何避免arc diff玷污现有节点</a></li>
<li><a href="#_10">如何创建只包含部分文件的评审单</a></li>
</ul>
</li>
</ul>
<!-- /MarkdownTOC -->
<hr />
<h1 id="round-1"><a name="user-content-round-1" href="#round-1" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>Round 1 : 起步</h1>
<p><img alt="" src="img/run-buffalo.jpg" /></p>
<h2 id="git"><a name="user-content-git" href="#git" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>git在哪里</h2>
<ul>
<li>Unix系(Ubuntu/Fedora/macOS/……)默认就有,打开terminal,输入<code>git --version</code>,就在那里了</li>
<li>Windows上要安装:<a href="https://github.com/git-for-windows/git">Git for Windows</a></li>
</ul>
<h2 id="git-for-windows"><a name="user-content-git-for-windows" href="#git-for-windows" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>Git for Windows 咋用</h2>
<p>一路“下一步”安装完即可。</p>
<p><img alt="" src="img/git4windows-install.png" /></p>
<ol>
<li>Git Bash: Linux 风格的命令行,如: /user/bin</li>
<li>Git CMD: Windows风格的命令行,即:C:\system</li>
<li>Git GUI: 图形化界面</li>
<li>其实还有一个: ${安装目录}/bin/sh.exe —— 我喜欢直接用这个</li>
</ol>
<p><img alt="" src="img/git4windows-sh.png" /></p>
<p>对比一下1和4:</p>
<p><img alt="" src="img/git4windows-gitbash.png" /><br />
<img alt="" src="img/git4windows-bin.png" /></p>
<ul>
<li>1和4的图标不同,4其实是Windows自身的cmd窗口</li>
<li>4由于是Windows自身cmd窗口,所以对中文支持较好</li>
</ul>
<p>所以建议您直接用4:<strong>直接双击或在cmd中打开 ${安装目录}/bin/sh.exe 来运行MinGW环境和git</strong></p>
<h2 id="git_1"><a name="user-content-git_1" href="#git_1" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>先单机玩玩还是先弄来个别人的git库</h2>
<p>先单机玩玩吧,理由如下:</p>
<p>git 和 svn 最大的区别:</p>
<ul>
<li>svn是集中式管控:所有库(repo)的内容都在server上,离了server连 svn log 都看不了,更别说提交代码了</li>
<li>git是分布式管控:每个git项目里面的.git文件夹中都包括了所有的库(repo)内容,可以看log、提交代码、创建分支、打tag……<ul>
<li>两台电脑的git库之间是<strong>同步(sync)</strong>的概念,大家都是平等的</li>
</ul>
</li>
</ul>
<p>所以说我们还是先练习一下除了sync之外的基础命令吧,会了这些之后,至少你能在本机快乐的写日记了。</p>
<blockquote>
<p>我看到有些小伙伴还在用类似EDiary等日记本软件或PIM软件来写每天的日记,积累了这么多年的日记,一旦win10上运行不了EDiary可咋整?还是赶紧试试用纯文本+Markdown来写日记,用git本地做版本管理吧!</p>
</blockquote>
<p>下文我使用个人日记的小项目来演示本机的git操作</p>
<h2 id="git_2"><a name="user-content-git_2" href="#git_2" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>如何在本机git我的日记</h2>
<p>OK,让我们从头开始,跟着做一遍吧,Good Luck ……</p>
<ul>
<li>做一下git要求的最基本的两个配置:name 和 email<br />
<pre><code class="cmd">$ git config --global user.name wkevin
$ git config --global user.emal wkevin27@gmail.com
</code></pre></li>
<li>创建一个文件夹并写一篇日记<br />
<pre><code class="cmd">MBP:demo wangkevin$ mkdir mydiary
MBP:demo wangkevin$ cd mydiary
$ cat >diary.md
# Diary
## 2016.1.31
回家过年^C
$ ls
diary.md
$ cat diary.md
# Diary
## 2016.1.31
回家过年
</code></pre></li>
<li><code>git init</code>:在文件夹中创建git库<br />
<pre><code class="cmd">$ git init
Initialized empty Git repository in /Users/wangkevin/workspace/kproject/demo/mydiary/.git/
</code></pre></li>
<li>和SVN有.svn类似,git也有.git<br />
<pre><code class="cmd">$ ls -a
. .. .git diary.md
$ ls .git
HEAD config hooks objects
branches description info refs
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
</code></pre></li>
<li><code>git status</code>:显示一个未被管控的文件(Untracked files) diary.md<br />
<pre><code class="cmd">$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
diary.md
nothing added to commit but untracked files present (use "git add" to track)
</code></pre></li>
<li><code>git add filename</code>:将文件纳入管理,filename 支持通配符,最常用的就是点(.)表示所有文件<br />
<pre><code class="cmd">$ git add diary.md
</code></pre></li>
<li><code>git status</code> 显示此文件待提交(to be committed),此时文件已经开始被git管理了,文件进入一种暂存状态(stage),如果想反悔可以用<code>git rm --cached</code>使其进入unstage状态<br />
<pre><code class="cmd">$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: diary.md
</code></pre></li>
<li><code>git status -s</code> -short 短模式<br />
<pre><code class="cmd">$ git status -s
A diary.md
</code></pre></li>
<li><code>git status -b</code> -branch 显示分支,<code>git status</code>不带参数默认就是-b的,所以常和短模式合作,合并为一个sb,哈哈<br />
<pre><code class="cmd">$ git status -sb
## Initial commit on master
A diary.md
</code></pre></li>
<li><code>git commit</code>: 将文件从暂存态提交入库 —— 暂存就像回收站(删除前给你一个check的机会,多次操作放入回收站的文件可以一次清空),多次操作放入暂存,最后考虑成熟了,check OK了,再commit提交<br />
<pre><code class="cmd">$ git commit
aster (root-commit) 14dd781] create mydiary
1 file changed, 4 insertions(+)
create mode 100644 diary.md
</code></pre></li>
<li>执行 <code>git commit</code> 后会自动打开一个编辑器(编辑器是可配置的,以后再说怎么配置),比如 vi,进行提交log的撰写,保存退出即提交成功,不保存退出即放弃提交<br />
<pre><code class="vi"> 1
2 # Please enter the commit message for your changes. Lines starting
3 # with '#' will be ignored, and an empty message aborts the commit.
4 # On branch master
5 #
6 # Initial commit
7 #
8 # Changes to be committed:
9 # new file: diary.md
10 #
</code></pre></li>
<li>再查<code>git status</code>,都已经提交干净了<br />
<pre><code class="cmd">$ git status
On branch master
nothing to commit, working directory clean
$ git status -s
</code></pre></li>
<li>现在可以看log了<br />
<pre><code class="cmd">$ git log
commit 14dd7815fcf56c961e11c52e96e2fc3fbd7d0543
Author: wkevin <wkevin27@gmail.com>
Date: Sun Jan 31 11:39:55 2016 +0800
create mydiary
</code></pre></li>
<li>git 和 svn 不同,没有一个数字递增的节点号,而是一串40Bytes的哈希字符,指定一个提交只需要给出这个字符串即可,当然不能让你每次都把40个字符全输入一遍,只需要输入够区分提交的即可(一般是前7位),如果咱的库规模还很小,前4位也行哦(下文中的“6784”)<br />
<pre><code class="cmd">$ git lg
b81373d | 2016-01-31 15:49:08 +0800 | 2016-01-31 15:49:08 +0800 | wkevin add .gitignore file
67840e1 | 2016-01-31 12:20:26 +0800 | 2016-01-31 12:20:26 +0800 | wkevin 2.2日记
bf36ab9 | 2016-01-31 12:19:33 +0800 | 2016-01-31 12:19:33 +0800 | wkevin 2.1的日记
14dd781 | 2016-01-31 11:39:55 +0800 | 2016-01-31 11:39:55 +0800 | wkevin create mydiary
$ git log 6784
commit 67840e1813af1084abd5d07d2e2a2e185c679f09
Author: wkevin <wkevin27@gmail.com>
Date: Sun Jan 31 12:20:26 2016 +0800
2.2日记
</code></pre></li>
<li>每天可以随时写日记、随时<code>git add</code>、适时<code>git commit</code>,经过一段时间,你的diary库就越来越让你爱不释手了<br />
<pre><code class="cmd">$ git log
commit 67840e1813af1084abd5d07d2e2a2e185c679f09
Author: wkevin <wkevin27@gmail.com>
Date: Sun Jan 31 12:20:26 2016 +0800
2.2日记
commit bf36ab9b0d489a2eda911be9e01bddc395fc29e0
Author: wkevin <wkevin27@gmail.com>
Date: Sun Jan 31 12:19:33 2016 +0800
2.1的日记
commit 14dd7815fcf56c961e11c52e96e2fc3fbd7d0543
Author: wkevin <wkevin27@gmail.com>
Date: Sun Jan 31 11:39:55 2016 +0800
create mydiary
</code></pre></li>
<li>觉得<code>git log</code>默认显示的内容不爽?想看更详细的、或更简略的?——别急,统统没问题,各种参数全方位满足你的各种需求,但这里先不说,后文慢慢来,先不要用这些复杂的参数来打击自己吧,不过来个一步简洁到位的的命令:<code>git shortlog</code> —— 什么?太简洁了?哈哈,别急,从简洁到纸到复杂到翔全都有,慢慢来。<br />
<pre><code class="cmd">$ git shortlog
wkevin (3):
create mydiary
2.1的日记
2.2日记
</code></pre></li>
</ul>
<hr />
<p>如果只是让git管理个<strong>日记本</strong>,自己写、自己看、绝不给别人看、绝不上网……这些命令就差不多够了!</p>
<p>哇!好累啊,可以休息一下了,就这些命令,玩几天,把日记写上一个礼拜,然后我们再继续。如果你不打算继续了,也没关系,这些命令就写日记–够用了!</p>
<p>第一局,Over!</p>
<h1 id="round-2"><a name="user-content-round-2" href="#round-2" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>Round 2 : 优雅</h1>
<p><img alt="" src="img/gray-owl-mouse-sw.jpg" /></p>
<p>欢迎回来,能回来接着读说明你是个积极追求上进的好同学,我们继续聊!</p>
<p>用git写了一些日记,你肯定有了新需求,最令你恼火的可能有:</p>
<ul>
<li>敲命令真烦人,尤其还辣么长的命令</li>
<li>看log真晃眼,不清爽</li>
<li>提交之前还要来个add,啥子意思</li>
</ul>
<h2 id="addcommitstatus"><a name="user-content-addcommitstatus" href="#addcommitstatus" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>每次都要敲add、commit、status,嫌累了</h2>
<p>有这样的问题说明你已经是git的初级用户了,并且听了我的建议:“使用命令行,远离GUI” —— 我一点都不奇怪,绝大部分程序猿一旦用上git都会上瘾的,会频繁的<code>git commit</code>,然后在<code>git log</code>中寻觅自己的成就感,否则吃不好饭、睡不好觉……呵呵</p>
<p>言归正传。</p>
<p>别名(alias)是linux系统的基本概念,在git中也如鱼得水:</p>
<ul>
<li>这样设置别名<br />
<pre><code class="cmd">$ git config --global alias.st "status"
</code></pre></li>
<li>然后就可以这样操作了<br />
<pre><code class="cmd">$ git st
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: diary.md
no changes added to commit (use "git add" and/or "git commit -a")
</code></pre></li>
<li>换个别名玩玩<br />
<pre><code class="cmd">$ git config --global alias.st "status -sb"
$ git st
## master
M diary.md
</code></pre></li>
<li>把让你烦的命令都用2个字来别名一下吧。比如:<br />
<pre><code class="cmd">$ git config --global alias.ci "commit"
</code></pre></li>
</ul>
<h2 id="git_3"><a name="user-content-git_3" href="#git_3" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>有些文件不希望被git管理</h2>
<p>问:markdown写的 diary.md ,会在本地生成 diary.html 检查和欣赏一下,但其实是不需要 commit 的,如何在 <code>git commit</code> 的时候忽略它们。</p>
<p>答:<code>git commit</code>的时候已经不能忽略了,要忽略需要在<code>git add</code>的时候,通过编辑<strong>.gitignore文件</strong>让add命令忽略它们。</p>
<ul>
<li>diary.html 就是我们不想提交的过程文件<br />
<pre><code class="cmd">$ git st
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: diary.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
diary.html
no changes added to commit (use "git add" and/or "git commit -a")
</code></pre></li>
<li>手工生成一个<strong>.gitignore</strong>的文件,写入含有通配符的文件名(即:后缀名为html的文件)<br />
<pre><code class="cmd">$ cat >.gitignore
*.html
^C
$ cat .gitignore
*.html
</code></pre></li>
<li>diary.html 已经被自动忽略。<br />
<pre><code class="cmd">$ git st
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: diary.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
no changes added to commit (use "git add" and/or "git commit -a")
</code></pre></li>
</ul>
<h2 id="git-log"><a name="user-content-git-log" href="#git-log" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>我要筛选 git log</h2>
<ul>
<li>可以只看某个子目录或某个文件的log</li>
<li>可以从某个提交开始看<br />
<pre><code class="cmd">$ git log 6784
commit 67840e1813af1084abd5d07d2e2a2e185c679f09
Author: wkevin <wkevin27@gmail.com>
Date: Sun Jan 31 12:20:26 2016 +0800
2.2日记
</code></pre></li>
<li>可以只看某个人的log<br />
<pre><code class="cmd">$ git log --author=wkevin
commit 67840e1813af1084abd5d07d2e2a2e185c679f09
Author: wkevin <wkevin27@gmail.com>
Date: Sun Jan 31 12:20:26 2016 +0800
2.2日记
……
</code></pre></li>
<li>–author 支持匹配<br />
<pre><code class="cmd">$ git log --author=wke
commit 67840e1813af1084abd5d07d2e2a2e185c679f09
Author: wkevin <wkevin27@gmail.com>
Date: Sun Jan 31 12:20:26 2016 +0800
2.2日记
……
</code></pre></li>
<li>–author 的一个错误匹配<br />
<pre><code class="cmd">$ git log --author=wken
$
</code></pre></li>
<li>–author 上使用通配符<br />
<pre><code class="cmd">$ git log --author=wke.*n
commit 67840e1813af1084abd5d07d2e2a2e185c679f09
Author: wkevin <wkevin27@gmail.com>
Date: Sun Jan 31 12:20:26 2016 +0800
2.2日记
</code></pre></li>
</ul>
<h2 id="git-log_1"><a name="user-content-git-log_1" href="#git-log_1" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>觉得 git log 中的时间看着困难,精简下呗</h2>
<ul>
<li>使用 –date=short<br />
<pre><code class="cmd">$ git log --pretty=medium --date=short
commit 67840e1813af1084abd5d07d2e2a2e185c679f09
Author: wkevin <wkevin27@gmail.com>
Date: 2016-01-31
2.2日记
commit bf36ab9b0d489a2eda911be9e01bddc395fc29e0
Author: wkevin <wkevin27@gmail.com>
Date: 2016-01-31
2.1的日记
commit 14dd7815fcf56c961e11c52e96e2fc3fbd7d0543
Author: wkevin <wkevin27@gmail.com>
Date: 2016-01-31
create mydiary
</code></pre></li>
</ul>
<h2 id="git-log_2"><a name="user-content-git-log_2" href="#git-log_2" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>我要定制 git log,不想一页看不了几条</h2>
<p>默认的<code>git log</code>一条commit log至少需要6行来显示,一页顶多看个5、6条,很不方便。如果单条达到10行的话,一页也就看个2、3条。像linux这样的项目,经常遇到长篇大论的log,内容倒是详实了,但很难做一览表式的查询。</p>
<p>下面我们祭出 git log 的必杀技: –pretty 或 –format</p>
<p><code>git log --pretty=xxx</code> 等价于 <code>git log --format=xxx</code>, xxx 可以是这些:</p>
<ul>
<li>oneline:只显示一行</li>
<li>short</li>
<li>medium</li>
<li>full</li>
<li>fuller:会看到有两个角色:author(作者) 和 commit(提交人)</li>
<li>email</li>
<li>raw</li>
<li>format:’......’</li>
</ul>
<p>其中<code>oneline</code>能够帮你精简log</p>
<pre><code class="cmd">$ git log --pretty=oneline
67840e1813af1084abd5d07d2e2a2e185c679f09 2.2日记
bf36ab9b0d489a2eda911be9e01bddc395fc29e0 2.1的日记
14dd7815fcf56c961e11c52e96e2fc3fbd7d0543 create mydiary
</code></pre>
<p>其实 <code>--oneline</code> 也是一个单独的参数</p>
<pre><code class="cmd">$ git log --oneline
67840e1 2.2日记
bf36ab9 2.1的日记
14dd781 create mydiary
</code></pre>
<h2 id="onelinehashauthordatemessage"><a name="user-content-onelinehashauthordatemessage" href="#onelinehashauthordatemessage" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>oneline太简陋了,我想一行里面看到hash、author、date、message</h2>
<p>那需要用上 –pretty=formate:”......”参数了</p>
<p>format 参数很多,没必要逐一掌握,除了你是强迫症患者 – 凑巧本文不使用强迫症的视角,哈哈</p>
<p>我常用的有:</p>
<ul>
<li>%h:commit hash</li>
<li>%ai: author date</li>
<li>%an: author name</li>
<li>%ci: commit date</li>
<li>%cn: commit name</li>
<li>%s: log message</li>
</ul>
<p>示例:</p>
<ul>
<li>只看日期、作者、log(专业术语是:subject)<br />
<pre><code class="cmd">$ git log --pretty=format:'%ad %an %s'
Sun Jan 31 15:49:08 2016 +0800 wkevin add .gitignore file
Sun Jan 31 12:20:26 2016 +0800 wkevin 2.2日记
Sun Jan 31 12:19:33 2016 +0800 wkevin 2.1的日记
Sun Jan 31 11:39:55 2016 +0800 wkevin create mydiary
</code></pre></li>
<li>日期太碍眼,精简一下<br />
<pre><code class="cmd">$ git log --pretty=format:'%ad %an %s' --date=short
2016-01-31 wkevin add .gitignore file
2016-01-31 wkevin 2.2日记
2016-01-31 wkevin 2.1的日记
2016-01-31 wkevin create mydiary
</code></pre></li>
<li>不好了,但太精简了,咋只有date,没有time<br />
<pre><code class="cmd">$ git log --pretty=format:'%ad %an %s' --date=local
Sun Jan 31 15:49:08 2016 wkevin add .gitignore file
Sun Jan 31 12:20:26 2016 wkevin 2.2日记
Sun Jan 31 12:19:33 2016 wkevin 2.1的日记
Sun Jan 31 11:39:55 2016 wkevin create mydiary
</code></pre></li>
<li>commit hash 最好也能加上<br />
<pre><code class="cmd">$ git log --pretty=format:'%h %ad %an %s' --date=local
b81373d Sun Jan 31 15:49:08 2016 wkevin add .gitignore file
67840e1 Sun Jan 31 12:20:26 2016 wkevin 2.2日记
bf36ab9 Sun Jan 31 12:19:33 2016 wkevin 2.1的日记
14dd781 Sun Jan 31 11:39:55 2016 wkevin create mydiary
</code></pre></li>
</ul>
<p>最后,你还需这样:<br />
<pre><code class="cmd">$ git config --global --replace-all alias.lg "log --pretty=format:'%h %ad %an %s' --date=local"
</code></pre></p>
<h2 id="git-log_3"><a name="user-content-git-log_3" href="#git-log_3" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>git log 已经很好了,但好像还是缺点啥</h2>
<p>那就是颜色了,加上颜色让字段分的更加清晰</p>
<pre><code class="cmd">git config --global --replace-all alias.lg "log --pretty=format:'%C(auto) %h | %ai | %Cred %an %Cgreen %s'"
</code></pre>
<p><img alt="" src="img/git-lg-with-color.png" /></p>
<p>为什么改用<code>%ai</code>,不用<code>%ad</code>了?<br />
<code>%ad</code>会受到<code>--date=xxx</code>的影响,<code>%ai</code>不会。所以限制了<code>%ad</code>的使用,如果常从github上拿代码,会看到世界各地的提交人和提交时间,我还是希望分一下时区的,所以用了<code>%ai</code>。</p>
<p>比如我们来查看linux的源码:</p>
<p><img alt="" src="img/git-lg-by-linux.png" /></p>
<h2 id="git-log-fuller-author-commit"><a name="user-content-git-log-fuller-author-commit" href="#git-log-fuller-author-commit" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>git log –fuller 中的 author 和 commit 啥关系</h2>
<p>必须要说了,git的设计者的设计思路是:希望提交人(执行<code>git commit</code>的人)能够把author写明白,而不是据为己有。所以git的作者(author)和提交人(commit)可以不是同一个人。</p>
<pre><code class="cmd">$ git commit --author=wkevin --date='2016-01-30 22:04:04 +0800'
</code></pre>
<p>上面的命令可以在commit的同时指定提交内容的author和AUTHOR_DATE,这个恐怕要靠提交者(committer)的记忆力和公德心了,把这段代码真实author的名字和写就时间录进去,而不是让git默认的把自己的name和提交时间(COMMITTER_DATE)录入库中。</p>
<p>在没有github之前,一个开源项目通常还是只设置几个有权限的提交人,大家想贡献代码就发patch给有权限的人,然后有权人commit。但自从有了github,发明了fork(fork并不属于git,而是github的独创哦)和PR(Pull-Request),让这个过程更加的轻便,也让项目的发展更加《失控》,有能力的人可以在自己的领地fork并发展一个项目,PR或不PR给原作者全凭个人喜好,原作者如果“懒政”,其他人完全可以独立发展。—— 每个人都在自己的库里commit,使得committer和author通常都是一个人,大家都是通过PR给其他人,而不是发送patch了。—— 所以 <code>--author</code> 这个参数已经很久不用一次了。</p>
<h2 id="log"><a name="user-content-log" href="#log" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>看log的时候能否把修改了哪些文件也列出来</h2>
<pre><code class="cmd">$ git log --stat
</code></pre>
<h2 id="tortoisesvndiff"><a name="user-content-tortoisesvndiff" href="#tortoisesvndiff" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>我要能像TortoiseSVN那样左右两栏对比看diff</h2>
<p>这个必须有!</p>
<blockquote>
<p>git和TortoiseSVN相比是不恰当的,git要和subversion比较,它们两个是协议;TortoiseGit才是和TortoiseSVN比较,这两个是前端。Subversion的前端并不多,除了TortoiseSVN并没有更多的选择,git的前端却不少:TortoiseGit、GitForWindows、Github for Desktop……</p>
<p>前端对协议进行了封装(比如默认安装的TortoiseSVN都已经找不到<code>svn</code>等命令,所以也不能运行<code>svn log</code>、<code>svn commit</code>)和更多的图形化工作(图标重绘、文本比较工具……)的事情留在后面慢慢说,回到比较工具上来:除非你是要制作补丁包,或者改动很小,否则你几乎不会想直接查看<code>git diff</code>,配置好第三方比较工具的调用方法是必须要做的 —— 这个懒偷不得。</p>
<p>git 调用第三方工具是灵活的,当然TortoiseSVN调用第三方diff/Merge工具也是可定制的,并且用户不指定第三方工具的话,TortoiseSVN项目自己做了一个比较工具TortoiseMerge来作为默认,TortoiseGit也是有默认的。git则需要手工设置。</p>
</blockquote>
<p><strong>git中查看差异有两个命令</strong>:</p>
<ol>
<li><code>git diff</code>: 在Terminal中按照Linux的传统方式生成patch<br />
<img alt="" src="img/git-diff.png" /></li>
<li><code>git difftool</code>: 使用第三方工具显示差异<br />
<img alt="" src="img/git-difftool-merge.png" /> </li>
</ol>
<p><code>git difftool</code> 命令能够调用的第三方比较工具有很多,列几个本人用过的:</p>
<ul>
<li>收费的<ul>
<li><a href="http://www.scootersoftware.com">Beyond Compare</a> – Win、Linux、macOS</li>
<li><a href="http://www.araxis.com">Araxis Merge</a> – Win、macOS</li>
<li><a href="http://www.ultraedit.com/products/ultracompare.html">UltraCompare</a> – Win,本来是UE的一个插件,近几年独立出来了</li>
</ul>
</li>
<li>免费但不开源的<ul>
<li><a href="http://www.sourcegear.com/diffmerge/downloads.php">DiffMerge</a> – Win、Linux、macOS</li>
</ul>
</li>
<li>开源的:<ul>
<li><a href="http://meldmerge.org">Meld</a> – Win、Linxu、macOS</li>
</ul>
</li>
</ul>
<p>用哪个呢?这是萝卜白菜的事情,不要纠结,你用惯了哪个就是哪个(我相信你的电脑上肯定已经有了一个文本比较工具,用它就是了,本着开放、开源、和跨平台的原则,我个人推荐Meld)。git调用它们的方法配置是大同小异。我不能每种软件在每个系统中都试一遍,所以只能条目列在这里,但我本人没搞过的就空着了,看官自己百度一下吧,照葫芦画瓢能力强的话也用不着百度。</p>
<ul>
<li><strong>Araxis Merge</strong><ul>
<li>macOS: <code>vi ~/.gitconfig</code>,加入:<br />
<pre><code>difftool.prompt=false
diff.tool=araxis
merge.tool=araxis
mergetool.araxis.path=/Applications/Araxis Merge.app/Contents/Utilities/compare
difftool.araxis.path=/Applications/Araxis Merge.app/Contents/Utilities/compare
</code></pre></li>
<li>Linux</li>
<li>Windows</li>
</ul>
</li>
<li><strong>BeyondCompare</strong><ul>
<li>macOS</li>
<li>Linux</li>
<li>Windows<br />
<pre><code class="cmd">$ git config --global diff.tool bc3
$ git config --global difftool.bc3.path "c:/program files/beyond compare 3/bcomp.exe"
</code></pre></li>
</ul>
</li>
<li><strong>DiffMerge</strong><ul>
<li>macOS</li>
<li>Linux</li>
<li>Windows<br />
<pre><code class="cmd">$ git config --global diff.tool diffmerge
$ git config --global difftool.diffmerge.cmd 'diffmerge "$LOCAL" "$REMOTE"'
</code></pre></li>
</ul>
</li>
<li><strong>Meld</strong><ul>
<li>macOS</li>
<li>Linux</li>
<li>Windows</li>
</ul>
</li>
</ul>
<p>除此之外,还可以配置一项:</p>
<pre><code class="cmd">$ git config --global difftool.prompt false
</code></pre>
<p>OK,弄好了吧,我们来总结一下其知识点,如果不想看,可以跳过去看下条了。</p>
<ul>
<li>配置方法两种:<ol>
<li>通过 <code>git config ...</code> 命令</li>
<li>通过 <code>vi ~/.gitconfig</code> 直接修改git的配置文件,方法1最终也是落实到2上</li>
</ol>
</li>
<li>配置命令有两个:<ol>
<li>cmd:git在执行某个difftool的时候,执行的命令,用户没有定义的话,会使用tool的名字做默认启动;如果用户定义的话,就必须加上 $LOCAL $REMOTE</li>
<li>path: 用于定位不在PATH变量里的命令,但不需要加 $LOCAL $REMOTE</li>
</ol>
</li>
</ul>
<p>肯定还是有些完美主义者,一台电脑上安装了多个比较软件,想要不断切换 —— 也是没问题的。</p>
<ul>
<li>可以配置多个cmd<br />
<pre><code class="cmd">$ git config --global difftool.bc.cmd 'beyondcompare "$LOCAL" "$REMOTE"'
$ git config --global difftool.am.cmd 'araxismerge "$LOCAL" "$REMOTE"'
$ git config --global difftool.dm.cmd 'diffmerge "$LOCAL" "$REMOTE"'
</code></pre></li>
<li>根据需求随时切换<br />
<pre><code class="cmd">$ git config --global diff.tool bc
</code></pre><br />
或<br />
<pre><code class="cmd">$ git config --global diff.tool am
</code></pre><br />
或<br />
<pre><code class="cmd">$ git config --global diff.tool dm
</code></pre></li>
</ul>
<h2 id="git-add"><a name="user-content-git-add" href="#git-add" class="headeranchor-link" aria-hidden="true"><span class="headeranchor"></span></a>修改完了为什么不是直接提交,而是git add</h2>
<p>git在 <code>git commit</code> 之前首先要 <code>git add</code>,从svn转移过来的同学会对这点有一些疑惑和质疑。</p>
<p><code>git add</code> 将文件放入到暂存区(stage),并生成对象 —— 参见本文的 <a href="#git-object">git 的对象(object)</a></p>
<p>理解git需要理解文件的5种状态和3个区(area):</p>
<p>5种状态:</p>
<ol>
<li>未跟踪态(untracked)</li>
<li>未修改状态(unmodified)</li>
<li>修改状态(modified),即:待暂存(staging)</li>
<li>已暂存(staged)</li>
<li>已提交(committed)</li>
</ol>
<p>3个区:</p>
<ol>
<li>本地工作目录(working directory)</li>
<li>暂存区(staging area,又叫做index)</li>
<li>git库(repository)</li>
</ol>
<p>1、2、3状态在本地工作目录,4状态属于暂存区,5状态属于git库。</p>
<p><embed src="img/git-state-and-area.svg" type="image/svg+xml" /></p>
<p>如果我修改了一下README.md,<code>git add</code>了一下,然后又修改了一下,用<code>git st</code>的打印是这样的:</p>
<pre><code class="cmd">$ git st
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
</code></pre>
<p>很多地方把暂存和stage混在一起,不查字典的话还以为stage的中文翻译就是暂存。其实 stage 就这个单词的本身的意思是:</p>
<ol>
<li>名词:舞台、讲台,比如:戏剧表演的舞台、国际政治的舞台;阶段,类似phase,比如:stage one/two意思是第一/二阶段,three-stage rocket意思是三级火箭</li>
<li>动词:上演、举行、组织,类似play、organize,比如:stage a football match,举办足球赛</li>
</ol>
<p>stage本身并没有暂存的意思,git中可以理解为把文件放到一个舞台上上演一下,进而文件进入到一个新的阶段。——用这个词可以说是一箭三雕。</p>
<p>你可以输入<code>git help stage</code> 看看</p>