Git是目前世界上最先进的分布式版本控制系统,Git可以做源代码管理
Linus (Linus Torvalds 林纳斯.托瓦斯)是在BitKeeper停止向开源社区提供免费版本后开发了Git,BitKeeper在免费使用的许可证中加入很多限制条件,惹恼了内核开发者,最终促使Linus开发出了毁灭BitMover的Git。
Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下
所有的版本控制系统,其实只能跟踪文本文件的改动,图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化
集中式版本控制工具 :SVN
- 版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器下载最新的版本,然后开发代码,写完代码后需要把自己的代码推送到中央服务器。
- 缺点是,就一台服务器,服务器单点故障,容错性差。怎么解决:集群(去中心化)
分布式版本控制系统GIt 根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库
分布式版本控制工具 :Git
分为本地仓库和远程仓库,每个人都要维护好自己的本地库
- 本地仓库:是在开发人员自己电脑上的Git仓库
- 远程仓库:是在远程服务器上的Git仓库
- 优点是,容灾能力强,本地版本管理,异地协作,灵活分支
分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已
Git作用:最核心的就是协同开发,当然Git还有这些作用:
代码托管中心(中心就是服务器)
代码托管中心负责维护远程库
局域网
- Gitlab
Internet
- GitHub
- 码云(gitee)
下载Git https://git-for-windows.github.io/
下载可视化工具:TortoiseGit
下载地址: TortoiseGit – Windows Shell Interface to Git
不过我是不用下载了,我们有老师发的压缩包
至少知道谁提交的(从本地库——>中央仓库)
用户名和邮箱地址是本地git客户端的一个变量 . 用户每次提交代码都会记录用户名和邮箱
安装完成后,在任意的文件目录下,右键都可以开打Git的命令行窗口——Git Bash Here
Git是分布式版本控制系统,所以需要填写用户名和邮箱作为一个标识,即:用户签名
签名的作用是区分不同操作者身份。用户的签名信息在每一个版本的提交信息中能够看到,以此确认本次提交是谁做的。
这里设置用户签名和将来登录GitHub(或其他代码托管中心)的账号没有任何关系。
设置全局用户签名
git config --global user.name "用户名" git config --global user.email "用户邮箱"
全局,就是只要用我电脑提交代码,都会是这个签名
怎么看成功没?查看配置信息
git config --list
实际上,全局用户签名保存在了 .gitconfig文件,可视化,可以方便修改
在当前登录的系统用户路径下,生成~/.gitconfig隐含文件,里面可以看到刚刚设置的信息。如果不用命令设置,也可以直接打开文件进行设置
工作区:项目的当前目录(放代码的地方)
本地库(版本库):工作区有个隐藏目录.git,它就是Git的本地版本库,不具备共享的能力,代码放到本地库,才能和中央仓库关联。
暂存区(stage):一般存放在"git目录"下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引库(index),临时存储我们的代码,想把工作区的代码放到本地库,必须要过暂存区
暂存区和本地库也是有快照的。发现有问题,可以版本切换,进行版本穿梭
分支(Branch):分支是保存代码的区域
Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD
仓库中有很多个分支(分支就是子目录)
命令名称 |
命令作用 |
git init |
初始化本地库 |
git config --global user.name 用户名 |
设置用户签名的用户名部分 |
git config --global user.email 邮箱 |
设置用户签名的邮箱部分 |
git status |
查看本地库状态 |
git add 文件名 |
添加到暂存区 |
git commit -m "日志信息" 文件名 |
提交到本地库 |
git reflog |
查看历史记录 |
git reset --hard 版本号 |
版本穿梭 |
要使用Git对我们的代码进行版本控制,首先需要获得Git仓库,获取Git仓库通常有两种方式
方式1:在本地初始化一个Git仓库
方式2:从远程仓库克隆
本地初始化操作步骤
git init 通过该命令创建本地库,会在当前目录产生.git隐藏文件夹。初始化时没有这个index文件
用老师的话说查看状态,几个区整利索了吗
untracked files 未跟踪(红色),意思是git就没管理它,它和git没有半毛钱关系
文件名是 绿色,表示已经管理到暂存区,还未提交到本地库
--------
Modified 已修改状态(红色和绿色) ,代码改了没放到本地库。红色在工作区,绿色在暂存区。
Git工作目录下的文件状态信息:
Untracked 未跟踪(未被纳入版本控制)
Tracked 已跟踪(被纳入版本控制)
Unmodified 未修改状态
Modified 已修改状态
Staged 已暂存状态
这些文件的状态会随着我们执行Git的命令发生变化
红色表示新建文件或者新修改的文件,都在工作区.
绿色表示文件在暂存区
新建的文件在工作区,需要添加到暂存区并提交到仓库区
新建并编辑文件a.txt
touch a.txt
vim a.txt
此时使用git status 查看
第一步 用“git add”把文件纳入Git管理,实际是把本地文件修改添加到暂存区
第二步 用“git commit”提交更改,实际上就是把暂存区的所有内容提交到当前分支
git add 文件名 || 添加到暂存区(栈空间、index文件)
git add . || 添加项目中所有的文件
git add a.txt 添加到暂存区
git status
初始化不会有暂存区index文件,add a.txt后才有
git reset <文件名称> 重置一定注意写清楚文件名
git reset a.txt 撤销暂存区的文件(退路)
git commit -m "日志信息" 文件名 || 提交到本地库,日志内容可以双引号也可以单引号
commit 会生成一条版本记录,add只是添加暂存区,不会生成版本记录
我们再次修改a.txt文件内容,
vim a.txt
git status
再次添加到暂存区,提交到本地仓库,这次提交的时候不加-m会怎么样
git add a.txt
git commit
事实证明:执行commit命令时不加-m 会进入编辑模式,需要填写提交日志
git commit -am "注释内容" || 添加和提交合并命令
commit -am注意,后面不能写文件名,会都add/commit
commit -am是前提已经添加过的,新创建的文件c.txt不行
版本号(唯一标识)
git log a.txt
git log --pretty=oneline
git reflog(用的多)
- 查看历史操作,版本号-7个就能标识唯一了
不方便,只能退,不能回去
一次回退一个版本,一个^代表一个版本数量
git reset --hard HEAD^
回退n次操作
git reset --hard HEAD~n
查看历史操作,然后进行版本穿梭
git reflog a.txt
git reset --hard 版本号
前提:未add,未commit(不常用)
git checkout -- a.txt(等价于idea的ctrl+Z)
前提:已add,未commit
git reset <文件名称>
创建a.txt,在里面添加内容,并把它提交到本地库。
1、此时再在工作区里看看a.txt,他还是存在的。
2.一不做二不休,把工作区的a.txt删除。此时再次查看a.txt,就找不到这个文件了
3.git status,查看
现在有俩种选择
选择一:删错了,可以从版本库里恢复最新的文件
git checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
选择二:确定要从版本库中删除该文件
rm a.txt git add a.txt git commit -m "remove a.txt"
仓库中存储代码的目录
几乎所有的版本控制系统都以某种形式支持分支,使用分支意味着你可以把你的工作从开发主线上分离开来(代码分类),以免影响开发主线。
Git 的master分支并不是一个特殊分支。 它跟其它分支没有区别。 之所以几乎每一个仓库都有 master 分支,是因为git init 命令默认创建它,并且大多数人都懒得去改动它。
命令名称 |
作用 |
git branch 分支名 |
创建分支 |
git branch -v |
查看分支 |
git checkout 分支名 |
切换分支 |
git merge 分支名 |
把指定的分支合并到当前分支上 |
git checkout -b |
创建+切换分支 |
git branch -d |
删除分支 |
HEAD指向的就是当前分支
所以切换分支的本质就是移动HEAD指针。
HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,每次提交,
master
分支都会向前移动一步,这样,随着你不断提交,master
分支的线也越来越长----------------------
创建一个新的dev分支的时候,此时,对工作区的修改和提交就是针对
dev
分支了,比如新提交一次后,dev
指针往前移动一步,而master
指针不变---------------------
合并分支
把
dev
合并到master
上。Git怎么合并呢?最简单的方法,就是直接把master
指向dev
的当前提交,就完成了合并--------------------
删除分支
删除
dev
分支就是把dev
指针给删掉,删掉后,我们就剩下了一条master
分支
修改同一个文件的同一行(冲突)
合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改。Git无法替我们决定使用哪一个。必须人为决定新代码内容。
怎么制造冲突
这里我犯过一个错,我先在hotfix分支修改了a.txt文件,然后没添加暂存区也没提交到本地仓库,我就直接切换回到master分支了,我还很蒙蔽,怎么master分支的a.txt也改了呢?
其实要是在hotfix中add,commit以后再切换,master分支中是看不到的a.txt有修改的
正确的制造冲突
第一步:在hotfix分支修改a.txt文件并add,commit.不会报错,接着切换到master分支
第二步:在master分支修改a.txt文件并add,commit,不会报错。
第三步:把hotfix分支合并到master分支,此时会报错冲突
Git会找出来并提示。
Git使用“<<<<<<<、=========、>>>>>>>>>>”符号帮我们标记出来,现在产生冲突的内容。
vim a.txt,打开发现文件是这样的
冲突的解决
①编辑有冲突的文件,删除特殊符号,决定要使用的内容
②添加到暂存区
③执行提交(注意:使用git commit命令时不能带文件名)
此时杀个回马枪,我们切换到hotfix分支,看看a.txt文件的状态,再次合并就不会产生冲突了
容易冲突的操作方式
多个人同时操作了同一个文件
一个人一直写不提交
修改之前不更新最新代码
提交之前不更新最新代码
擅自修改同事代码
养成良好的操作习惯,先`pull`在修改,修改完立即`commit`和`push`
一定要确保自己正在修改的文件是最新版本的
各自开发各自的模块
如果要修改公共文件,一定要先确认有没有人正在修改
下班前一定要提交代码,上班第一件事拉取最新代码
一定不要擅自修改同事的代码
实际情况 往往是这样,找一台电脑充当服务器的角色,每天24小时开机,其他每个人都从这个“服务器”仓库克隆一份到自己的电脑上,并且各自把各自的提交推送到服务器仓库里,也从服务器仓库中拉取别人的提交。
GitHub的网站就是提供Git仓库托管服务的,所以,只要注册一个GitHub账号,就可以免费获得Git远程仓库。
何搭建Git远程仓库呢?我们可以借助互联网上提供的一些代码托管服务来实现
gitHub https://github.com/码云 Gitee - 基于 Git 的代码托管和研发协作平台
GitLab The One DevOps Platform | GitLab
码云(本次使用)
码云是国内的一个代码托管平台,由于服务器在国内,
所以相比于GitHub,码云速度会更快GitLab
GitLab是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务
GitHub
GitHub是一个面向开源及私有软件项目的托管平台,因为只支持Git 作为唯一的版本库格式进行托管,故名gitHub
本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作。
首先进入到gitee平台中的个人主页面。然后进入到要删除的仓库的管理界面中。
点击右边的"管理"按钮。
在管理界面中,在左边点击"删除仓库"。
接着按提示操作就好了
clone:克隆,就是将远程仓库复制到本地
push:推送,就是将本地仓库代码上传到远程仓库
pull:拉取,就是将远程仓库代码下载到本地仓库
git remote add <别名> <远端地址>
git remote add orign 复制名
关联后远程库的名字就是origin
git remote -v //查看远程库信息
上面显示了可以抓取和推送的origin
的地址。如果没有推送权限,就看不到push的地址
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上。
git push <远端代号> <本地分支名称>
1、第一次推送master分支时,加上了-u参数。会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令
git push -u origin master
2、简化以后的:
git push origin master //把本地master分支的最新修改推送至远程仓库
如果使用https协议,会弹出一个框,输入登录码云的账号和密码,就可以在我们刚创建的仓库中看到推送上来的文件了
根据名字删除远程库:比如删除origin
git remote rm origin
此处的“删除”其实是解除了本地和远程的绑定关系,并不是物理上删除了远程库。远程库本身并没有任何改动。要真正删除远程库,需要登录到GitHub,在后台页面找到删除按钮再删除
git clone
git clone <远端地址> <新项目目录名>。
<项目目录名> 是指为克隆的项目在本地新建的目录名称,可以不填,默认是GitHub的项目名。
命令执行完后,会自动为这个远端地址建一个名为origin的代号
李四直接推送就行,不用再给远程仓库起别名
对a.txt进行修改,再add,commit,push
git pull origin master //张三再拉取代码
如果
git pull
提示no tracking information
则说明本地分支和远程分支的链接关系没有创建,用命令
git branch --set-upstream-to
origin/ 当然也可以这样,让本地dev分支和origin/dev关联
git branch --set-upstream-to=origin/dev dev
在push出现冲突时,解决冲突
推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,
解决办法:
先用
git pull
把最新的提交从origin/dev
抓下来,然后,在本地合并,解决冲突,add commit (commit的时候不能加文件名??)再推送
本地库提交到远程库,权限不够
管理-仓库成员管理-开发者-邀请用户
(仓库直接下载下来,没有输入密码)
控制面板-用户账户-管理windows凭据
ssh模式比https模式的一个重要好处就是,每次push,pull,fetch等操作时不用重复填写用户名密码。前提是你必须是这个项目的拥有者或合作者,且配好了ssh key
为什么GitHub需要SSH Key呢?因为GitHub需要识别出你推送的提交确实是你推送的,而不是别人冒充的,而Git支持SSH协议,所以,GitHub只要知道了你的公钥,就可以确认只有你自己才能推送。
------------
步骤1、检查电脑家目录下是否已经生成了SSH key,如果有.ssh目录删除即可
步骤2、创建SSH Key : ssh-keygen -t rsa -C lisiatguigu123
然后一路回车(3次),给账户生成公钥和私钥
步骤3、成功的话(执行命令不需要输入任何内容),会在用户主目录下生成.ssh文件夹,查看生成两个文件
这两个就是SSH Key的秘钥对,
id_rsa
是私钥,不能泄露出去,id_rsa.pub
是公钥,可以放心地告诉任何人。
打开id_rsa.pub,复制里面的内容,到gitee上
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC+v9YMeJEDdiWno/htJLyWQ/lCr1cxfucEN0eXcMK0EwgRg3QxhYVZ7rGgdJe09GUgVGZvqY/yb/VuRdHkaJmnU/PphhXsCg+ShtctRryvn/1/jvLxKm6m471asBwrqjCRZSnzEP4haPoesDvkbFz2nIuAmJARkjTW3yw5XLvV4WaAN7GxhkTPZTSMw1xWX9z+zOaRBFmA0NdLHK6c76ux2lofMNrFCA5n2UxzGuI+ykzrIIaCnAfsabYSNYi4SkfFok1EVxxgTye9kX2OUUUnDKLoyxCEwCyx9ZPfAFzcMGQ4vHci4bfRKvv1dEnaPCP9+hDnF0cobhcyTDXQ1qu4H7G7mTp+L1m+jX3U16sWHx0pXf8ZLNkmYAY6oN2n8iF83UPOYHzWyI0OV1MVGJGHNwSRAAhvEdncEpH29NlKUmR3KPtQqtWBc/5DmenMqESClZiW8gcG3zJrIpLdzHMe4HS9n8hT460QfvQqvztisByQ7gGQ49lXmsLJZ+DKuAs= shiyulong520
在远程库-用户-设置 -ssh公钥
不需要输入密码
起别名,
新建一个b.txt,add,commit,push到远程仓库
git push originssh hotfix
结果报错了??
.idea 文件夹下的文件(无效的文件)
maven工程的targer目录
为什么要忽略他们
与项目的实际功能无关,不参与服务器上部署运行。把它们忽略掉能够屏蔽IDE工具之间的差异。
1、创建忽略规则文件(git.ignore)
这个文件的存放位置原则上在哪里都可以
为了便于让~/.gitconfig文件引用,建议也放在用户家目录下
注意不要在一行里写,要换行顶格。git.ignore文件内容如下:#是注释
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
.classpath
.project
.settings
target
.idea
*.iml
2、 在.gitconfig文件中引用忽略规则文件
这里要使用“正斜线(/)”,不要使用“反斜线(\)”
[core]
excludesfile = C:/Users/Lenovo/git.ignore
可以点击右边的“test”按钮,会弹出如下框就好了
这一步,相当于git init,创建 本地仓库
VCS 版本控制系统
效果就是出现红色文件(自动状态检查)和出现.git文件夹
右键操作对象(可以是一个目录,也可以是一个单独文件),操作的效果文件会变成绿色
也是右键选择Git,Commit File或者是Commit Directory
接着点击【Git】--》【Commit Directory】在打开的窗口中选择要上传到本地仓库的代码并添加注释后提交到本地仓库内。
terminal窗口可以写git的命令
------------
新建分支hotfix
-----------------
合并分支
文件名字是蓝色的-表示已经add过了,可以直接提交到本仓库
在和远程库交互过程中也有可能发生冲突,因为解决办法一样,所以这里按照分支操作过程中产生的冲突来演示。
冲突指在同一个文件在同一个位置有不同内容。
合并分支的时候可能会有冲突:
我们把hotfix分支合并到master分支时,会弹出一个框,直接双击
直接双击,就会出来一个相当友好的界面。点击我红色框圈住的箭头或叉号,好了之后点击应用会
自动提交,重要的事情说三遍,会自动提交!会自动提交!会自动提交!
此时,master分支里是我们处理共的代码了
再切换回去到hotfix分支
此时再把master分支合并到当前的分支hotfix
,请问会产生冲突吗?不会。虽然我觉得难以理解,就当是这个冲突已经处理过了吧
安装Gitee插件
分享工程到 gitee
接着会弹出一个框
通过idea创建远程仓库
要推送其他的分支master到远程仓库,先从hotfix分支切换到master分支,再项目上右键-仓库-push
要拉取的话,和push一样,这回选择pull,因为在idea中我在master,所以拉取时默认选择的也是远程仓库的master分支
做尚医通项目的时候跟东哥学到的。前4步没变,在项目上右键add、commit之后 ,再
1. 右击项目点击【Git】--》【Repository】--》【Remotes...】。在打开的【Git Remotes】窗口中添加码云的远程仓库。码云的远程仓库地址可以在码云仓库内找到。
a
第一次使用idea上传代码到git,需要输入git仓库的用户名和密码。
2.上传代码到码云,右击项目点击【Git】--》【Repository】--》【Push...】在打开的【Push commits】内可以看到已提交到本地仓库的提交信息。点击【Push】按钮将本地仓库的代码上传到码云上,上传成功后就可以在码云上看到。
接着就可以在码云中看到了
Gitflow工作流通过为功能开发、发布准备和维护设立了独立的分支,让发布迭代过程更流畅
分支种类
主干分支 master
主要负责管理正在运行的生产环境代码。永远保持与正在运行的生产环境完全一致。
开发分支 develop
主要负责管理正在开发过程中的代码。一般情况下应该是最新的代码。
bug修理分支 hotfix
要负责管理生产环境下出现的紧急修复的代码。 从主干分支分出,修理完毕并测试上线后,并回主干分支。并回后,视情况可以删除该分支
发布版本分支 release
较大的版本上线前,会从开发分支中分出发布版本分支,进行最后阶段的集成测试。该版本上线后,会合并到主干分支。生产环境运行一段阶段较稳定后可以视情况删除。
功能分支 feature
为了不影响较短周期的开发工作,一般把中长期开发模块,会从开发分支中独立出来。 开发完成后会合并到开发分支。
git工作流程:
先pull远程仓库的最新版本
合并解决冲突
先提交到本地仓库再推送到远程仓库