-
Notifications
You must be signed in to change notification settings - Fork 2
/
git-use.txt
973 lines (732 loc) · 37.8 KB
/
git-use.txt
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
1 检查SSH公钥
cd ~/.ssh
2 生成SSH公钥
ssh-keygen -t rsa -C "[email protected]"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/you/.ssh/id_rsa):
默认回车
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
可以输入你在github上设置的密码,但每次git操作都必须输入密码,如果直接回车就不用了,生成公私钥成功:
Your identification has been saved in /home/you/.ssh/id_rsa.
Your public key has been saved in /home/you/.ssh/id_rsa.pub.
The key fingerprint is:
01:0f:f4:3b:ca:85:d6:17:a1:7d:f0:68:9d:f0:a2:db [email protected]
3 添加SSH公钥到github
打开github,找到账户里面添加SSH,把id_rsa.pub内容复制到key里面。
4 测试是否生效
使用下面的命令测试
ssh -T [email protected]当看到这些内容放入时候,直接yes
The authenticity of host 'github.com (207.97.227.239)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)?看到这个内容放入时候,说明就成功了。
Hi username!
You've successfully authenticated, but GitHub does not provide shell access.
****************生成key
ssh-keygen -t rsa -C "[email protected]"
cat ~/.ssh/id_rsa.pub
添加key到github上
**********git 配置
一、创建github repository(仓库)
仓库地址使用SSH,如果用https地址每次push/pull都要输入github账号密码。二、安装客户端
windows: https://desktop.github.com/
linux(centos): yum install git(升级到git新版本)
绑定用户:
git config --global user.name "xxx"
git config --global user.email "[email protected]"
ps:git config –global 参数,有了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱。
查看git配置:
git config --list
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
git clone [email protected]:chaofeibest/gittee-demo.git
git clone [email protected]:swiftchao/git-use.git
配置自动生成changeId
github
gitdir=$(git rev-parse --git-dir); scp -p -P 29418 [email protected]:hooks/commit-msg ${gitdir}/hooks/commit-msg
Starlingx的
gitdir=$(git rev-parse --git-dir); scp -p -P 29418 [email protected]:hooks/commit-msg ${gitdir}/hooks/
git commit --amend
***************上传本地项目到github
mkdir demo
cd demo
echo "# demo" >> README.md
git init //把这个目录变成Git可以管理的仓库
git add README.md //文件添加到仓库
git add . //不但可以跟单一文件,还可以跟通配符,更可以跟目录。一个点就把当前目录下所有未追踪的文件全部add了(空目录不会被添加)
git status //查看当前工作区的状态(需提交的变更)
git commit -m "first commit" //把文件提交到仓库
git remote add origin [email protected]:swiftchao/demo.git //关联远程仓库
git push -u origin master //将本地主分支推到远程(如无远程主分支则创建,用于初始化远程仓库)
git push origin master //将本地主分支推到远程主分支
*********git下载
git pull origin master //把远程库更改拉到本地仓库
git clone [email protected]:swiftchao/demo.git //克隆远程仓库到本地
git clone https://github.com/swiftchao/demo.git //克隆远程仓库到本地
git clone https://github.com/swiftchao/demo //克隆远程仓库到本地
**********git 实践使用
Git 全局设置:
git config --global user.name "chaofei"
git config --global user.email "[email protected]"
创建 git 仓库:
mkdir git-use
cd git-use
git init
touch README.md
git add README.md
git commit -m "first commit"
git remote add origin https://gitee.com/chaofeibest/git-use.git
git push -u origin master
已有项目?
cd existing_git_repo
git remote add origin https://gitee.com/chaofeibest/git-use.git
git push -u origin master
*********************git remote add
------------------------------------------------------------
git remote add github [email protected]:swiftchao/git-use.git
git remote add gitee [email protected]:chaofeibest/git-use.git
**********git回退
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
现在,我们要把当前版本append GPL回退到上一个版本add distributed,就可以使用git
reset命令:
$ git reset --hard HEAD^
HEAD is now at e475afc add distributed
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git
reset --hard commit_id。
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
********git比较区别
用git diff HEAD -- readme.txt命令可以查看工作区和版本库里面最新版本的区别:
$ git diff HEAD -- readme.txt
diff --git a/readme.txt b/readme.txt
index 76d770f..a9c5755 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
-Git tracks changes.
+Git tracks changes of files.
**********git丢弃修改
你可以发现,Git会告诉你,git checkout -- file可以丢弃工作区的修改:
$ git checkout -- readme.txt
命令git checkout --
readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
Git同样告诉我们,用命令git reset HEAD
<file>可以把暂存区的修改撤销掉(unstage),重新放回工作区:
$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
*********git删除
git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt""''
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
$ git checkout -- test.txt
*************git stash
并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?
幸好,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge
现在,用git
status查看工作区,就是干净的(除非有没有被Git管理的文件),因此可以放心地创建分支来修复bug。
首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支:
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)
$ git checkout -b issue-101
Switched to a new branch 'issue-101'
现在修复bug,需要把“Git is free software ...”改为“Git is a free software
...”,然后提交:
$ git add readme.txt
$ git commit -m "fix bug 101"
[issue-101 4c805e2] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)
修复完成后,切换到master分支,并完成合并,最后删除issue-101分支:
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)
$ git merge --no-ff -m "merged bug fix 101" issue-101
Merge made by the 'recursive' strategy.
readme.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
太棒了,原计划两个小时的bug修复只花了5分钟!现在,是时候接着回到dev分支干活了!
$ git checkout dev
Switched to branch 'dev'
$ git status
On branch dev
nothing to commit, working tree clean
工作区是干净的,刚才的工作现场存到哪去了?用git stash list命令看看:
$ git stash list
stash@{0}: WIP on dev: f52c633 add merge
工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git
stash drop来删除;
另一种方式是用git stash pop,恢复的同时把stash内容也删了:
$ git stash pop
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: hello.py
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.txt
Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a)
再用git stash list查看,就看不到任何stash内容了:
$ git stash list
你可以多次stash,恢复的时候,先用git stash
list查看,然后恢复指定的stash,用命令:
$ git stash apply stash@{0}
************git分支
Feature分支
阅读: 294839
软件开发中,总有无穷无尽的新的功能要不断添加进来。
添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
现在,你终于接到了一个新任务:开发代号为Vulcan的新功能,该功能计划用于下一代星际飞船。
于是准备开发:
$ git checkout -b feature-vulcan
Switched to a new branch 'feature-vulcan'
5分钟后,开发完毕:
$ git add vulcan.py
$ git status
On branch feature-vulcan
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: vulcan.py
$ git commit -m "add feature vulcan"
[feature-vulcan 287773e] add feature vulcan
1 file changed, 2 insertions(+)
create mode 100644 vulcan.py
切回dev,准备合并:
$ git checkout dev
一切顺利的话,feature分支和bug分支是类似的,合并,然后删除。
但是!
就在此时,接到上级命令,因经费不足,新功能必须取消!
虽然白干了,但是这个包含机密资料的分支还是必须就地销毁:
$ git branch -d feature-vulcan
error: The branch 'feature-vulcan' is not fully merged.
If you are sure you want to delete it, run 'git branch -D
feature-vulcan'.
销毁失败。Git友情提醒,feature-vulcan分支还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用大写的-D参数。。
现在我们强行删除:
$ git branch -D feature-vulcan
Deleted branch feature-vulcan (was 287773e).
终于删除成功!
***************git多人协作
多人协作
阅读: 499207
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
要查看远程库的信息,用git remote:
$ git remote
origin
或者,用git remote -v显示更详细的信息:
$ git remote -v
origin [email protected]:michaelliao/learngit.git (fetch)
origin [email protected]:michaelliao/learngit.git (push)
上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。
推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
$ git push origin master
如果要推送其他分支,比如dev,就改成:
$ git push origin dev
但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?
master分支是主分支,因此要时刻与远程同步;
dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
总之,就是在Git中,分支完全可以在本地自己藏着玩,是否推送,视你的心情而定!
抓取分支
多人协作时,大家都会往master和dev分支上推送各自的修改。
现在,模拟一个你的小伙伴,可以在另一台电脑(注意要把SSH
Key添加到GitHub)或者同一台电脑的另一个目录下克隆:
$ git clone [email protected]:michaelliao/learngit.git
Cloning into 'learngit'...
remote: Counting objects: 40, done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 40 (delta 14), reused 40 (delta 14), pack-reused 0
Receiving objects: 100% (40/40), done.
Resolving deltas: 100% (14/14), done.
当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的master分支。不信可以用git
branch命令看看:
$ git branch
* master
现在,你的小伙伴要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支:
$ git checkout -b dev origin/dev
现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程:
$ git add env.txt
$ git commit -m "add env"
[dev 7a5e5dd] add env
1 file changed, 1 insertion(+)
create mode 100644 env.txt
$ git push origin dev
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 308.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
f52c633..7a5e5dd dev -> dev
你的小伙伴已经向origin/dev分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送:
$ cat env.txt
env
$ git add env.txt
$ git commit -m "add new env"
[dev 7bd91f1] add new env
1 file changed, 1 insertion(+)
create mode 100644 env.txt
$ git push origin dev
To github.com:michaelliao/learngit.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to
'[email protected]:michaelliao/learngit.git'
hint: Updates were rejected because the tip of your current branch is
behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git
pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:
$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull <remote> <branch>
If you wish to set tracking information for this branch you can
do so with:
git branch --set-upstream-to=origin/<branch> dev
git
pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:
$ git branch --set-upstream-to=origin/dev dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
再pull:
$ git pull
Auto-merging env.txt
CONFLICT (add/add): Merge conflict in env.txt
Automatic merge failed; fix conflicts and then commit the
result.
这回git
pull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push:
$ git commit -m "fix env conflict"
[dev 57c53ab] fix env conflict
$ git push origin dev
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 621 bytes | 621.00 KiB/s,
done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
7a5e5dd..57c53ab dev -> dev
因此,多人协作的工作模式通常是这样:
首先,可以试图用git push origin
<branch-name>推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新,需要先用git
pull试图合并;
如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用git push origin
<branch-name>推送就能成功!
如果git pull提示no tracking
information,则说明本地分支和远程分支的链接关系没有创建,用命令git
branch --set-upstream-to <branch-name>
origin/<branch-name>。
这就是多人协作的工作模式,一旦熟悉了,就非常简单。
********git tag
命令git tag <tagname>用于新建一个标签,默认为HEAD,也可以指定一个commit id;
命令git tag -a <tagname> -m "blablabla..."可以指定标签信息;
命令git tag可以查看所有标签。""
git tag -a v0.1 -m "version 0.1 released" 1094adb""
git tag v1.0
可以用命令git tag查看所有标签:
$ git tag
v1.0
默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?
方法是找到历史提交的commit id,然后打上就可以了:
$ git log --pretty=oneline --abbrev-commit
12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
4c805e2 fix bug 101
e1e9c68 merge with no-ff
f52c633 add merge
cf810e4 conflict fixed
5dc6824 & simple
14096d0 AND simple
b17d20e branch test
d46f35e remove test.txt
b84166e add test.txt
519219b git tracks changes
e43a48b understand how stage works
1094adb append GPL
e475afc add distributed
eaadf4e wrote a readme file
比方说要对add merge这次提交打标签,它对应的commit id是f52c633,敲入命令:
$ git tag v0.9 f52c633
再用命令git tag查看标签:
$ git tag
v0.9
v1.0
注意,标签不是按时间顺序列出,而是按字母排序的。可以用git show
<tagname>查看标签信息:
$ git show v0.9
commit f52c63349bc3c1593499807e5c8e972b82c8f286 (tag: v0.9)
Author: Michael Liao <[email protected]>
Date: Fri May 18 21:56:54 2018 +0800
add merge
diff --git a/readme.txt b/readme.txt
...
可以看到,v0.9确实打在add merge这次提交上。
还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:
$ git tag -a v0.1 -m "version 0.1 released" 1094adb
用命令git show <tagname>可以看到说明文字:
$ git show v0.1
tag v0.1
Tagger: Michael Liao <[email protected]>
Date: Fri May 18 22:48:43 2018 +0800
version 0.1 released
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (tag: v0.1)
Author: Michael Liao <[email protected]>
Date: Fri May 18 21:06:15 2018 +0800
append GPL
diff --git a/readme.txt b/readme.txt
如果标签打错了,也可以删除:
$ git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)
因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
如果要推送某个标签到远程,使用命令git push origin <tagname>:
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0
或者,一次性推送全部尚未推送到远程的本地标签:
$ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v0.9 -> v0.9
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
$ git tag -d v0.9
Deleted tag 'v0.9' (was f52c633)
然后,从远程删除。删除命令也是push,但是格式如下:
$ git push origin :refs/tags/v0.9
To github.com:michaelliao/learngit.git
- [deleted] v0.9
要看看是否真的从远程库删除了标签,可以登陆GitHub查看
命令git push origin <tagname>可以推送一个本地标签;
命令git push origin --tags可以推送全部未推送过的本地标签;
命令git tag -d <tagname>可以删除一个本地标签;
命令git push origin :refs/tags/<tagname>可以删除一个远程标签。
***************git多个库同步
git remote rm origin
然后,先关联GitHub的远程库:
git remote add github [email protected]:michaelliao/learngit.git
注意,远程库的名称叫github,不叫origin了。
接着,再关联码云的远程库:
git remote add gitee [email protected]:liaoxuefeng/learngit.git
同样注意,远程库的名称叫gitee,不叫origin。
现在,我们用git remote -v查看远程库信息,可以看到两个远程库:
git remote -v
gitee [email protected]:liaoxuefeng/learngit.git (fetch)
gitee [email protected]:liaoxuefeng/learngit.git (push)
github [email protected]:michaelliao/learngit.git (fetch)
github [email protected]:michaelliao/learngit.git (push)
------------------------------------------------------------
git remote add github [email protected]:swiftchao/git-use.git
git remote add gitee [email protected]:chaofeibest/git-use.git
------------------------------------------------------------
如果要推送到GitHub,使用命令:
git push github master
如果要推送到码云,使用命令:
git push gitee master
这样一来,我们的本地库就可以同时与多个远程库互相同步:
********git配置别名
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
***********git 颜色
自定义Git
在安装Git一节中,我们已经配置了user.name和user.email,实际上,Git还有很多可配置项。
比如,让Git显示颜色,会让命令输出看起来更醒目:
$ git config --global color.ui true
**********git 服务器搭建
搭建Git服务器
阅读: 594768
在远程仓库一节中,我们讲了远程仓库实际上和本地仓库没啥不同,纯粹为了7x24小时开机并交换大家的修改。
GitHub就是一个免费托管开源代码的远程仓库。但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓库使用。
搭建Git服务器需要准备一台运行Linux的机器,强烈推荐用Ubuntu或Debian,这样,通过几条简单的apt命令就可以完成安装。
假设你已经有sudo权限的用户账号,下面,正式开始安装。
第一步,安装git:
$ sudo apt-get install git
第二步,创建一个git用户,用来运行git服务:
$ sudo adduser git
第三步,创建证书登录:
收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。
第四步,初始化Git仓库:
先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:
$ sudo git init --bare sample.git
Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git:
$ sudo chown -R git:git sample.git
第五步,禁用shell登录:
出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:
git:x:1001:1001:,,,:/home/git:/bin/bash
改为:
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
这样,git用户可以正常通过ssh使用git,但无法登录shell,因为我们为git用户指定的git-shell每次一登录就自动退出。
第六步,克隆远程仓库:
现在,可以通过git clone命令克隆远程仓库了,在各自的电脑上运行:
$ git clone git@server:/srv/sample.git
Cloning into 'sample'...
warning: You appear to have cloned an empty repository.
剩下的推送就简单了。
管理公钥
如果团队很小,把每个人的公钥收集起来放到服务器的/home/git/.ssh/authorized_keys文件里就是可行的。如果团队有几百号人,就没法这么玩了,这时,可以用Gitosis来管理公钥。
这里我们不介绍怎么玩Gitosis了,几百号人的团队基本都在500强了,相信找个高水平的Linux管理员问题不大。
管理权限
有很多不但视源代码如生命,而且视员工为窃贼的公司,会在版本控制系统里设置一套完善的权限控制,每个人是否有读写权限会精确到每个分支甚至每个目录下。因为Git是为Linux源代码托管而开发的,所以Git也继承了开源社区的精神,不支持权限控制。不过,因为Git支持钩子(hook),所以,可以在服务器端编写一系列脚本来控制提交等操作,达到权限控制的目的。Gitolite就是这个工具。
这里我们也不介绍Gitolite了,不要把有限的生命浪费到权限斗争中。
小结
搭建Git服务器非常简单,通常10分钟即可完成;
要方便管理公钥,用Gitosis;
要像SVN那样变态地控制权限,用Gitolite
Git HEAD detached from XXX 解决
git解决游离状态
git branch tem
git checkout master
git merge tem
git status
git pull origin master
git status
git branch -d tem
# patch
1 使用git format-patch生成所需要的patch:
当前分支所有超前master的提交:
git format-patch -M master
某次提交以后的所有patch:
git format-patch 4e16 --4e16指的是commit名
从根到指定提交的所有patch:
git format-patch --root 4e16
某两次提交之间的所有patch:
git format-patch 365a..4e16 --365a和4e16分别对应两次提交的名称
某次提交(含)之前的几次提交:
git format-patch –n 07fe --n指patch数,07fe对应提交的名称
故,单次提交即为:
git format-patch -1 07fe
git format-patch生成的补丁文件默认从1开始顺序编号,并使用对应提交信息中的第一行作为文件名。如果使用了-- numbered-files选项,则文件名只有编号,不包含提交信息;如果指定了--stdout选项,可指定输出位置,如当所有patch输出到一个文件;可指定-o <dir>指定patch的存放目录;
2应用patch:
先检查patch文件:git apply --stat newpatch.patch
检查能否应用成功:git apply --check newpatch.patch
打补丁:git am --signoff < newpatch.patch
# format-patch生成patch文件
22bcd3f0 开始的commitid
075833ff 是结束的commitid
git format-patch 22bcd3f0..075833ff
mkdir patches
mv *.patch patches/
# 检查patch文件的格式
git apply --stat /e/work/patch/20191209/patches/0001-nsp-router-changes.patch
# 检查patch文件是否能应用成功
git apply --check /e/work/patch/20191209/patches/0001-nsp-router-changes.patch
打补丁
git am --signoff < /e/work/patch/20191209/patches/0001-nsp-router-changes.patch
git format-patch 075833ff..8ce644b3
mkdir patches-1209-2
mv *.patch patches-1209-2
#cherry-pick
git branch -av
git branch -vv
git branch hangxin_1230 remotes/gerrit/hangxin_1230
git checkout master
git log --oneline
git checkout hangxin_1230
git cherry-pick d04bcec4
git add .
git commit
git review hangxin_1230
#
git branch -av
更新分支的代码
git checkout -b hangxin_1230 remotes/gerrit/hangxin_1230
git checkout -b hangxin_1230 remotes/origin/hangxin_1230
git pull
git checkout master
git pull origin master
git log --oneline
git checkout hangxin_1230
git cherry-pick d04bcec4
git status
git diff .
git add sql
git status
git commit
git review hangxin_1230
#报错解决
! [rejected] master -> master (fetch first)
error: failed to push some refs to '[email protected]:chaofeibest/git-use.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
git remote -v
git remote add gitee [email protected]:chaofeibest/git-use.git
git remote -v
#报错解决pull下代码就可以了
git pull gitee master
git push gitee master
#gerrit不能对一个已经merge/abandon的change进行再次提交操作,要再次提交需要修改changeId
获取已经提交的commitId
git log --oneline
git reset 4bf54595
git status
#修改已有的changeId
git commit --amend
#查看changeId已经修改
git log
#再重新提交
git review hangxin_1230
#统计提交
#使用 git 统计代码的数量
#统计某一名开发者有效代码总行数:
git log --author="chaofei" --numstat --pretty=tformat: | gawk '{ add += $1; subs += $2; loc += $1 + $2} END {printf "added lines: %s removed lines : %s total lines : %s\n", add, subs, loc}'
#统计一段时间内代码变化
git log --author="chaofei" --since ==2016-01-01 --until=2016-08-08 --numstat --pretty=tformat: | gawk '{ add += $1; subs += $2; loc += $1 + $2} END {printf "added lines: %s removed lines : %s total lines : %s\n", add, subs, loc}'
git log --author chaofei --stat | perl -ne 'END {print $c} $c += $1 if /(\d+) insertions/'
git log --author chaofei --stat | perl -ne 'END {print $c} $c += $1 if /(\d+) deletions/'
git log --author chaofei --stat | perl -ne 'END {print $c} $c += $1 if /(\d+) file changed/'
#统一某人的总的commit数量
git log --author=chaofei --oneline | wc -l
提交排名top 10
%aN代表只显示commit的author name。
也可以使用%ae,使用author email,防止出现重名的情况。
然后按照名字或者email排序,之后uniq的时候数count,之后按照第一列的值按照number的方式排序,最后取前10条记录
git log --pretty=%ae
git log --pretty=%aN | sort| uniq -c
58 chaofei
3 cicd
33 ckji
sort -r从大大小排列
git log --pretty=%aN | sort| uniq -c | sort -k1 -n -r | head -n 10
#统计有多少个代码贡献者
git log --pretty=%aN | sort -u | wc -l
sort命令支持很多参数,常用参数如下:
短参数 长参数 说明
-n – number-sort 按字符串数值排序,与-g区别为不转为浮点数
-g –general-number-sort 按通用数值排序,支持科学计数法
-f –ignore-case 忽略大小写,默认大小写字母不同
-k –key=POS1[,POS2] 排序从POS1开始,若指定POS2,则POS2结束,否则以pos1排序
-t –field-separator=SEP 指定列的分割符
-r –reverse 降序排序,默认为升序
-h –human-numeric-sort 使用易读性数字(例如: 2K 1G)
-u –unique 去除重复的行
-o –output=FILE 将输出写入文件
用法:uniq [选项]... [文件]
从输入文件或者标准输入中筛选相邻的匹配行并写入到输出文件或标准输出。
不附加任何选项时匹配行将在首次出现处被合并。
长选项必须使用的参数对于短选项时也是必需使用的。
-c, --count 在每行前加上表示相应行目出现次数的前缀编号
-d, --repeated 只输出重复的行
-D, --all-repeated[=delimit-method 显示所有重复的行
delimit-method={none(default),prepend,separate}
以空行为界限
-f, --skip-fields=N 比较时跳过前N 列
-i, --ignore-case 在比较的时候不区分大小写
-s, --skip-chars=N 比较时跳过前N 个字符
-u, --unique 只显示唯一的行
-z, --zero-terminated 使用'\0'作为行结束符,而不是新换行
-w, --check-chars=N 对每行第N 个字符以后的内容不作对照
--help 显示此帮助信息并退出
--version 显示版本信息并退出
若域中为先空字符(通常包括空格以及制表符),然后非空字符,域中字符前的空字符将被跳过。
提示:uniq 不会检查重复的行,除非它们是相邻的行。
如果您想先对输入排序,使用没有uniq 的"sort -u"。
#系统进程内存占用排序
ps aux | sort -gr -k 4 | head -n 5
sort -t ':' -k 3 -nr passwd
git stash 用法总结和注意点
常用git stash命令:
(1)git stash save "save message" : 执行存储时,添加备注,方便查找,只有git stash 也要可以的,但查找时不方便识别。
(2)git stash list :查看stash了哪些存储
(3)git stash show :显示做了哪些改动,默认show第一个存储,如果要显示其他存贮,后面加stash@{$num},比如第二个 git stash show stash@{1}
(4)git stash show -p : 显示第一个存储的改动,如果想显示其他存存储,命令:git stash show stash@{$num} -p ,比如第二个:git stash show stash@{1} -p
(5)git stash apply :应用某个存储,但不会把存储从存储列表中删除,默认使用第一个存储,即stash@{0},如果要使用其他个,git stash apply stash@{$num} , 比如第二个:git stash apply stash@{1}
(6)git stash pop :命令恢复之前缓存的工作目录,将缓存堆栈中的对应stash删除,并将对应修改应用到当前的工作目录下,默认为第一个stash,即stash@{0},如果要应用并删除其他stash,命令:git stash pop stash@{$num} ,比如应用并删除第二个:git stash pop stash@{1}
(7)git stash drop stash@{$num} :丢弃stash@{$num}存储,从列表中删除这个存储
(8)git stash clear :删除所有缓存的stash
# 修改已提交的commit的msg
1. 使用git log命令查看历史记录
git log
2.使用git rebase -i HEAD~6确定要修改哪些commit
其中,HEAD~6表示最近的6个,后面的6可以改成其他数字。
git rebase -i HEAD~6
假设我们需要修改第2条和第4条commit的message,
则需要将它们的命令(command),由pick改为edit,
其它地方保持不变(此时还不用修改message)。
修改完成之后,保存修改。
1 edit 4c4c5c71 add vpc subent lb vip 2 external network domain ALTER TABLE prefixes ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `end_ip`; ALTER TABLE ipam_pools ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `prefix_id`; ALTER TABLE allocation_pool ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `end_ip`; ALTER TABLE subnet ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `alias`; ALTER TABLE i p_pools ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `gateway`; ALTER TABLE sp_ip_pool_allocation ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `device_type`; ALTER TABLE loadbalancer ADD `networ k_type` VARCHAR(255) DEFAULT NULL AFTER `recycled`;
2 pick 0f0ff2f4 instance ipAddress optimize
3 edit eca677d7 add http code and exception
4 pick 691bd190 add vpn service in openstack4j
5 pick 15f388fb modify a BUG
6 pick 54ca0f4b router external gateway
7
8 # Rebase cc04af5e..54ca0f4b onto cc04af5e (6 commands)
9 #
10 # Commands:
11 # p, pick = use commit
12 # r, reword = use commit, but edit the commit message
13 # e, edit = use commit, but stop for amending
14 # s, squash = use commit, but meld into previous commit
15 # f, fixup = like "squash", but discard this commit's log message
16 # x, exec = run command (the rest of the line) using shell
17 # d, drop = remove commit
18 #
19 # These lines can be re-ordered; they are executed from top to bottom.
20 #
21 # If you remove a line here THAT COMMIT WILL BE LOST.
22 #
23 # However, if you remove everything, the rebase will be aborted.
24 #
25 # Note that empty commits are commented out
3. 轮流使用git commit --amend和git rebase --continue修改每个edit的commit
business-chain
2 add vpc subent lb vip 2 external network domain
3 ALTER TABLE prefixes ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `end_ip`;
4 ALTER TABLE ipam_pools ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `prefix_id`;
5 ALTER TABLE allocation_pool ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `end_ip`;
6 ALTER TABLE subnet ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `alias`;
7 ALTER TABLE ip_pools ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `gateway`;
8 ALTER TABLE sp_ip_pool_allocation ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `device_type`;
9 ALTER TABLE loadbalancer ADD `network_type` VARCHAR(255) DEFAULT NULL AFTER `recycled`;
10
11 Change-Id: Ic9a0176a13ea1a0a4d0694b8e55d30a601a7269d
12
chaofei@DESKTOP-T6A6N35 MINGW64 /e/work/fiberhome/code/git/fitmgr/fitmgr-visual/fitmgr-resourcecenter (vpc-2-external-network-domain|REBASE-i 1/6)
$ git rebase --continue
chaofei@DESKTOP-T6A6N35 MINGW64 /e/work/fiberhome/code/git/fitmgr/fitmgr-visual/fitmgr-resourcecenter (vpc-2-external-network-domain|REBASE-i 3/6)
$ git commit --amend
[detached HEAD 735bb4bf] business-chain add http code and exception
Date: Tue May 19 20:05:00 2020 +0800
3 files changed, 75 insertions(+)
$ git rebase --continue
Successfully rebased and updated refs/heads/vpc-2-external-network-domain.
chaofei@DESKTOP-T6A6N35 MINGW64 /e/work/fiberhome/code/git/fitmgr/fitmgr-visual/fitmgr-resourcecenter (vpc-2-external-network-domain)
chaofei@DESKTOP-T6A6N35 MINGW64 /e/work/fiberhome/code/git/fitmgr/fitmgr-visual/fitmgr-resourcecenter (vpc-2-external-network-domain)
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
chaofei@DESKTOP-T6A6N35 MINGW64 /e/work/fiberhome/code/git/fitmgr/fitmgr-visual/fitmgr-resourcecenter (master)
$ git pull
Already up-to-date.
chaofei@DESKTOP-T6A6N35 MINGW64 /e/work/fiberhome/code/git/fitmgr/fitmgr-visual/fitmgr-resourcecenter (master)
$ git checkout vpc-2-external-network-domain
Switched to branch 'vpc-2-external-network-domain'
chaofei@DESKTOP-T6A6N35 MINGW64 /e/work/fiberhome/code/git/fitmgr/fitmgr-visual/fitmgr-resourcecenter (vpc-2-external-network-domain)
$ git rebase master
First, rewinding head to replay your work on top of it...
git remote remove gerrit
git remote add gerrit http://fchao:[email protected]:8082/fitcloud/neutron-vpnaas.git
Closes-Bug: 10275
fix bug of delete ipsec-site-connection vpn-service status still active