Git 分布式版本控制工具
1、目标
-
了解Git基本概念
-
能够概述git工作流程
-
能够使用Git常用命令
-
熟悉Git代码托管服务
-
能够使用idea操作 git
2. 概述
2.1 开发中的实际场景
-
场景一:备份
-
场景二:代码还原
-
场景三:协同开发
-
场景四:追溯问题代码的编写人和编写时间!
2.2、版本控制器的方式
- 集中式版本控制工具
集中式版本控制工具,版本库是集中存放在中央服务器的,team里每个人work时从中央服务器下载代码,是必须联网才能工作,局域网或互联网。个人修改后然后提交到中央版本库。
举例:SVN和CVS
- 分布式版本控制工具
分布式版本控制系统没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样工作的时候,无 需要联网了,因为版本库就在你自己的电脑上。多人协作只需要各自的修改推送给对方,就能互相看到对方的修改了。
举例:Git
Git 和 GitHub 详解
一、Git 基础
1. Git
Git是分布式的,Git不需要有中心服务器,我们每台电脑拥有的东西都是一样的。我们使用Git并且有个中心服务器,仅仅是为了方便交换大家的修改,但是这个服务器的地位和我们每个人的PC是一样的。我们可以把它当做一个开发者的pc就可以就是为了大家代码容易交流不关机用的。没有它大家一样可以工作,只不过“交换”修改不方便而已。
git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。Git是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 同生活中的许多伟大事物一样,Git 诞生于一个极富纷争大举创新的年代。Linux 内核开源项目有着为数众多的参与者。绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002 年间)。到 2002 年,整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代 码。
到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了 Linux 内核社区免费使用 BitKeeper 的权力。 这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds)基于使用 BitKeeper 时的经验教训,开发出自己的版本系统。 他们对新的系统制订了若干目标:
- 速度(很快的)
- 简单的设计
- 对非线性开发模式的强力支持(允许成千上万个并行开发的分支----可以多人同时开发)
- 完全分布式
- 有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)
2. Git 下载和安装
-
下载地址:
https://git-scm.com/downloads -
使用默认值安装
- 使用 Git Bash 中演示的时候,会用到一些基本的linux命令:
- ls / ll : 查看当前目录
- cat : 查看文件内容
- touch : 创建文件
- vi : vi编辑器(使用 vi 编辑器是为了方便展示效果,其他的编辑器也可以)
-
资源管理器内单击鼠标右键选择
Git Bash Here
-
输入
git --version
检查是否安装成功 -
或者说我们在电脑里面的任意位置右键会有 Git GUI Here 和 Git Bash 也说明安装成功了
- Git GUI:Git提供的图形界面工具
- Git Bash:Git提供的命令行工具
-
当安装Git后首先要做的事情是设置用户名称和email地址。这是非常重要的,因为每次Git提交都会使用该用户信息。
3. Git 基本工作流程
命令解析如下:
- clone(克隆): 从远程仓库中克隆代码到本地仓库
- checkout (检出):从本地仓库中检出一个仓库分支然后进行修订
- add(添加): 在提交前先将代码提交到暂存区
- commit(提交): 提交到本地仓库。本地仓库中保存修改的各个历史版本
- fetch (抓取) : 从远程库抓取到本地仓库,不进行任何的合并动作,一般操作比较少。
- pull (拉取) : 从远程库拉到本地库,自动进行合并(merge),然后放到到工作区,相当于 fetch+merge
- push(推送) : 修改完成后,需要和团队成员共享代码时,将代码推送到远程仓库
主要涉及到四个关键点:
-
工作区:本地电脑存放项目文件的地方,比如 learnGitProject 文件夹;
-
暂存区(Index/Stage):在使用 git 管理项目文件的时候,其本地的项目文件会多出一个.git 的文件夹,将这个.git 文件夹称之为版本库。其中.git 文件夹中包含了两个部分,一个是暂存区(Index 或者 Stage),顾名思义就是暂时存放文件的地方,通常使用 add 命令将工作区的文件添加到暂存区里;
-
本地仓库:.git 文件夹里还包括 git 自动创建的 master 分支,并且将 HEAD 指针指向 master 分支。使用 commit 命令可以将暂存区中的文件添加到本地仓库中;
-
远程仓库:不是在本地仓库中,项目代码在远程 git 服务器上,比如项目放在 github 上,就是一个远程仓库,通常使用 clone 命令将远程仓库拷贝到本地仓库中,开发后推送到远程仓库中即可;
日常开发时代码实际上放置在工作区中,也就是本地的 XXX.java 这些文件,通过 add 等这些命令将代码文教提交给暂存区(Index/Stage),也就意味着代码全权交给了 git 进行管理,之后通过 commit 等命令将暂存区提交给 master 分支上,也就是意味打了一个版本,也可以说代码提交到了本地仓库中。另外,团队协作过程中自然而然还涉及到与远程仓库的交互。
因此,经过这样的分析,git 命令可以分为这样的逻辑进行理解和记忆:
-
git 管理配置的命令;几个核心存储区的交互命令:
-
工作区与暂存区的交互;
-
暂存区与本地仓库(分支)上的交互;
-
本地仓库与远程仓库的交互。
工作目录 | 暂存区 | git 仓库 | 远程仓库 |
---|---|---|---|
被 Git 管理的项目 | 临时存放被修改的文件 | 目录用于存放提交记录 | 远程代码仓库 |
git init | git add | git commit | git push |
4. Git 使用前的配置命令
在使用前告诉 git 你是谁:
4.1 第一次使用 git,配置用户信息
- 配置用户名:
git config --global user.name "your name"
; - 配置用户邮箱:
git config --global user.email "youremail@github.com"
;
4.2查询配置信息
- 列出当前配置:
git config --list
; - 列出 repository 配置:
git config --local --list
; - 列出全局配置:
git config --global --list
; - 列出系统配置:
git config --system --list
;
4.3其他配置
-
配置解决冲突时使用哪种差异分析工具,比如要使用 vimdiff:
git config --global merge.tool vimdiff
; -
配置 git 命令输出为彩色的:
git config --global color.ui auto
; -
配置 git 使用的文本编辑器:
git config --global core.editor vi
;
注:
- 更改–>重复上述命令
- 也可直接修改
C:\Users\用户\.gitconfig
4.5 为一些常用的指令配置别名
有些常用的指令参数非常多,每次都要输入好多参数,为了稍微可以方便一点点,我们可以使用别名。
4.5.1打开用户目录,创建 .bashrc 文件
部分windows系统不允许用户创建点号开头的文件,可以打开gitBash,执行
touch ~/.bashrc
4.5.2 在 .bashrc 文件中输入如下内容(下面命名的别名只是我们的示例内容):
#用于输出git提交日志 (用新名字 git-log 来指代之前的 git log --pretty=oneline --all --graph --abbrev-commit 这个旧名字)
alias git-log='git log --pretty=oneline --all --graph --abbrev-commit'
#用于输出当前目录所有文件及基本信息
alias ll='ls -al'
注意: 如果使用的是 vi 编辑器的话,vi 退出编辑器的时候,按 esc,输入冒号(英文),然后切换到最后一行的模式,之后一行的模式决定了是否保存文件。
4.5.3打开gitBash,执行
source ~/.bashrc
4.5.4 解决 GitBash乱码问题
-
打开GitBash执行下面命令
git config --global core.quotepath false
-
${git_home}/etc/bash.bashrc 文件最后加入下面两行
export LANG="zh_CN.UTF-8" export LC_ALL="zh_CN.UTF-8"
5. 创建本地仓库
要使用 Git 对我们的代码进行版本控制,首先需要我们获取本地仓库
-
在电脑的任意位置创建一个空目录(比如:example)作为我们的本地 Git 仓库
-
进入这个目录中,点击右键打开 Git Bash 窗口
-
执行命令 git init
-
如果创建成功的话,就可以在文件夹下面看到隐藏的 .git 目录了
(命令窗口里面会显示:Initialized empty Git repository in your path—已经初始化了一个空项目)
6. 工作区上的操作命令
Git 工作目录下对于文件的修改(增加、删除、更新)会存在几个状态,这些修改的状态会随着我们执行Git 的命令而发生变化。
- git add (工作区 --> 暂存区)
- git commit (暂存区 --> 本地仓库)
6.1git init
初始化 git 仓库
新建仓库
- 将工作区中的项目文件使用 git 进行管理,即创建一个新的本地仓库:
git init
;- 从远程 git 仓库复制项目:
git clone
; 克隆项目时如果想定义新的项目名,可以在 clone 命令后指定新的项目名:git clone git://github.com/wasd/example.git NewName
;
6.2git status
查看文件状态
查新信息
- 查询当前工作区所有文件的状态:
git status
; (我们直接使用 touch 文件名 来创建文件)- 比较工作区中当前文件和暂存区之间的差异,也就是修改之后还没有暂存的内容:git diff;指定文件在工作区和暂存区上差异比较:
git diff
;
6.3 git add 文件/文件列表
提交到暂存区
提交
- 提交工作区所有文件到暂存区:
git add .
- 提交工作区中指定文件到暂存区:
git add ...
;- 提交工作区中某个文件夹中所有文件到暂存区:
git add [dir]
;
6.4git commit -m 提交信息
向仓库提交代码
提交文件到版本库
- 将暂存区中的文件提交到本地仓库中,即打上新版本(后面的双引号里面的内容是本次提交的版本的 提示信息):
git commit -m "commit_info"
;- 将所有已经使用 git 管理过的文件暂存后一并提交,跳过 add 到暂存区的过程:
git commit -a -m "commit_info"
;- 提交文件时,发现漏掉几个文件,或者注释写错了,可以撤销上一次提交:
git commit --amend
;
6.5git log
查看提交记录
查看信息
- 比较暂存区与上一版本的差异:
git diff --cached
;- 指定文件在暂存区和本地仓库的不同:
git diff --cached
;- 查看提交历史:git log;参数
-p
展开每次提交的内容差异,用-2
显示最近的两次更新,如git log -p -2
;- 带有参数的查看提交日志 :git log [option]
- –all 显示所有分支
- –pretty=online 将提交信息显示为一行
- –abbrev-commit 使得输出的 commitId (每一次提交所生成的标识码) 更加的简短。
- –graph 以图的形式显示
6.6git reset 版本切换
版本切换
- 回退到指定的版本 :git reset --hard commitID
这里面的这个 (commitID ) 我们可以通过 git log 指令进行查看(如果配置别名的话,也可以使用 git-log 指令查看)
- 查看我们已经删除的记录:git reflog ( 可以查看我们的操作记录 )
6.7 添加问价到忽略列表:
创建 .gitignore 文件,里面输入我们要忽略的文件匹配名称
一般我们总会有些文件无需纳入Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以在工作目录中创建一个名为 .gitignore 的文件(文件名称固定),列出要忽略的文件模式。
下面是一个示例:(一般这种文件都说是已经给出的,我们只需要复制到我们的代码里面是使用就可以了)
# no .a files
*.a
# but do track lib .a, even though you are ignoring .a files above
!lib.a
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
# ignore all files in the build/ directory
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .pdf files in the doc/ directory
doc/**/*.pdf
使用案例:
7. 撤销
-
用暂存区中的文件覆盖工作目录中的文件:
git checkout -- 文件名
不加-- 文件名
则覆盖全部文件 -
将文件从暂存区中删除:
git rm --cached 文件名
-
将 git 仓库中指定的更新记录恢复出来,并且覆盖暂存区和工作目录:
git reset --hard commitID
-
撤销
- 删除工作区文件,并且也从暂存区删除对应文件的记录:
git rm
; - 从暂存区中删除文件,但是工作区依然还有该文件:
git rm --cached
; - 取消暂存区已经暂存的文件:
git reset HEAD ...
; - 撤销上一次对文件的操作:
git checkout --
。要确定上一次对文件的修改不再需要,如果想保留上一次的修改以备以后继续工作,可以使用 stashing 和分支来处理; - 隐藏当前变更,以便能够切换分支:
git stash
; - 查看当前所有的储藏:
git stash list
; - 应用最新的储藏:
git stash apply
,如果想应用更早的储藏:git stash apply stash@{2}
;重新应用被暂存的变更,需要加上--index
参数:git stash apply --index
; - 使用 apply 命令只是应用储藏,而内容仍然还在栈上,需要移除指定的储藏:
git stash drop stash{0}
;如果使用 pop 命令不仅可以重新应用储藏,还可以立刻从堆栈中清除:git stash pop
; - 在某些情况下,你可能想应用储藏的修改,在进行了一些其他的修改后,又要取消之前所应用储藏的修改。Git 没有提供类似于 stash unapply 的命令,但是可以通过取消该储藏的补丁达到同样的效果:
git stash show -p stash@{0} | git apply -R
;同样的,如果你沒有指定具体的某个储藏,Git 会选择最近的储藏:git stash show -p | git apply -R
;
更新文件
- 重命名文件,并将已改名文件提交到暂存区:
git mv [file-original] [file-renamed]
;
- 删除工作区文件,并且也从暂存区删除对应文件的记录:
二、Git 进阶
1. 分支
使用分支意味着你可以把你的工作从开发主线上分离开来进行重大的Bug修改、开发新的功能,以免影响开发主线。或者说是在创建分支的时候生成一个副本,新创建的分支里面的内容就是这个副本里面的内容,避免影响开发主线。
1.1分支细分
- 主分支(master):第一次向 git 仓库提交更新记录时自动产生的一个分支。
- 开发分支(develop):作为开发的分支,基于 master 分支创建。
- 功能分支(feature):作为开发具体功能的分支基于开发分支创建。
1.2分支命令
git branch
查看分支 ()git branch 分支名称
创建分支git checkout 分支名称
切换分支git merge 来源分支
合并分支git branch -d 分支名称
删除分支(分支合并后才允许被删除)(-D 大写强制删除)git push origin :branch-name
: 远程仓库同步删除掉的分支
注意:
开发分支文件后要 commit
后再切换主分支,否则分支文件会出现在主分支里面。
使用 git log 显示的时候,HEAD 指向的分支就是我们当前所在的分支
在当前分支的时候,不能删除当前分支,只能删除其他分支
分支管理
- 创建分支:
git branch
,如git branch testing
;- 从当前所处的分支切换到其他分支:
git checkout
,如git checkout testing
;- 新建并切换到新建分支上:
git checkout -b
;- 删除分支:
git branch -d
;(-d 删除分支的时候,需要进行各种检查,比如说我们对一个分支进行了修改之后并没有将该分支合并到其他分支上面,这个时候我们使用 -d 删除的话,他会有提示显示,而且删除失败;-D 删除分支的时候,不作任何检查,直接强制进行删除)- 将当前分支与指定分支进行合并:
git merge
;- 显示本地仓库的所有分支:
git branch
;- 查看各个分支最后一个提交对象的信息:
git branch -v
;- 查看哪些分支已经合并到当前分支:
git branch --merged
;- 查看当前哪些分支还没有合并到当前分支:
git branch --no-merged
;- 把远程分支合并到当前分支:
git merge /
,如git merge origin/serverfix
;如果是单线的历史分支不存在任何需要解决的分歧,只是简单的将 HEAD 指针前移,所以这种合并过程可以称为快进(Fast forward),而如果是历史分支是分叉的,会以当前分叉的两个分支作为两个祖先,创建新的提交对象;如果在合并分支时,遇到合并冲突需要人工解决后,再才能提交;- 在远程分支的基础上创建新的本地分支
:git checkout -b /
,如git checkout -b serverfix origin/serverfix
;- 从远程分支 checkout 出来的本地分支,称之为跟踪分支。在跟踪分支上向远程分支上推送内容:
git push
。该命令会自动判断应该向远程仓库中的哪个分支推送数据;在跟踪分支上合并远程分支:git pull
;- 将一个分支里提交的改变移到基底分支上重放一遍:
git rebase
,如git rebase master server
,将特性分支 server 提交的改变在基底分支 master 上重演一遍;使用 rebase 操作最大的好处是像在单个分支上操作的,提交的修改历史也是一根线;如果想把基于一个特性分支上的另一个特性分支变基到其他分支上,可以使用--onto
操作:git rebase --onto
,如git rebase --onto master server client
;使用 rebase 操作应该遵循的原则是:一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行 rebase 操作;
1.3分支冲突
当两个分支上对文件的修改可能会存在冲突,例如同时修改了同一个文件的同一行(如果不是同一行的话,系统会给你自动合并的),这时就需要手动解决冲突,解决冲突步骤如下:
-
处理文件中冲突的地方(有冲突的地方,我们可以直接进入对应的文件里面,根据不同分支里面的内容信息,进行选择性删除保存,最后 add commit 就行了)
-
将解决完冲突的文件加入暂存区(add)
-
提交到仓库(commit)
示例代码如下(这里面我们使用了vi 编辑器):
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git branch #查看一下当前我们的分支(默认的有一个 master 分支)
* master
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git branch dev #创建 dev 分支
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git branch #查看分支--当前在 master 分支里面
dev
* master
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git checkout dev #切换到 dev 分支下面
Switched to branch 'dev'
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (dev)
$ touch file2.txt #创建新文件 file2.txt
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (dev)
$ vi file2.txt #使用 vi 编辑器 编辑 dev 分支下的文件 file2.txt,写入内容 count-dev
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (dev)
$ git add .
warning: LF will be replaced by CRLF in file2.txt.
The file will have its original line endings in your working directory
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (dev)
$ git commit -m "dev-2" # commit 提交到本地的代码仓库
[dev 33e8925] dev-2
1 file changed, 1 insertion(+)
create mode 100644 file2.txt
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (dev)
$ git checkout master #切换到 master 分支下面,此时我们会发现,我们刚刚在 dev 分支下创建的 file2.txt 文件在我们的文件夹的窗口里面看不到,如果此时再将分支切换为 dev ,就可以看到,这就是体现的我们使用分支的好处之一(或者说为什么使用分支)
Switched to branch 'master'
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ touch file2.txt #创建新文件 file2.txt
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ vi file2.txt #使用 vi 编辑器 编辑 dev 分支下的文件 file2.txt,写入内容 count-master
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git add .
warning: LF will be replaced by CRLF in file2.txt.
The file will have its original line endings in your working directory
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git commit -m "master-2" # commit 提交到本地的代码仓库
[master b9f4ad9] master-2
1 file changed, 1 insertion(+)
create mode 100644 file2.txt
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git merge dev #将 dev 分支合并到当前分支(master)里面
CONFLICT (add/add): Merge conflict in file2.txt #提示合并冲突
Auto-merging file2.txt
Automatic merge failed; fix conflicts and then commit the result. #合并失败(提示处理冲突后重新提交)
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master|MERGING)
$ cat file2.txt # 查看 冲突文件 file2.txt
<<<<<<< HEAD # 表示当前分支(下面的内容是当前分支下的冲突文件的冲突内容)
count-master
=======
count-dev
>>>>>>> dev # 表示要合并的分支(上面的内容是该分支下的冲突文件的冲突内容)
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master|MERGING)
$ vi file2.txt #使用 vi 编辑器 编辑 当前 分支下的文件 file2.txt(冲突文件),写入内容 what we want to write
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master|MERGING)
$ cat file2.txt #查看我们编辑之后的冲突文件
what we want to write
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master|MERGING)
$ git add .
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master|MERGING)
$ git commit -m "update what we want" #提交到本地的仓库
[master e1e8740] update what we want
1.4 开发中分支使用原则与流程
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来进行重大的Bug修改、开发新的功能,以免影响开发主线。
在开发中,一般有如下分支使用原则与流程:
-
master (生产) 分支:线上分支,主分支,中小规模项目作为线上运行的应用对应的分支;
-
develop(开发)分支:是从master创建的分支,一般作为开发部门的主要开发分支,如果没有其他并行开发不同期上线要求,都可以在此版本进行开发,阶段开发完成后,需要是合并到master分支,准备上线。
-
feature/xxxx分支:从develop创建的分支,一般是同期并行开发,但不同期上线时创建的分支,分支上的研发任务完成后合并到develop分支,之后该分支可以删除。
-
hotfix/xxxx分支:从master派生的分支,一般作为线上bug修复使用,修复完成后需要合并到master、test、develop分支。
-
还有一些其他分支,在此不再详述,例如test分支(用于代码测试)、pre分支(预上线分支)等
等。
2.暂时保存更改
git 中可以不提交更改,只提取分支上所有改动并储存,让开发人员得到一个干净的副本,临时转向其它工作。复制到“剪切板”,可以“粘贴“到其它分支。
场景:
- 储存临时改动:
git stash
- 恢复临时改动:
git stash pop
3. 打标签
Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。
-
列出现在所有的标签:
git tag
; -
使用特定的搜索模式列出符合条件的标签,例如只对 1.4.2 系列的版本感兴趣:
git tag -l "v1.4.2.*"
; -
创建一个含附注类型的标签,需要加
-a
参数,如git tag -a v1.4 -m "my version 1.4"
; -
使用 git show 命令查看相应标签的版本信息,并连同显示打标签时的提交对象:
git show v1.4
; -
如果有自己的私钥,可以使用 GPG 来签署标签,只需要在命令中使用
-s
参数:git tag -s v1.5 -m "my signed 1.5 tag"
; -
验证已签署的标签:git tag -v ,如
git tag -v v1.5
; -
创建一个轻量级标签的话,就直接使用 git tag 命令即可,连
-a
,-s
以及-m
选项都不需要,直接给出标签名字即可,如git tag v1.5
; -
将标签推送到远程仓库中:git push origin ,如
git push origin v1.5
; -
将本地所有的标签全部推送到远程仓库中:
git push origin --tags
;
4.远程仓库
4.1常用的托管服务
前面我们已经知道了Git中存在两种类型的仓库,即本地仓库和远程仓库。
那么我们如何搭建Git远程仓库呢?我们可以借助互联网上提供的一些代码托管服务来实现,其中比较常用的有GitHub、码云、GitLab等。
-
GitHub( 地址:https://github.com/ )是一个面向开源及私有软件项目的托管平台,因为只支持Git 作为唯一的版本库格式进行托管,故名GitHub(但是其服务器是在国外的,所以一般速度比较慢)
-
码云(地址: https://gitee.com/ )是国内的一个代码托管平台,由于服务器在国内,所以相比于 GitHub,码云速度会更快
-
GitLab (地址: https://about.gitlab.com/ )是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务,一般用于在企业、学校等内部网络搭建git私服。
三、Gitee
注册马云账号并登录,在码云官网上方的导航栏 ,点击"加号",选择新建仓库,然后给我们的仓库命个名,访问权限就阔以了,其他的选择默认的选项就可以。
仓库创建完之后可以看到仓库地址:如图所示:
1. 配置SSH秘钥
-
生成SSH公钥
- 输入 ssh-keygen -t rsa 然后不断回车就阔以了
- 如果公钥已经存在,则会自动覆盖
-
Gitee 设置账户的公用秘钥
-
获取秘钥:cat ~/.ssh/id_rsa.pub
-
将 bash 命令行里面出来的内容复制到 码云官网–个人头像–设置–安全设置–SSH公钥 的公钥栏里面(标题的话 ,随便输入点东西就可以),然后确定,之后会让我们再输入以下密码确认一下身份,然后就配置成功了。
-
验证是否配置成功:bash 终端输入:
ssh -T git@gitee.com # 然后在输入一个 yes 就可以了
具体的代码如下:
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master) $ ssh -T git@gitee.com #下面的这一部分内容是由于我们是第一次连接才出现的提示内容,直接选择 yes 选项输入即可 The authenticity of host 'gitee.com (212.64.62.183)' can't be established. ED25519 key fingerprint is SHA256:+ULzij2u99B9eWYFTw1Q4ErYG/aepHLbu96PAUCoV88. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added 'gitee.com' (ED25519) to the list of known hosts. Hi 池木! You've successfully authenticated, but GITEE.COM does not provide shell access. # 出现上面的 提示 ,就代表着公钥我们已经配置成功了。
-
2. 操作远程仓库
2.1添加远程仓库
此操作是先初始化本地的仓库,然后与已创建的远程仓库进行对接
-
命令: git remote add <远端名称> <仓库路径>
-
命令解释:根据仓库路径添加一个远程仓库,将该仓库命名为 我们设置的 远端名称
-
远端名称,默认是origin,取决于远端服务器设置
-
仓库路径,从远端服务器获取此URL–(我们在码云上选中SSH时候显示的地址)
-
例如: git remote add origin git@gitee.com:example/git_test.git
-
示例代码如下:
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git remote add origin git@gitee.com:example/git_test.git #添加远程仓库
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git remote #查看远程仓库(有结果,证明连接成功了)
origin
2.2查看远程仓库
- 命令 :
git remote
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git remote #查看远程仓库(有结果,证明连接成功了)
origin
2.3推送到远程仓库
- 命令:
git push [-f] [--set-upstream] [远端名称 [本地分支名][:远端分支名] ]
如果远程分支名和本地分支名称相同,则可以只写本地分支
-
git push origin master
-
-f 表示强制覆盖(一般是不使用的)
-
-u 或者 --set-upstream
推送到远端的同时并且建立起和远端分支的关联关系。 -
git push --set-upstream origin master
如果当前分支已经和远端分支关联,则可以省略分支名和远端名。
- git push 将master分支推送到已关联的远端分支。
- 补充:查看分支之间(本地分支与远程分支)的绑定关系:
git branch -vv
# git push origin master:master 可以简写为 git push origin master (咱就是说:后面的那个本地分支呵呵远端分支一样的时候,可以简写成一个)
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$ git push origin master
#下面的这一部分是我们在第一次 push 的时候才会提示的内容,后面我们进行 push 的时候就不会有这种提示信息了
Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 8 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (12/12), 900 bytes | 450.00 KiB/s, done.
Total 12 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.3]
To gitee.com:amazingABC/git_test.git
* [new branch] master -> master
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
#当我们直接使用git push 的时候,他不让 push ,需要我们进行绑定(因为我们也没有制定,他也不知道怎么 push ),这里他也提醒我们使用 --set-upstream
$ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin master
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
# 查看分支之间的绑定关系(现在没有绑定关系)
$ git branch -vv
dev 33e8925 dev-2
* master e1e8740 update what we want
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
# 分支绑定,将本地的 master 分支绑定到 外端的 master 分支(之后,我们在 master 分支下面执行 git push 命令的时候就会直接将本地的 master 分支 push 到外端的 master 分支上面)
$ git push --set-upstream origin master:master
Everything up-to-date
Branch 'master' set up to track remote branch 'master' from 'origin'.
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
# 查看分支之间的绑定关系(绑定之后,下面我们就可以看到绑定关系 本地的 master 绑定到 origin/master 即外端的 master 分支)
$ git branch -vv
dev 33e8925 dev-2
* master e1e8740 [origin/master] update what we want
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
# 本地的 master push 到 origin/master 即外端的 master 分支
$ git push
Everything up-to-date
17946@LAPTOP-6TK990GF MINGW64 /d/webpra/gittest (master)
$
2.4从远程仓库克隆
-
如果已经有一个远端仓库,我们可以直接clone到本地。
- 命令: git clone <仓库路径> [本地目录]
- 本地目录可以省略,会自动生成一个目录(远程的仓库的名字);如果不省略的话,我们所制定的本地目录就是我们将远程的仓库要克隆到的文件目录
2.5从仓库送抓取和拉取
远程分支和本地的分支一样,我们可以进行merge操作,只是需要先把远端仓库里的更新都下载到本地,再进行操作。
抓取 命令:git fetch [remote name] [branch name]
抓取指令就是将仓库里的更新都抓取到本地,不会进行合并
黑马程序员 北京昌平校区如果不指定远端名称和分支名,则抓取所有分支。
拉取 命令:git pull [remote name] [branch name]
拉取指令就是将远端仓库的修改拉到本地并自动进行合并,等同于 fetch+merge
如果不指定远端名称和分支名,则抓取所有并更新当前分支。
2.6 解决合并冲突
在一段时间,A、B用户修改了同一个文件,且修改了同一行位置的代码,此时会发生合并冲突。
A用户在本地修改代码后优先推送到远程仓库,此时B用户在本地修订代码,提交到本地仓库后,也需要推送到远程仓库,此时B用户晚于A用户,故需要先拉取远程仓库的提交,经过合并后才能推送到远端分支,如下图所示。
我们一般在本地的话,是先执行一下 pull 指令,然后再执行 push 上传到远端,(这样的话,如果有冲突,我们在本地执行 pull 的时候就会报出来这个冲突,然后我们可以进行及时的更改;但是如果直接执行 push 的话,这个冲突就不是那么好解决的了!)
2.7 Gitee 复制 Github 仓库
在Gitee 中创建仓库的时候,我们就可以直接使用 创建已有仓库,然后使用 github 的链接到 Gitee 上面,就会迁移到 我们的码云上面的
- 如果 我们 Github 上面的代码发生了更改,我们就可直接使用我们码云的仓库后面的 刷新 符号,进行刷新,然后我们就可以将内容实现和 Github 上的代码仓库中的内容的同步了
四、Github
1. 注册 Github 账号
略~
2. 多人协作开发流程
- A 在自己的计算机中创建本地仓库
- A 在 GitHub 中创建远程仓库
- A 将本地仓库推送到远程仓库
- B 克隆远程仓库到本地进行开发
- B 将本地仓库开发内容推送到远程仓库
- A 将远程仓库中的最新内容拉去本地
3. 创建远程仓库
4. 推送到远程仓库
-
git push 远程仓库地址 分支名称
-
git push 远程仓库地址别名 分支名称
-
git push -u 远程仓库地址别名 分支名称
-u
记住推送地址和分支,下次只需要输入git push
-
git remote add 远程仓库地址别名 远程仓库地址
-
删除别名:
git remote remove 远程仓库地址别名
-
第一次提交需要用户名和密码,电脑会记住密码在凭据管理器,第二次就不用了。
本地仓库上的操作
- 查看本地仓库关联的远程仓库:
git remote
;在克隆完每个远程仓库后,远程仓库默认为origin
;加上-v
的参数后,会显示远程仓库的url
地址; - 添加远程仓库,一般会取一个简短的别名:
git remote add [remote-name] [url]
,比如:git remote add example git://github.com/example/example.git
; - 从远程仓库中抓取本地仓库中没有的更新:
git fetch [remote-name]
,如git fetch origin
;使用 fetch 只是将远端数据拉到本地仓库,并不自动合并到当前工作分支,只能人工合并。如果设置了某个分支关联到远程仓库的某个分支的话,可以使用git pull
来拉去远程分支的数据,然后将远端分支自动合并到本地仓库中的当前分支; - 将本地仓库某分支推送到远程仓库上:
git push [remote-name] [branch-name]
,如git push origin master
;如果想将本地分支推送到远程仓库的不同名分支:git push :
,如git push origin serverfix:awesomebranch
;如果想删除远程分支:git push [romote-name] :
,如git push origin :serverfix
。这里省略了本地分支,也就相当于将空白内容推送给远程分支,就等于删掉了远程分支。 - 查看远程仓库的详细信息:
git remote show origin
; - 修改某个远程仓库在本地的简称:
git remote rename [old-name] [new-name]
,如git remote rename origin org
; - 移除远程仓库:
git remote rm [remote-name]
;
- 查看本地仓库关联的远程仓库:
5. 拉取仓库
5.1 克隆仓库
- 克隆远程仓库到本地:
git clone 仓库地址
5.2 拉取远程仓库中最新版本
- 拉取远程仓库最新版本到本地:
git pull 远程仓库地址 分支名称
6解决冲突
多人开发同一个项目时,如果两个人修改了同一个文件同一个地方
git pull
- 手动解决冲突
git push
7. 跨团队协作
fork
到自己的远程仓库clone
到本地进行修改push
到远程仓库pull request
发送给原作者- 原作者查看
commit
审核 - 原作者
merge pull request
8. SSH 免密登录
-
生成密钥:
ssh-keygen
密匙储存目录:
C:\User\用户\.ssh
公钥名称:
id_rsa.pub
私钥名称:
id_rsa
-
Github 添加公钥
-
复制 SSH 地址:
-
设置 ssh 别名:
$ git remote add origin_ssh SSH地址
-
远程推送:
$ git push origin_ssh master
9. Git 忽略清单
将不需要的文件名字添加到此文件中,执行 git 命令时就会忽略这些文件。
-
git 忽略清单文件名称:
.gitignore
-
将工作目录所有文件添加到缓存区:
git add .
-
例子:
# 此为注释 – 将被 Git 忽略 # 忽略所有 .a 结尾的文件 *.a # 但 lib.a 除外 !lib.a # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO /TODO # 忽略 build/ 目录下的所有文件 build/ # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt doc/*.txt # 忽略 doc/ 目录下所有扩展名为 txt 的文件 doc/**/*.txt
10. 为仓库添加说明
在仓库根目录添加readme.md
文件即可
五、在Idea 中使用Git
1. 插件推荐:Gitee 码云
我们可以在 idea 中安装一个插件 Gitee 码云,然后在里面进行账号的登录,这样我们就可以省略代码和账户的认证操作了。
settings ===> version control ===> gitee ===>填写登录信息
2. 配置Git
安装好IntelliJ IDEA后,如果Git安装在默认路径下,那么idea会自动找到git的位置,如果更改了Git的安装位置则需要手动配置下Git的路径。选择File→Settings打开设置窗口,找到 Version Control 下的 git 选项:
点击右侧的 Test 按钮,下面出现 Git 的版本号的话,就说明配置成功了
3. 在Idea 中操作 Git
场景:本地已经有一个项目,但是并不是git项目,我们需要将这个放到码云的仓库里,和其他开发人员继续一起协作开发
3.1 创建项目的远程仓库
具体步骤见上面我们创建仓库的目录
注意:由于我们是要将本地仓库给推动到远程仓库,所以创建仓库的时候下面的选项:比如说:初始化仓库,设置模板,选择分支类型等,这些我们都不要进行选择。
3.2 初始化本地仓库
首先,我们打开一个我们本地的项目,由于 Idea 项目会自动生成一个 .idea 文件目录,这个目录的话,我们就不需要仓库对其进行管理了,所以这一我们一般的话导入 .gitignore 文件,来忽略对这里的文件的管理。
在 Idea 中我们选择 Git 中的 VCS operations
然后选择 Create Git Repository ,选择我们要进行使用的本地的项目的目录就阔以了
初始化为仓库之后,上面就会有一些符号,比如说对号和箭头之类的,具体的作用如下
我们是先提交到本地仓库,然后再将本地仓库给 push 到远程仓库
我们点击 对号 进行提交的时候,idea 会相对弱化我们的缓存区,我们直接全选,然后下面输入对应的 commit message (bash 命令行窗口里面执行提交的时候我们使用 双引号所引着的提示信息-版本日志信息,这个信息我们在 idea 下面的Version Control (或者 git )—> log 栏目里面就可以看到,点击对应的提示信息,右侧还会显示,我们在这次提交的时候都是提交了什么内容。)
- 将本地的仓库 push 到远程仓库
导航栏 Git --> Manage Rometes —> 弹出窗口左下角的加号 —> 输入名称和我们远程仓库所对应的 SSH 链接就可以了。
- 远程仓库的克隆
导航栏 Git —> clone —> 输入我们仓库的 ssh 链接就可以了(后面的目录我们也可以更改)
- 解决冲突
和我们之前解决冲突的方式一样:在本地的话,一般都是先执行 pull ,然后在进行 push , 在执行 pull 的时候在本地就把冲突给解决掉,然后在进行提交,对于那种,我们提交的功能都是所需要的是时候,我们可以直接把文件中提示冲突的内容直接给删除掉,直接改成我们想要的代码,然后进行 pull 加上 push 就可以了。(对于我们修改的文件,我们可能需要先对其进行一下 add 操作!!!)
3.3 分支创建
idea 的分支创建有好多种方式,比如说
- 右下角的 master 处,点击之后我们可以看到我们本地和远程的分支,在相应的内容部分右键可以进行很多种操作:新建分支,checkout , merge等等操作(可以自行查看一下一下)
- 但是我们一般才有,在 log 界面里面的指定节点处进行右键新建分支(优点:可以指定我们新建分支的节点;可以清楚地看到分支的结构)
3.4 几条铁令
-
切换分支前先提交本地的修改,如果未提交就直接切换分支的话,我们所做的代码修改将不会进行保存
-
代码及时提交,提交过了就不会丢
-
遇到任何问题都不要删除文件目录,第1时间找老师
4. 代码的团队内合作
- 进入网站的库的首页
- 点击设置 settings
- 左栏 Manage access
- Invite a collaborator -------> 邀请一个合作伙伴
- 输入对方的 账号,然后在主页会显示一个邀请函()后面也会有一个地址
- 对方访问对应的邀请函的地址的时候,就会看到邀请界面,接受邀请之后,在对方的账号上面也就可以看到主人的仓库的代码了
- 对方就可以直接进行代码的更改和 push 了
5. 代码实现跨团队合作
- 被人搜索到你的代码,然后点击 fork 插入到我们自己的代码仓库里面
- 对其进行修改(修改之后 commit ,只是我们这边显示更改了,但是代码的主人那并没有发生更改,我们可以发送 pull request ,填写部分信息发送请求)
- 在代码主人的主页部分的 pull request部分就会接收到请求,然后可以查看修改的代码信息,包括后面的发送和回复信息(直接聊天–聊天内容,上面会自动更新)
- 如果主人感觉代码还是可以的,代码原主人那里就可以就是接收更改了,点击 merge pull request ,之后两端的代码就都被更新了
六、Gitlab
1. GitLab_简介和安装环境准备
-
GitLab简介
GitLab 是由 GitLab Inc.开发,使用 MIT 许可证的基于网络的 Git 仓库管理工具,且具有wiki 和 issue 跟踪功能。使用 Git 作为代码管理工具,并在此基础上搭建起来的 web 服务。(可搭建局域网Git仓库)。 -
GitLab 由乌克兰程序员 DmitriyZaporozhets 和 ValerySizov 开发,它使用 Ruby 语言写成。后来,一些部分用 Go 语言重写。截止 2018 年 5 月,该公司约有 290 名团队成员,以及 2000 多名开源贡献者。 GitLab 被 IBM, Sony, JülichResearchCenter, NASA, Alibaba,Invincea, O’ReillyMedia, Leibniz-Rechenzentrum(LRZ), CERN, SpaceX 等组织使用。
2. GitLab官网地址
安装说明
3. GitLab安装
3.1服务器准备
准备一个系统为 CentOS7 以上版本的服务器, 要求内存 4G,磁盘 50G。
关闭防火墙, 并且配置好主机名和 IP,保证服务器可以上网。
此教程使用虚拟机:主机名: gitlab-server IP 地址: 192.168.6.200
3.2安装包准备
Yum 在线安装 gitlab- ce 时,需要下载几百 M 的安装文件,非常耗时,所以最好提前把所需 RPM 包下载到本地,然后使用离线 rpm 的方式安装。
注:资料里提供了此 rpm 包,直接将此包上传到服务器/opt/module 目录下即可。
3.3 编写安装脚本
安装 gitlab 步骤比较繁琐,因此我们可以参考官网编写 gitlab 的安装脚本。
[root@gitlab-server module]
#使用 vim 编辑器打开 gitlab-install.sh
sudo rpm -ivh /opt/module/gitlab-ce-13.10.2-ce.0.el7.x86_64.rpm
sudo yum install -y curl policycoreutils-python openssh-server cronie
sudo lokkit -s http -s ssh
sudo yum install -y postfix
sudo service postfix start
sudo chkconfig postfix on
curl https://packages.gitlab.com/install/repositories/gitlab/gitlabce/script.rpm.sh | sudo bash
sudo EXTERNAL_URL="http://gitlab.example.com" yum -y install gitlabce
注意:执行上面的操作的时候,会打印出来很多的日志信息,不用理他就行了
给脚本执行权限
[root@gitlab-server module]# chmod +x gitlab-install.sh
[root@gitlab-server module]# ll
总用量 403104
-rw-r--r--. 1 root root 412774002 4 月 7 15:47 gitlab-ce-13.10.2-ce.0.el7.x86_64.rpm
-rwxr-xr-x. 1 root root 416 4 月 7 15:49 gitlab-install.sh
然后执行该脚本,开始安装 gitlab-ce。注意一定要保证服务器可以上网。
[root@gitlab-server module]# ./gitlab-install.sh
警告: /opt/module/gitlab-ce-13.10.2-ce.0.el7.x86_64.rpm: 头 V4
RSA/SHA1 Signature, 密钥 ID f27eab47: NOKEY
准备中... #################################
[100%]
正在升级/安装...
1:gitlab-ce-13.10.2-ce.0.el7
################################# [100%]
4初始化GitLab服务
执行以下命令初始化 GitLab 服务,过程大概需要几分钟,耐心等待…
[root@gitlab-server module]# gitlab-ctl reconfigure
。 。 。 。 。 。
Running handlers:
Running handlers complete
Chef Client finished, 425/608 resources updated in 03 minutes 08 seconds
gitlab Reconfigured!
5启动GitLab服务
执行以下命令启动 GitLab 服务,如需停止,执行 gitlab-ctl stop
(服务启之后,我们才能够正常的访问)
[root@gitlab-server module]# gitlab-ctl start
ok: run: alertmanager: (pid 6812) 134s
ok: run: gitaly: (pid 6740) 135s
ok: run: gitlab-monitor: (pid 6765) 135s
ok: run: gitlab-workhorse: (pid 6722) 136s
ok: run: logrotate: (pid 5994) 197s
ok: run: nginx: (pid 5930) 203s
ok: run: node-exporter: (pid 6234) 185s
ok: run: postgres-exporter: (pid 6834) 133s
ok: run: postgresql: (pid 5456) 257s
ok: run: prometheus: (pid 6777) 134s
ok: run: redis: (pid 5327) 263s
ok: run: redis-exporter: (pid 6391) 173s
ok: run: sidekiq: (pid 5797) 215s
ok: run: unicorn: (pid 5728) 221s
6. GitLab_登录GitLab并创建远程库
6.1 登录GitLab
使用主机名或者 IP 地址即可访问 GitLab 服务。可配一下 windows 的 hosts 文件(C:\Windows\System32\drivers\etc)===> 配置之后,我们就可以在浏览器中通过访问 主机名 gitlab-server 的方式,访问到我们的服务器了。
当然,我们也可以不进行配置,但是此时我们需要通过服务器的 IP 地址进行访问。
首次登陆之前,需要修改下 GitLab 提供的 root 账户的密码,要求 8 位以上,包含大小写子母和特殊符号。比如说:Abcd.1234
然后使用修改后的密码登录 GitLab。
登陆成功之后,我们就可以看到我们的远程仓库的界面了。
6.2 创建远程库
在我们的 Gitlab 首页,进行以下操作:New project ==> Create a project ==> 配置我们的仓库的名称 ===>创建完成
6.3 通过 idea 链接远程库
- 首先在 idea 中安装一个插件
gitlab projects 2020
安装完成之后,我们在 Settings --> Version Control —> Gitlab —> Add new Gitlab Server —> 输入我们的服务器的链接,然后选择相应的协议就可以连接成功了
然后我们在我们的服务器网页上面,点开我们的仓库,找到 clon => http 链接,在我们的 idea 里面 创建新的远程库的链接,然后就可以进行正常的 push 等等的 git 操作了。
注意:我们在网页上复制的 远程库的不是完全可以在我们的 idea 中绑定的时候使用的。我们需要对其进行以下稍微的修改才能够正常的使用。比如:
# 我们复制得到的链接(默认给的是一个例子的链接)
http://gitlab.example.com/root/git-test.git
# 我们需要将里面的例子给改成我们的主机名(如果上面没有配置 host 文件的话,也可以写 ip 地址)
http://gitlab-server/root/git-test.git
http://192.168.6.200/root/git-test.git