Git原理与配置
Git是什么
- Git是分布式版本控制软件
基本命令
git add:将本地文件增加到暂存区
git commit:将暂存区的文件提交到本地仓库(本地分支,默认master分支)
git push:将本地仓库的内容推送到远程仓库(远程分支)
git pull:将远程仓库(远程分支)的内容拉取到本地仓库(本地分支)
为什么要有暂存区?因为如果每次都是直接提交的话,版本太多不好管理,可以做多次修改后统一提交
安装
- 安装时:use git from git bash only,其他默认下一步
- 配置path:git的bin目录
- 配置git:用户名和邮箱
git config --global user.name "用户名"
git config --global user.email "邮箱"
- 查看用户名和邮箱:
C:\Users\DELL\.gitconfig
-
搭建git服务器:统一托管网站(https://github.com/)
-
本地和远程仓库之间免秘钥通信:配置ssh,先在本地配置,再发送给远程
- 本地生成ssh:
ssh-keygen -t rsa -C 邮箱
一路回车 - 发送给远程:github -settings -ssh -new ssh -title任意 key中输入本地生成的ssh:将id_rsa.pub文件中的内容复制到远程的key中
- 本地生成ssh:
- 测试连通性:
ssh -T git@github.com
- 如果本地和远程成功通信,则可以在/.ssh目录中发现一个known_hosts文件
- 如果失败:可能是网站不稳定,多试几次
- .git目录:git版本控制的目录
本地新建项目,并关联远程
在本地新建git项目:在项目根目录下:右键-git bash-git init
在远程建立git项目:生成项目的唯一标识ssh:git@github.com:linxd1999/mygitDemo.git
关联本地和远程项目:git remote add origin git@github.com:linxd1999/mygitDemo.git
Git常见操作
常用Linux命令
touch 文件名:在当前目录下创建一个新文件
ls:查看当前目录下的所有文件
ctrl A:光标回当前行开头
ctrl E:光标到当前行结尾
ctrl C:放弃本行内容,启用下一行
echo '新内容' > 文件名:把文件中的内容用新内容来覆盖
第一次发布项目
git add . //文件->暂存区
git commit -m "注释内容" //暂存区->本地分支(默认master)
git push -u origin master //本地分支->远程分支
第一次下载项目
git clone 远程仓库的ssh密钥
提交更新(本地->远程)
(当前工作目录下 右键git bash)
git add .
git commit -m "注释内容"
git push origin master
更新(本地->远程)
(在远程修改文件后保存)
在文件目录下:git pull
邮箱和用户名
设置用户名和邮箱,形如git config --global user.name xxx
git config --global (基本不用,给整个计算机一次性设置)
git config --system (推荐使用,给当前用户一次性设置),在C盘用户目录下的.gitconfig文件中
git config --local(给当前项目一次性设置),在项目.git/config文件中
移除用户名和邮箱
git config --local --unset user.name
或者直接找到文件位置进去修改
文件状态转换
工作区->暂存区:git add 文件名
暂存区->工作区:git rm --cached 文件名 或者 git reset head 文件名
暂存区->对象区:git commit -m "文件注释"
暂存区->工作区:commit文件之后,修改这个文件(直接修改,vi等操作)
工作区->暂存区:撤销文件的修改,git checkout -- 文件名 (--后有一个空格)
删除与还原
对象区->暂存区(删除已提交的文件):git rm 文件名,删除已提交的文件,放到暂存区
还原文件:
1.恢复到工作区:git reset head 文件名
2.git checkout -- 文件名(--后有空格)
彻底删除文件:git commit -m "彻底删除"
区别“操作系统删除” rm:文件删除,并放到工作区
重命名
重命名的原理:把原文件删除,再创建一个内容一样的新文件
git mv 旧文件名 新文件名
可以利用git checkout -- 旧文件名 把旧文件恢复到对象区(这样同样的文件会以两个不同的名字存在)
注释重写(重写提交说明)
git commit --amend -m '新的注释'
忽略
为什么要使用忽略?因为配置文件不需要存储到远程仓库去
否则别人在拉取仓库的时候可能会出现路径混乱的问题(与其他人的配置文件冲突),只需要传代码的文件即可
方法:创建.gitignore文件,并编辑
通配符:*任意字符,!排除某些文件(通常一起使用)
(*.properties和!b.properties)表示:除了b.properties文件,其余.properties结尾的文件全部忽略
dir/:忽略dir目录中的所有文件
dir/*.txt:忽略dir目录下所有的以txt结尾的文件
dir/*/*.txt:能忽略dir/abc/a.txt,但不能忽略dir/abc/def/a.txt
dir/**/*.txt:任意级别目录
空目录会被自动忽略
Git分支
什么是分支
分支就是一条commit链,一条工作记录线
分支基本操作
查看分支:git branch(git branch -v)
创建分支:git branch 分支名
切换分支:git checkout 分支名
创建分支并切换:git checkout -b 分支名
合并分支:git merge 分支名
删除分支:git branch -d 分支名(不能删除当前所在分支,需要切换到另一个分支才能删除)
强行删除分支:git branch -D 分支名
细节:
1.如果在分支A中进行了写操作(增删改),但此操作局限在工作区中进行(没有add和commit),在master中能够看到该操作。
如果在分支A中进行了写操作,并且commit到了对象区,则master中无法观察到此文件
2.如果在分支A中进行了写操作,但此操作局限在工作区中进行,则删除分支不需要合并
分支合并
分支名:指向当前的提交(commit)
HEAD:指向当前分支(HEAD->分支名)
如果一个分支靠前(new),一个分支落后(master),则如果不冲突,master可以通过merge直接追赶上new,称为fast forward。
fast forward本质上就是分支指针的移动:
1.两个分支fast forward归于一点commit
2.丢失分支信息(git log --graph看不见两个分支的路径,因为被合并了)
git merge默认使用fast forward,但我们可以手动禁止:git merge --no-ff 分支名
1.两个分支不会归于一个commit,主动合并的分支,会前进一步
2.分支信息不会丢失(git log --graph)
冲突
冲突:如果两个分支在同一个时刻,且两个分支同时修改了同一个文件的同一行,在合并时会引起冲突
如何解决冲突?(拿master和new分支举例)
1.先在某个分支(例如master)中打开这个文件,把内容修改为最终需要的内容
2.git add 文件名(这里的add并不是从工作区到暂存区,而是告诉git冲突已经解决)
3.git commit -m "文件注释"
解决冲突会造成两次提交,即sha1值会出现两个:1次是最终提交,1次是将对方分支(new)的提交信息获取过来
这时候观察文件内容,master中的文件内容是最终修改后的内容,而new中的文件内容是解决冲突前的内容
这时候直接把new分支合并到master分支即可
这时候可能有人会问了,同样修改了同一行为什么最后这次合并不要解决冲突呢?
这其实是因为master分支的最终提交和new在解决冲突之前的提交不处于同一时刻,所以直接合并即可
简而言之:如果一方落后,则落后方可以直接通过merge合并到处于前面的分支
码住码住
tql