GIT教程
GIT教程
原创者:文思
一、Git基础
1、认识GIT
有了SVN为何还用GIT?
SVN增量式管理,GIT采取了文件系统快照的方式
SVN集中式管理,GIT分布式管理

其他优势:
大部分操作在本地不需要联网,只有pull和push时需要
尽可能添加数据还不是修改或删除数据
分支操作快捷(指针)
与Linux命令全面兼容
2、安装GIT
非windows环境安装:
https://git-scm.com/download/win
依次输入:./config,make,sudo make install
windows环境安装: Windows下要使用很多Linux/Unix的工具时,需要Cygwin这样的模拟环境,Git也一样。Cygwin的安装和配置都比较复杂。
msysgit,模拟环境和Git都打包好了,只需要下载一个单独的exe安装程序。msysgit是Windows版的Git。
https://git-for-windows.github.io原始下载,因中国国情:
http://www.oschina.net/p/git/或http://www.oschina.net/p/msysgit下载。
安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功! 安装完成后,还需要最后一步设置,在命令行输入:
$ git config--global user.name "Your Name" $ git config --global user.email"email@example.com"
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。
注意:git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址
3、GIT结构
工作区(写代码的地方)—git addà暂存区(临时存储)—git commità本地库(历史版本)
实际使用中很多人喜欢直接commit到本地库,这或许是从svn沿袭来的习惯。
工作区:版本库(.git) = .svn
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。SVN是没有暂存区的。
文件往Git版本库里添加的时候,是分两步执行的:
第一步用git add把文件添加进去,实际上就是把文件修改添加到暂存区。

第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

创建Git版本库时,Git自动为我们创建了唯一一个master分支,git commit就是往master分支上提交更改。add需要提交的文件修改通通放到暂存区,然后commit可一次性提交暂存区的所有修改

4、Git和代码托管中心:
局域网-GitLab服务器
外网-GitHub、码云
本地库与远程库协作方式:团队内部协作、跨团队协作


5、Git命令行操作
1)本地库初始化
git add

2)设置签名
用户名,email地址
作用:区分开发人员身份
这里设置的签名和登录远程库的账号、密码没有关系
命令:
项目级别/仓库级别:仅在当前本地库范围内有效
git config user.name tom_pro
git config user.email good_pro@126.com
信息保存位置:

系统用户界别:登录当前操作系统的用户范围
git config –globaluser.name tom_glb
git config –globalgood_pro@126.com
项目级别优先于用户级别

3)常用git命令
git stauts,显示工作目录和暂存区的状态:

上面绿色的文件代表在暂存区,未提交到本地库。
新建文件后git status查看:

上面红色文件代表在工作区未提交到暂存区。
git add 文件名,提交文件到暂存区:

以上文件已到暂存区,git rm - -cache 文件名, 代表从暂存区撤销文件Changes to be committed:(use “git reset
HEAD<file>…” to unstage):

git add再次提交testGit.txt到暂存区,后进行git commit提交:
git commit 文件名,提交文件到暂存区:
git commit testGit.txt

输入提交的日志信息后:


至此文件已到本地库。修改文件再次提交看看信息是什么


git status看一下:

git add然后git commit即可。大家想下两步操作麻烦吗,回想一下maven命令的声明周期原理,如果我们直接commit呢?看看

直接提交完成,commit包含了add操作。即commit命令对应着eclipse中的commit选项。
查看历史记录操作:git log

想让日志优美一点:git log –pretty=oneline或git log –oneline

reflog 可看到移动到当前版本需要的步数

Head代表指针,指向的是每一个历史记录。
git reset --hard版本切换3种方式:
使用索引值草最(推荐)、使用^符号(只能往后退)、使用~符号(后退)
使用索引值草最(推荐):


可以看到3bc406c已经回退到当前最近版本。再恢复:

可以看到又恢复了。
使用^符号:

使用~符号:

