Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。
Git易于学习,占地面积小,性能极快。
它具有廉价的本地库,方便的暂存区域和多个工作流分支等特性。其性能优于Subversion、CVS、Perforce和ClearCase等版本控制工具。
版本控制是一种记录文件内容变化,以便将来查阅特定版本修订情况的系统。
版本控制其实最重要的是可以记录文件修改历史记录,从而让用户能够查看历史版本,方便版本切换。
个人开发过渡到团队协作。
CVS、SVN(Subversion)、VSS…
集中化的版本控制系统诸如
CVS、SVN等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法。
这种做法带来了许多好处,每个人都可以在一定程度上看到项目中的其他人正在做些什么。而管理员也可以轻松掌控每个开发者的权限,并且管理一个集中化的版本控制系统,要远比在各个客户端上维护本地数据库来得轻松容易。
事分两面,有好有坏。这么做显而易见的缺点是中央服务器的单点故障。如果服务器宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。
Git、Mercurial、Bazaar、Darcs…
像
Git这种分布式版本控制工具,客户端提取的不是最新版本的文件快照,而是把代码仓库完整地镜像下来(本地库)。这样任何一处协同工作用的文件发生故障,事后都可以用其他客户端的本地仓库进行恢复。因为每个客户端的每一次文件提取操作,实际上都是一次对整个文件仓库的完整备份。
分布式的版本控制系统出现之后,解决了集中式版本控制系统的缺陷:
1. 服务器断网的情况下也可以进行开发(因为版本控制是在本地进行的)
2. 每个客户端保存的也都是整个完整的项目(包含历史记录,更加安全)
代码托管中心是基于网络服务器的远程代码仓库,一般我们简单称为远程库。
局域网
互联网
GitHub(外网)
Gitee码云(国内网站)
官网地址:
https://git-scm.com/或https://github.com/git-for-windows/git/releases
查看GNU协议,可以直接点击下一步。
选择Git安装位置,要求是非中文并且没有空格的目录,然后下一步。
Git选项配置,推荐默认设置,然后下一步。
Git安装目录名,不用修改,直接点击下一步。
Git的默认编辑器,建议使用默认的Vim编辑器,然后点击下一步。
修改Git的环境变量,选第一个,不修改环境变量,只在Git Bash里使用Git。
选择后台客户端连接协议,选默认值OpenSSL,然后下一步。
配置Git文件的行末换行符,Windows使用CRLF,Linux使用LF,选择第一个自动转换,然后继续下一步。
选择Git终端类型,选择默认的Git Bash终端,然后继续下一步。
选择Git pull合并的模式,选择默认,然后下一步。
选择Git的凭据管理器,选择默认的跨平台的凭据管理器,然后下一步。
其他配置,选择默认设置,然后下一步。
实验室功能,技术还不成熟,有已知的bug,不要勾选,然后点击右下角的Install按钮,开始安装Git。
点击Finsh按钮,Git安装成功!
右键任意位置,在右键菜单里选择Git Bash Here即可打开Git
Bash命令行终端。
在Git Bash终端里输入git
–version查看git版本,如图所示,说明Git安装成功。
命令名称 | 作用 |
---|---|
git config --global user.name 用户名 | 设置用户签名 |
git config --global user.email 邮箱 | 设置用户邮箱 |
git init | 初始化本地库 |
git status | 查看本地库状态 |
git add 文件名 | 添加到暂存区 |
git commit -m “日志信息” 文件名(message) | 提交到本地库 |
git reflog | 查看历史记录 |
git reset --hard 版本号 | 版本穿梭 |
在使用Git进行版本控制时,我们需要设置用户签名,主要包含:
用户名称(user.name)
用户邮箱(user.email)
用户签名用来标识提交者身份,每次Git提交都会使用以上信息标识提交者身份。多人协作开发同一个仓库时,正确设置用户签名非常重要。
语法如下:
git config --global user.name "your name"
git config --global user.email "your email"
**注意:**这里设置用户签名和将来登录GitHub(或其他代码托管中心)的账号没有任何关系。
全局范围的签名设置:
$ git config --global user.name gangge
$ git config --global user.email [email protected]
查看配置是否成功:
$ git config --list
Git本地仓库内部维护了一个完整的代码版本库,它存储了所有的版本信息和元数据,使我们有能力进行版本控制
创建一个空目录,在目录下执行如下命令:
git init
$ git init
Initialized empty Git repository in F:/git-test1/.git/
Git会在执行命令的目录下生成一个名为**.git**的隐藏目录。它就是Git本地仓库,包含所有的版本信息。
git status
工作区没有任何文件
$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
$ vim hello.txt
hello git!
检测到未追踪的文件
$ git status
On branch master
No commits yet
Untracked files:
(use "git add ..." to include in what will be committed)
hello.txt
nothing added to commit but untracked files present (use "git add" to track)
1)基本语法
git add 文件名
2)案例实操
$ git add hello.txt
warning: LF will be replaced by CRLF in hello.txt.
The file will have its original line endings in your working directory.
检测到暂存区有新文件
$ git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached ..." to unstage)
new file: hello.txt
1)基本语法
git commit -m "日志信息" 文件名
2)案例实操
$ git commit -m "my first commit hello.txt" hello.txt
warning: LF will be replaced by CRLF in hello.txt.
The file will have its original line endings in your working directory.
[master (root-commit) 86366fa] my first commit hello.txt
1 file changed, 16 insertions(+)
create mode 100644 hello.txt
没有文件需要提交
$ git status
On branch master
nothing to commit, working tree clean
$ vim hello.txt
hello git!
hello atguigu!
检测到工作区有文件被修改
$ git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git add hello.txt
warning: LF will be replaced by CRLF in hello.txt.
The file will have its original line endings in your working directory.
工作区的修改添加到了暂存区
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: hello.txt
$ git commit -m "my second commit hello.txt" hello.txt
warning: LF will be replaced by CRLF in hello.txt.
The file will have its original line endings in your working directory.
[master (root-commit) 86366fa] my secondcommit
1 file changed, 16 insertions(+)
create mode 100644 hello.txt
修改hello.txt
$ vim hello.txt
hello git!
hello atguigu!
hello shanghai!
新增文件hello2.txt
$ vim hello2.txt
hello pangju!
$ git add .
warning: LF will be replaced by CRLF in hello.txt.
The file will have its original line endings in your working directory
warning: LF will be replaced by CRLF in hello2.txt.
The file will have its original line endings in your working directory
$ git commit -m 'my first batch commit'
[master 8ac2fc4] my first batch commit
2 files changed, 2 insertions(+)
create mode 100644 hello2.txt
删除
1)基本语法
-- 查看版本信息
git reflog
-- 查看版本详细信息
git log
2)案例实操
$ git reflog
8ac2fc4 (HEAD -> master) HEAD@{0}: commit: my first batch commit
9ccfb82 HEAD@{1}: commit: my second commit hello.txt
f6c1c01 HEAD@{2}: commit (initial): my first commit hello.txt
git reset语法: 回退到某个提交
git reset --hard <commit>
$ git reflog
8ac2fc4 (HEAD -> master) HEAD@{0}: commit: my first batch commit
9ccfb82 HEAD@{1}: commit: my second commit hello.txt
f6c1c01 HEAD@{2}: commit (initial): my first commit hello.txt
8ac2fc4是当前分支所在位置
切换到f6c1c01版本,也就是我们第一次提交的版本
$ git reset --hard f6c1c01
HEAD is now at f6c1c01 my first commit hello.txt
查看版本切换后的版本日志:
$ git reflog
f6c1c01 (HEAD -> master) HEAD@{0}: reset: moving to f6c1c01
8ac2fc4 HEAD@{1}: commit: my first batch commit
9ccfb82 HEAD@{2}: commit: my second commit hello.txt
f6c1c01 (HEAD -> master) HEAD@{3}: commit (initial): my first commit hello.txt
查看版本切换后hello.txt文件的内容:
$ cat hello.txt
hello git!
切换回8ac2fc4,也就是最后一次提交的版本:
$ git reset --hard 8ac2fc4
HEAD is now at 8ac2fc4 my first batch commit
Git切换版本,底层其实是移动的HEAD指针。
在版本控制过程中,同时推进多个任务,为每个任务,我们就可以创建每个任务的单独分支。使用分支意味着程序员可以把自己的工作从开发主线上分离开来,开发自己分支的时候,不会影响主线分支的运行。对于初学者而言,分支可以简单理解为副本,一个分支就是一个单独的副本。(分支底层其实也是指针的引用)
线上一般存在以下的分支:master(线上),develop(开发),release(预发布),hotfix(线上bug修复)
master
: 主分支;主要是稳定的版本分支,正式发布的版本都从Master拉。develop:
开发分支;更新和变动最频繁的分支,正常情况下开发都是在Develop分支上进行的。release
:预发行分支;一般来说,代表一个版本的功能全部开发完成后递交测试,测试出Bug后进行修复的分支。features
: 功能分支; 其实Features不是一个分支,而是一个分支文件夹。里面包含了每个程序员开发的功能点。Feature开发完成后合入Develop分支。hotfix
: 紧急故障修复分支(如现场故障),内部分支,从master拉出此分支,merge到master和develop分支。最希望不会被创建的分支;这个分支的存在是在已经正式上线的版本中,发现了重大Bug进行修复的分支。同时并行推进多个功能开发,提高开发效率。
各个分支在开发过程中,如果某一个分支开发失败,不会对其他分支有任何影响。失败的分支删除重新开始即可。
命令名称 | 作用 |
---|---|
git branch 分支名 | 创建分支 |
git branch -v | 查看分支 |
git checkout 分支名 | 切换分支 |
git merge 分支名 | 把指定的分支合并到当前分支上 |
1)基本语法
git branch -v
2)案例实操
*代表当前所在的分支
$ git branch -v
* master 8ac2fc4 my first batch commit
1)基本语法
git branch 分支名
2)案例实操
创建分支:
$ git branch hot-fix
查看分支:新创建的分支与当前分支的历史相同,直到我们在这两个分支分别做出新的提交,它们的历史才会产生分歧。
$ git branch -v
hot-fix 8ac2fc4 my first batch commit
* master 8ac2fc4 my first batch commit
master分支修改hello.txt并提交:
$ vim hello.txt
hello git!
hello atguigu!
hello shanghai!
hello master update!
$ git add .
$ git commit -m 'master分支第一次提交更新'
[master d51987a] master分支第一次提交更新
1 file changed, 1 insertion(+)
查看分支:
$ git branch -v
hot-fix 8ac2fc4 my first batch commit
* master d51987a master分支第一次提交更新
git checkout 分支名
切换分支:
$ git checkout hot-fix
Switched to branch 'hot-fix'
查看分支:
$ git branch -v
* hot-fix 8ac2fc4 my first batch commit
master d51987a master分支第一次提交更新
查看hello.txt内容:和master分支的hello文件内容不一样
$ cat hello.txt
hello git!
hello atguigu!
hello shanghai!
hot-fox分支修改hello.txt并提交:
$ vim hello.txt
hello git!
hello atguigu!
hello shanghai!
hello hot-fix update!
$ git add .
$ git commit -m 'hot-fix分支第一次修改提交'
[hot-fox ea6f7ba] hot-fix分支第一次修改提交
1 file changed, 1 insertion(+)
当我们在不同分支上开发某个功能时,完成开发后需要通过分支合并,将这些功能集成到一起。
git merge 分支名
在master分支上合并hot-fix分支
切换到master分支:
$ git checkout master
Switched to branch 'master'
合并hot-fix分支:(master|MERGING)状态表示有冲突
$ git merge hot-fix
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.
冲突产生的表现:后面状态为MERGING
atguigu@DESKTOP-ECRD6S9 MINGW64 /f/git-test1 (master|MERGING)
$ cat hello.txt
hello git!
hello atguigu!
hello shanghai!
<<<<<<< HEAD
hello master update!
=======
hello hot-fix update!
>>>>>>> hot-fix
冲突产生的原因:
合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改。Git无法替我们决定使用哪一个。必须人为决定新代码内容。
查看状态(检测到有文件有两处修改)
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add ..." to mark resolution)
both modified: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
删除特殊符号,决定要使用的内容
特殊符号:<<<<<<< HEAD 当前分支的代码 ======= 合并过来的代码
>>>>>>> hot-fix
$ vim hello.txt
hello git!
hello atguigu!
hello shanghai!
hello master update!
hello hot-fox update!
添加到暂存区:
$ git add .
提交到本地仓库:
$ git commit -m 'master分支合并hot-fix分支解决冲突提交'
[master 37acde7] master分支合并hot-fix分支解决冲突提交
合并解决冲突提交后 MERGING状态消失
hot-fix分支已经使用完毕,可以删除
删除已合并的分支
git branch -d <branch_name>
查看分支:
$ git branch -v
hot-fix ea6f7ba hot-fix分支第一次修改提交
* master 37acde7 master分支合并hot-fix分支解决冲突提交
删除hot-fix分支:
$ git branch -d hot-fix
Deleted branch hot-fix (was ea6f7ba).
再次查看分支:
$ git branch -v
* master 37acde7 master分支合并hot-fix分支解决冲突提交
master、hot-fix其实都是指向具体版本记录的指针。当前所在的分支,其实是由HEAD决定的。所以创建分支的本质就是多创建一个指针。
HEAD如果指向master,那么我们现在就在master分支上,HEAD如果执行hotfix,那么我们现在就在hotfix分支上。
所以切换分支的本质就是移动HEAD指针。
前面我们已经知道了Git中存在两种类型的仓库,即本地仓库和远程仓库。那么我们如何搭建Git远程仓库呢?我们可以借助互联网上提供的一些代码托管服务来实现,其中比较常用的有GitHub、码云、GitLab等。
是一个面向开源及私有软件项目的托管平台,因为只支持Git
作为唯一的版本库格式进行托管,故名gitHub
是国内的一个代码托管平台,由于服务器在国内,所以相比于GitHub,码云速度会更快
是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务
gitee是一个基于git的代码托管平台, Git 并不像 SVN
那样有个中心服务器。目前我们使用到的 Git
命令都是在本地执行,如果你想通过 Git
分享你的代码或者与其他开发人员合作。
你就需要将数据放到一台其他开发人员能够连接的服务器上。
远程仓库工作流程:
查看远程仓库
添加远程仓库
克隆远程仓库
移除无效的远程仓库
从远程仓库中抓取与拉取
推送到远程仓库
进入码云官网地址:https://gitee.com/,点击注册Gitee
输入个人信息,进行注册即可。
帐号注册成功以后,直接登录。
登录以后,就可以看到码云官网首页了。
命令名称 | 作用 |
---|---|
git remote -v | 查看当前所有远程地址别名 |
git remote add 别名 远程地址 | 起别名 |
git push 别名 分支 | 推送本地分支上的内容到远程仓库 |
git clone 远程地址 | 将远程仓库的内容克隆到本地 |
git pull 远程库地址别名 远程分支名 | 将远程仓库对于分支最新内容拉下来后与当前本地分支直接合并 |
git remote -v 查看当前所有远程地址别名
git remote add 别名 远程地址
$ git remote -v
使用上面新建远程仓库后的地址
$ git remote add origin https://gitee.com/xgatguigu/git-test.git
$ git remote -v
origin https://gitee.com/xgatguigu/git-test.git (fetch)
origin https://gitee.com/xgatguigu/git-test.git (push)
git push 别名 分支
推送时需要输入远程仓库的账号密码,参考5.4.2.2第2小节
$ git push origin master
Enumerating objects: 19, done.
Counting objects: 100% (19/19), done.
Delta compression using up to 12 threads
Compressing objects: 100% (13/13), done.
Writing objects: 100% (19/19), 1.67 KiB | 342.00 KiB/s, done.
Total 19 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.4]
To https://gitee.com/xgatguigu/git-test.git
* [new branch] master -> master
注意:密码错误推送会失败
刷新仓库发现已将我们master分支上的内容推送到Gitee创建的远程仓库。
git clone 远程地址
$ git clone https://gitee.com/xgatguigu/git-test.git
Cloning into 'git-test'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 19 (delta 1), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (19/19), done.
Resolving deltas: 100% (1/1), done.
进入git-test执行
clone会做如下操作:
选择仓库中要更新的文件编辑:
编辑并提交更新:
1)基本语法
git pull 远程库地址别名 远程分支名
2)案例实操
协作者修改了仓库代码,现在第一个用户可以把远程仓库的更新拉取下来到本地直接合并:
$ git pull origin master
查看拉取后的文件:
$ cat hello.txt
hello git!
hello atguigu!
hello shanghai!
hello master update!
hello hot-fix update!
用户2(协作用户)更新!!!!
远程仓库中除了使用Https方式连接,还可以通过SSH地址连接。
$ ssh-keygen.exe -t rsa -C '[email protected]'
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/xugang/.ssh/id_rsa):
**注意:**这里的[email protected]只是生成的 sshkey的名称,可以随意编写,rsa是生成密钥对的加密算法。
按照提示三次回车,即可生成 ssh密钥对,在上面提示的路径下可以查看秘钥文件内容
复制生成后的 id_rsa.pub文件内的公钥
远程仓库配置公钥:
主页 「管理」->「部署公钥管理」->「添加部署公钥」
添加后,在终端(Terminal)中输入
$ ssh -T [email protected]
显示如下内容代表成功:
Hi xugang! You've successfully authenticated, but GITEE.COM does not provide shell access.
添加成功后,就可以使用SSH协议对仓库进行操作了。
创建springboot项目:git-test3
工作过程中产生的日志、缓存文件,编辑器产生的特定、临时文件,敏感信息配置文件以及视频、安装包等较大文件并不适合纳入版本管理。这些文件可以忽略掉。
忽略文件的目的:
在项目根目录下创建
忽略规则文件名:.gitignore
以行为单位定义忽略模式
支持通配符:
*
匹配0或N个字符、?
匹配一个字符
#
:注释行
/
:忽略当前路径
例如:target/ 表示忽略目录
*
:用来匹配零或多个字符
例如:*.class 表示忽略所有以.class结尾的文件
!
:否定忽略
例如:*.class 表示忽略所有以.class结尾的文件,使用 !A.class 可以取消A.class的忽略
配置需要忽略的文件:
右键点击项目选择Git -> Add将项目添加到暂存区。
为了方便测试,项目可以多次修改提交。
在IDEA的左下角,点击Git,然后点击Log查看版本
右键选择要切换的版本,然后在菜单里点击Checkout Revision。
选择Git,点击Branches按钮。
在弹出的Git Branches框里,点击New Branch按钮。
填写分支名称,创建hot-fix分支。
然后再IDEA的右下角看到hot-fix,说明分支创建成功,并且当前已经切换成hot-fix分支
在IDEA窗口的右下角,切换到master分支。
先在hot-fix分支修改文件并提交
在IDEA窗口的右下角,将hot-fix分支合并到当前master分支。
如果代码没有冲突,分支直接合并成功,分支合并成功以后的代码自动提交,无需手动提交本地库。
如图所示,如果master分支和hot-fix分支都修改了相同文件代码,在合并分支的时候就会发生冲突。
master分支修改AController并提交:
切换到hot-fix分支修改AController并提交:
我们现在站在master分支上合并hot-fix分支,就会发生代码冲突。
点击Conflicts框里的Merge按钮,进行手动合并代码。
手动合并完代码以后,点击右下角的Apply按钮。
代码冲突解决,自动提交本地库。
Idea默认不带码云插件,我们第一步要安装Gitee插件。
如图所示,在Idea插件商店搜索Gitee,然后点击右侧的Install按钮。
Idea链接码云和链接GitHub几乎一样,安装成功后,重启Idea。
Idea重启以后在Version Control设置里面看到Gitee,说明码云插件安装成功。
然后在码云插件里面添加码云帐号,我们就可以用Idea连接码云了。
对于已经通过git本地仓库管理的项目,可以直接推送到git远程仓库
IDEA右下角会有推送结果提示,下图所示表示推送成功:
只要码云远程库链接定义好以后,对码云远程库进行pull和clone的操作和GitHub相同
手动在gitee远程仓库中编辑项目代码
IDEA中拉取更新:右键点击项目,可以将远程仓库的内容pull到本地仓库。
注意:pull是拉取远端仓库代码到本地,如果远程库代码和本地库代码不一致,会自动合并,如果自动合并失败,还会涉及到手动解决冲突的问题。
研究开源项目、或者公司项目协作开发时,项目都会提交到远程仓库管理,一般我们会先将项目克隆到本地使用。
获取开源仓库地址:
等待克隆仓库文件下载成功后,按照上面的选择会创建新的工作空间并打开:如下图所示
码云提供了直接复制GitHub项目的功能,方便我们做项目的迁移和下载。
具体操作如下:
将GitHub的远程库HTTPS链接复制过来,点击导入按钮即可。
如果GitHub项目更新了以后,在码云项目端可以手动重新同步,进行更新!
如果出现401等情况连接不上的,是因为网络原因,可以使用以下方式连接:
然后去GitHub账户上设置token。
点击生成token。
复制红框中的字符串到idea中。
点击登录。
来到GitHub中发现已经帮我们创建好了gitTest的远程仓库。
右键点击项目,可以将当前分支的内容push到GitHub的远程仓库中。
注意:push是将本地库代码推送到远程库,如果本地库代码跟远程库代码版本不一致,push的操作是会被拒绝的。也就是说,要想push成功,一定要保证本地库的版本要比远程库的版本高!因此一个成熟的程序员在动手改本地代码之前,一定会先检查下远程库跟本地代码的区别!如果本地的代码版本已经落后,切记要先pull拉取一下远程库的代码,将本地代码更新到最新以后,然后再修改,提交,推送!
右键点击项目,可以将远程仓库的内容pull到本地仓库。
注意:pull是拉取远端仓库代码到本地,如果远程库代码和本地库代码不一致,会自动合并,如果自动合并失败,还会涉及到手动解决冲突的问题。
为clone下来的项目创建一个工程,然后点击Next。
远程仓库操作时:
先克隆远程仓库,将克隆的仓库文件夹导入到工作空间,进行二次开发
编写功能后可以提交更新到本地仓库后再推送到远程仓库
)
点击上图新建分支按钮新建分支
为了区分,可以在远程仓库切换到hotfix分支后 修改文件提交
语法:
git clone -b 远程分支名 远程仓库地址
实操:
git clone -b hotfixt-20230511 https://gitee.com/xgatguigu/git-test3.git
查看克隆结果
语法:
git push <远程主机名> <本地分支名>:<远程分支名>
实操:
修改文件提交到本地仓库:
vim pom.xml
git add .
git commit -m '本地修改hotfix分支文件提交'
推送更新到远程仓库指定分支:
git push origin hotfixt-20230511:hotfixt-20230511
回到master分支查看合并结果: