git笔记
该笔记是参照廖雪峰大佬写的Git教程 https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/
1、下载git
下载window版本的git,网址是:
一路下一步
2、自报家门
安装完后才能后,需要在gitbash中设置一下你自己的邮箱和用户
git config --global user.name "cheny"
git config --global user.email "597985642@qq.com"
git中用户名和邮箱地址的作用:
用户名和邮箱地址是本地git客户端的一个变量,不随git库而改变。
每次commit都会用用户名和邮箱纪录。
github的contributions统计就是按邮箱来统计的。
由于我们把remote 仓库放在这类云端,而提交的验证方式则是通过用户名和密码。因此,我们有时会疏忽掉提交邮箱和用户名的问题。因为,能够输入云端的用户名和密码,就能够提交上去。这个时候,如果我在其他的pc上想要提交,则需要修改一些本地提交到云端的用户名和邮箱。这样才能保证提交上去都是你自己的。
修改当前用户邮箱和用户的方法如下
git config --global user.name "username"
git config --global user.email "email"
查看自己的用户和邮箱
git config user.name
git config user.email
3、创建版本库
(1)假设我在桌面创建一个目录,名字叫learngit
mkdir leargit
cd leargit/
git init
这时候,一个新的git版本库就创建好了,会在我们的目录下面生成一个.git
目录
(2)然后我们用notepad++创建一个readme.txt
文件,并编辑文字
Git is a version control system.
Git is free software.
(3)把新建的文件添加到仓库
git add readme.txt
(4)提交
git commit -m "wrote a readme.txt file"
实际上,你可以add多个文件,提交只提交一次即可,如下:
git add file1.txt
git add file2.txt
git add file3.txt
git commit -m "add 3 files."
4、修改文件,查看状态,重新提交
(1)我们已经成功地添加并提交了⼀个readme.txt⽂件,现在,是时候继续⼯作了,于是,我 们继续修改readme.txt⽂件,改成如下内容:
Git is a distributed version control system.
Git is free software.
(2)查看当前状态、修改未提交
git status
(3)查看哪里做了修改
git diff readme.txt
(4)发现是正常的修改,然后重新把文件添加到仓库
git add readme.txt
(5)重新查看当前状态、等待提交
git status
(6)正式提交,提交到仓库
git commit -m "add distrubuted"
(7)再次查看状态、无任何变动、all clean
git status
5、版本回退
(1)先再修改一下readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
(2)添加到仓库
git add readme.txt
(3)提交
git commit -m "append GPL"
(4)查看之前所有的版本-详细版
git log
(5)查看之前所有的版本-缩略版
git log --pretty=oneline
(6)回退到上一版本
在Git中,⽤HEAD表⽰当前版本,也就是最新的 提交“730582...a42a”(注意我的提交ID和你的肯定不⼀样),上⼀个版本就是 HEAD^,上上⼀个版本就是HEAD^^,当然往上100 个版本写100个^⽐较容易数不过来, 所以写成HEAD~100。
git reset --hard HEAD^
(7)回到刚才的版本
用刚才的指令还可以继续回退到上⼀个版本“add 3 files”,不过且慢,然我们⽤git log再看 看现在版本库的状态:发现刚才的"append GPL"版本没了,最新的那个版本“append GPL”已经看不到了!好⽐你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?办法其实还是有的,只要上⾯的命令⾏窗⼝还没有被关掉,你就可以顺着往上找啊找啊,找到那个“append GPL”的commit id是“730582...a42a”,于是就可以指定回到未来的某个版本:不用写全
git reset --hard 73058
(8)查看reademe.txt
cat readme.txt
你会发先已经改变回来了
(9)查看所有提交的版本操作
现在,你回退到了某个版本,关掉了电脑,第⼆天早上就后悔了,想恢复到新版本怎么办? 找不到新版本的commit id怎么办?在Git中,总是有后悔药可以吃的。当你⽤$ git reset --hard HEAD^回退到“add distributed”版本时,再想恢复到“append GPL”,就必须找到“append GPL”的commit id。Git提供了⼀个命令git reflog⽤来记录你的每⼀次命令:
git reflog
6、工作区和暂存区
⼯作区(Working Directory):就是你在电脑⾥能看到的目录,⽐如我的learngit⽂件夹 就是⼀个⼯作区。
版本库(Repository):⼯作区有⼀个隐藏⺫录“.git”,这个不算⼯作区,⽽是Git的版本 库。 Git的版本库⾥存了很多东⻄,其中最重要的就是称为stage(或者叫index)的暂存区,还 有Git为我们⾃动创建的第⼀个分⽀master,以及指向master的⼀个指针叫HEAD。
第⼀步是⽤“git add”把⽂件添加进去,实际上就是把⽂件修改添加到暂存区; 第⼆步是⽤“git commit”提交更改,实际上就是把暂存区的所有内容提交到当前分⽀。 因为我们创建Git版本库时,Git⾃动为我们创建了唯⼀⼀个master分⽀,所以,现在, commit就是往master分⽀上提交更改。
实践:
(1)修改readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
(2)在工作区新建一个LICENSE.txt
hrbust_cheny
(3)查看当前状态、一个是修改状态、一个是从未被添加过是Untracked状态。
git status
(3)将两个文件都添加进去、并查看当前状态、
git add readme.txt
git add LICENSE.txt
git status
所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage)
现在工作区的状态是这个样子的
(4)commit提交、查看当前状态
git commit -m "understand how stage works"
git status
现在版本库变成了这样,暂存区就没有任何内容了
7、Git跟踪并管理的是修改,⽽⾮⽂件
当你有如下的操作时
第⼀次修改 -> git add -> 第⼆次修改 -> git commit
第二次修改的内容并没有提交到分支上,git只把提交到缓存区的内容上传到了主分支。
自己悟一下~
一个好用的命令,查看⼯作区和版本库⾥⾯最新版本的区别
git diff HEAD -- readme.txt
8、撤销修改、add之前撤销原样、commit之前撤销回原样
(1)
状态1:⼀种是readme.txt⾃修改后还没有被放到暂存区,现在,撤销修改就回到和版本库⼀模⼀ 样的状态
状态2:⼀种是readme.txt已经添加到暂存区后,⼜作了修改,现在,撤销修改就回到添加到暂存 区后的状态
git checkout -- readme.txt
(2)
把暂存区的修改撤销掉(unstage),重新放回⼯作区
git reset HEAD readme.txt
这样就把等待commit的文件,又回退到了还未add的状态
9、删除commit之后的文件、或者还原删除过的文件
当你把一个文件commit之后,你直接在文件夹中把这个文件删除,或者用命令行删除,这个时候你查看一下当前git的状态,git是有反应的
删除文件的指令
rm test.txt
这个时候查看git的状态
git status
(1)这个时候你有两种选择,一种是真的从git中删除
git rm test.txt
然后再查看状态
然后你再commit一下,就彻底没了
git commit -m "remove test.txt"
(2)另一种选择是,你后悔了,你想在把这个文件恢复回来
git checkout -- test.txt
git checkout其实是⽤版本库⾥的版本替换⼯作区的版本,⽆论⼯作区是修改还是删除,都 可以“⼀键还原”
10、连接远程仓库、使用SSH公私钥
(1)创建SSH Key。在⽤户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下 有没有id_rsa和id_rsa.pub这两个⽂件,如果已经有了,可直接 跳到下⼀步。如果没有,打 开Shell(Windows下打开Git Bash),创建SSH Key
ssh-keygen -t rsa -C "597985642@qq.com"
一路回车即可,也不用设密码,没啥用
然后会在你的用户目录下面生成一个.ssh
目录
我的目录是这样子的:C:\Users\cheny\.ssh
⾥⾯有id_rsa和id_rsa.pub两个⽂件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放⼼地告诉任何⼈。
(2)在github上添加自己的公钥
把自己本地的公钥id_rsa.pub
的内容复制到github里,title可以随便填
为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,⽽ 不是别⼈冒充的,⽽Git⽀持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只 有你⾃⼰才能推送。 当然,GitHub允许你添加多个Key。假定你有若干电脑,你⼀会⼉在公司提交,⼀会⼉在 家⾥提交,只要把每台电脑的Key都添加到GitHub,就可以在每台电脑上往GitHub推送 了。
11、将本地文件夹与远程github关联
这里假如你已经把本地的SSh公钥添加到了github中,就可以执行以下操作来进行关联
(1)在github里新建一个远程仓库,取名叫做learngit
(2)在本地的learngit
仓库运行下面的命令
git remote add origin git@github.com:13836005450/learngit.git
请千万注意,把上⾯的13836005450
替换成你⾃⼰的GitHub账户名,否则,你在本地关联的 就是我的远程库,关联没有问题,但是你以后推送是推不上去的,因为你的SSH Key公钥不 在我的账户列表中。
(3)将本地的内容推送到远端
git push -u origin master
把本地库的内容推送到远程,⽤git push命令,实际上是把当前分⽀master推送到远程。
由于远程库是空的,我们第⼀次推送master分⽀时,加上了-u参数,Git不但会把本地的 master分⽀内容推送的远程新的master分⽀,还会把本地的master分⽀和远程的master 分⽀关联起来,在以后的推送或者拉取时就可以简化命令。 推送成功后,可以⽴刻在GitHub⻚⾯中看到远程库的内容已经和本地⼀模⼀样。
从现在起,只要本地作了提交,就可以通过命令
git push origin master
把本地master分⽀的最新修改推送⾄GitHub。
13、从远程github克隆项目到本地
(1)在远程新建一个项目gitskills
,在初始化一个README.md
(2)在本地克隆
git clone git@github.com:13836005450/gitskills.git
(3)查看一下
cd gitskills
ls
这时候就会看到你的README.md
14、git的分支操作(鼓励使用分支)
git分支的创建、切换、合并速度都非常快,
(1)分支的好处如下:
分⽀就是科幻电影⾥⾯的平⾏宇宙,当你正在电脑前努⼒学习Git的时候,另⼀个你正在另 ⼀个平⾏宇宙⾥努⼒学习SVN。 如果两个平⾏宇宙互不干扰,那对现在的你也没啥影响。不过,在某个时间点,两个平⾏宇 宙合并了,结果,你既学会了Git⼜学会了SVN!
(2)分支的原理
⼀开始的时候,master分⽀是⼀条线,Git⽤master指向最新的提交,再⽤HEAD指向 master,就能确定当前分⽀,以及当前分⽀的提交点
每次提交,master分⽀都会向前移动⼀步,这样,随着你不断提交,master分⽀的线也越 来越⻓。 当我们创建新的分⽀,例如dev时,Git新建了⼀个指针叫dev,指向master相同的提交, 再把HEAD指向dev,就表⽰当前分⽀在dev上:
从现在开始,对⼯作区的修改和提交就是针对dev分⽀了,⽐如新提交⼀次后,dev 指针往前移动⼀步,⽽master指针不变:
假如我们在dev上的⼯作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单 的⽅法,就是直接把master指向dev的当前提交,就完成了合并
合并完分⽀后,甚⾄可以删除dev分⽀。删除dev分⽀就是把dev指针给删掉,删掉后,我 们就剩下了⼀条master分⽀
所以,git分支操作速度很快,方便快捷
(1)git创建分支、快速创建并切换
git checkout -b dev
(2)创建分支、不切换
git branch dev
(3)切换分支
git checkout dev
(4)查看分支
git branch
(5)删除分支
git branch -d dev
(6)合并分支
git merge dev
15、解决冲突
当两个不同的分支同时改变了同一行文字时,就会产生冲突,这时候当你自动合并分支的时候,会产生一个新的提交状态,冲突状态,并且会自动的将冲突的内容写在一起,让你手动的解决冲突。如下
Git⽤<<<<<<<,=======,>>>>>>>标记出不同分⽀的内容
手动更改之后,重新add、commit就行了。
16、分支策略
master分支应该是非常稳定的,应不稳定的分支应该是dev,每个小伙伴都有一个自己的分支,时不时的将自己的分支合并到dev上,当dev分支比较稳定后,在把dev分支合并到master分支上,所以一般工作时候的状态应该是这样子的。
17、bug分支
假如你正在操作你自己的分支,这时候boss突然告诉你,master分支上有一个bug,你去修复一下。
这个时候你手里任务还没完成,你还不能提交到dev分支,怎么办?
有个好办法,git提供了一个可以保存当前状态的方法
git stash
这样就把你当前的状态给保存的下来,你就放心的去切换到主分支去修复bug把。
一般修复bug都会建一个临时的分支,比如issure101
,等修复完后,再切换到主分支合并这个bug分支,然后把问题分支删除就行了。
接下来,你继续完成你剩余的工作,切换到自己的分支,你发现,里面啥也没有!
其实是给你隐藏了起来,查看隐藏的stash
git stash list
发现你没有完成的工作就在这里,然后恢复一下,这时有两种操作,一种是恢复后直接删除刚才的list
git stash pop
另一种是先恢复,后删除
git stash apply
git stash drop
18、强行删除一个分支
git branch -D name
19、多人合作
(1)首先在github新建一个远程仓库,默认只有一个master分支,再手动建一个dev分支
(2)克隆远程仓库到本地
git clone git@github.com:13836005450/gitskills.git
(3)当克隆过后,只克隆过来了一个master分支,在操作前先更新一下本地仓库,把其它的分支都拉取下来
git pull
(4)本地的master分支与远程的master分支直接就关联到了一起,本地把远程的master分支叫做origin,从本地创建一个dev分支,与远程的dev分支关联
git checkout -b dev origin/dev
(5)然后就直接正常操作了,注意,每次写代码前先更新一下当前的仓库,然后再正常上传推送
git pull
git push origin dev
(6)如果dev分支不让pull,出现"no tracking information",应该是本地的dev分支与远程的dev分支没有关联上
git branch --set-upstream dev origin/dev
20、标签管理
发布⼀个版本时,我们通常先在版本库中打⼀个标签,这样,就唯⼀确定了打标签时刻的版 本。将来⽆论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。 所以,标签也是版本库的⼀个快照。
(1)为最新的commit打一个标签
git tag v1.0
(2)查看所有的commit,为其中的某一个打一个标签
git log --pretty=oneline --abbrev-commit
git tag v0.9 4846
(3)打一个带有备注的标签
git tag -a v0.1 -m "version 0.1 released" 86fc
(4)查看所有标签
git tag
(5)查看标签的详细信息
git show v1.0
(6)删除标签
git tag -d v0.1
(7)推送本地标签到远程
git push origin v1.0 推送一个
或者
git push origin --tags 推送所有
(8)删除远程的标签
git tag -d v0.9 先删除本地的
git push origin :refs/tags/v0.9 再删除远端的
21、忽略某些文件、.gitignore文件
(1)新建一个.gitignore
文件
touch .gitignore
(2)编辑
# 测试
dist/
aa.txt
这样里面的dist文件夹和aa.txt就被忽略的,再用git status
查看时就没有提示了。