reset命令的三个参数对比:soft、hard、mixed
soft仅仅在本地库移动指针
mixed本地库移动指针并重置暂存区
hard在本地库移动指针,重置暂存区并重置工作区
git中对文件的删除操作也相当于修改,示例:文件删除并找回,创建文件并提交到本地库:

删除后并且再进行提交:


git reflog可以看到:

本地库里都有记录,包括删除的记录都存在,即可找回已删除文件。找回:

git diff,比较文件差异:
Git diff [文件名]将工作区中的文件和暂存区进行比较
Git diff [本地库历史版本] [文件名]将工作区中的文件和本地库历史记录比较。
例如:Git diff [文件名]将工作区中的文件和暂存区进行比较


提交后暂存区没有了,则无法比较了。
Git diff [本地库历史版本] [文件名]将工作区中的文件和本地库历史记录比较,使用本地库历史版本号比较:

分支
Branch命令,查看、创建分支
git branch –v查看分支
git branch [分支名]创建分支

git checkout[分支名]切换分支:

合并分支示例:先修改dev分支文件:

将修改后的dev分支的文件合并到master:
1、当前分支必须是master(站在接受修改的分支上,即切换为master分支)
2、执行merge命令

可以看到已经进行完成分支合并:

冲突解决:多个分支对同一个文件的同一个位置且内容不一致就会产生冲突。比如在master分支中修改testGit文件的最后一行,改为this is modify from;修改dev分支此文件最后一行为this is modify from dev!!!!!!


git chekout master 后 git merge master

看到合并成功且有冲突:

怎么解决就不用再说了。修改后冲突后看看暂存区是什么状态:

git add后再提交:

提交失败,回想一下eclipse中的操作,是不是先标记为“已解决”,这里应该有对应命令还是怎样?直接commit不写文件名:

貌似成功了,所以这时候commit提交一定不能带文件名。
6、Git的基本原理:
哈希,哈希是一个一系列的加密算法。不同的哈希算法有以下共同点:
1)不管输入的数据量有多大,输入同一个哈希算法,得到的加密结果长度固定。
2)哈希算法确定,输入数据确定,输出数据能够保证不变。
3)哈希算法不可逆
所以哈希算法可以用来验证文件。

Git底层采用的是SHA-1算法。
保存版本的机制
传统集中式版本控制工具的文件管理机制
以文件变更列表的方式存储信息。这类系统将它们保存的信息看作是一组基本,文件和每个文件随时间逐步累积的差:

Git 把数据看作是小型文件系统的一组快照。每次提交更新时Git 都会对当前的全部文件制作一个快照并保存这个快照的索引。为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。所以Git 的工作方式可以称之为快照流:

提交对象及其父对象形成的链条:

分支创建指针原理:

分支切换原理:


看出指针(HEAD)在git中的应用。
7、仓库
创建远程库,以使用github为例
推送本地库到远程库:git push 地址(别名) 分支

远程库clone到本地:git clone 地址

拉取:git pull 地址(别名) 分支,或者git
fetch 地址(别名) 分支
Pull = fetch +merge
8、SSH免密登陆
每个仓库有两种地址,一种https一种是SSH。
1)进入当前用户的根目录,删除以前创建的.ssh目录并生成一个新目录

2)运行命令生成.ssh 密钥目录
$ ssh-keygen -t rsa -C good_pro@126.com
[注意:这里-C 这个参数是大写的C]
进入.ssh 目录查看文件列表($ cd .ssh,$ ls –lF)
查看id_rsa.pub 文件内容($ cat id_rsa.pub)
3)复制id_rsa.pub 文件内容,登录GitHub,点击用户头像→Settings→SSH andGPG keys
4)New SSH Key
5)输入复制的密钥信息
6)回到Git bash 创建远程地址别名
(git remote add origin_ssh git@github.com:testGit2018y/test.git)
9、Eclipse操作,略,使用eclipse插件时多想想选项操作对应的命令及原理。
10、eclipse中的文件忽略(比较实用)
概念:Eclipse 特定文件。这些都是Eclipse 为了管理我们创建的工程而维护的文件,和开发的代码没有直接关系。最好不要在Git 中进行追踪,也就是把它们忽略。
.classpath 文件 .project 文件 .settings 目录下所有文件
什么要忽略Eclipse 特定文件呢?
同一个团队中很难保证大家使用相同的IDE 工具,而IDE 工具不同时,相关工程特定文件就有可能不同。如果这些文件加入版本控制,那么开发时很可能需要为了这些文件解决冲突。
GitHub 官网样例文件
https://github.com/github/gitignore
https://github.com/github/gitignore/blob/master/Java.gitignore
编辑本地忽略配置文件,文件名任意:
Java.gitignore
# 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, seehttp://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
.classpath
.project
.settings
Target
在~/.gitconfig文件中引入上述文件
[core]
excludesfile =C:/Users/Lenovo/Java.gitignore
[注意:这里路径中一定要使用“/”,不能使用“\”]
11、git工作流
Gitflow工作流
通过为功能开发、发布准备和维护设立了独立的分支,让发布迭代过程更流畅。严格的分支模型也为大型项目提供了一些非常必要的结构。
常见结构:
1)主干分支master
主要负责管理正在运行的生产环境代码。永远保持与正在运行的生产环境完全一致。
2)开发分支develop
主要负责管理正在开发过程中的代码。一般情况下应该是最新的代码。
3)bug 修理分支hotfix。修复完随时删除
主要负责管理生产环境下出现的紧急修复的代码。从主干分支分出,修理完毕并测试上线后,并回主干分支。并回后,视情况可以删除该分支。
4)准生产分支(预发布分支)release
较大的版本上线前,会从开发分支中分出准生产分支,进行最后阶段的集成测试。该版本上线后,会合并到主干分支。生产环境运行一段阶段较稳定后可以视情况删除。
5)功能分支feature。开发完后随时删除
为了不影响较短周期的开发工作,一般把中长期开发模块,会从开发分支中独立出来。开发完成后会合并到开发分支。

Forking 工作流
Forking 工作流是在GitFlow 基础上,充分利用了Git 的Fork 和pull request 的功能以达到代码审核的目的。更适合安全可靠地管理大团队的开发者,而且能接受不信任贡献者的提交。

二、git服务器搭建
官网地址
首页:https://about.gitlab.com/
安装说明:https://about.gitlab.com/installation/
安装命令摘录
sudo yum install -y curlpolicycoreutils-python openssh-server cronie
sudo lokkit -s http -s ssh
sudo yum install postfix
sudo service postfix start
sudo chkconfig postfix on
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh| sudo bash
sudo EXTERNAL_URL="http://gitlab.example.com" yum -y install gitlab-ee
实际问题:yum 安装gitlab-ee(或ce)时,需要联网下载几百M 的安装文件,非常耗时,所以应提前把所需RPM 包下载并安装好。
下载地址为:
https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-10.8.2-ce.0.el7.x86_64.rpm
调整后的安装过程
sudo rpm -ivh /opt/gitlab-ce-10.8.2-ce.0.el7.x86_64.rpm
sudo yum install -y curlpolicycoreutils-python openssh-server cronie
sudo lokkit -s http -s ssh
sudo yum install postfix
sudo service postfix start
sudo chkconfig postfix on
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
sudo EXTERNAL_URL="http://gitlab.example.com" yum -y install gitlab-ce
当前步骤完成后重启。
gitlab服务操作:
初始化配置gitlab:gitlab-ctl reconfigure
启动gitlab 服务:gitlab-ctl start
停止gitlab 服务:gitlab-ctl stop
访问Linux 服务器IP 地址即可,如果想访问EXTERNAL_URL 指定的域名还需要配置域名服务器或本地hosts文件。初次登录时需要为gitlab 的root 用户设置密码。应该会需要停止防火墙服务:service firewalld stop