1.Git概述

官方网站:https://git-scm.com

什么是版本控制

版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。

有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。 使用版本控制系统通常还意味着,就算你乱来一气把整个项目中的文件改的改删的删,你也照样可以轻松恢复到原先的样子。 但额外增加的工作量却微乎其微。

集中化版本控制

分布式版本控制

Git系统是一个分布式的系统,是用来保存工程源代码历史状态的命令行工具

Git、GitHub与GitLab

  • Git是一个版本管理软件
  • GitHub与GitLab都是用于管理版本的服务端软件
  • GitHub提供免费服务(代码需公开)
  • GitLab用于在企业内部管理Git版本库,功能上类似于GitHub

Git设计目标

  • 快速
  • 简单
  • 完全分布
  • 高效存储
  • 满足大规模项目需要

为什么要是用Git

  • 本地建立版本库
  • 本地版本控制
  • 多机异地协同工作
  • 更好用的提交列表
  • 更好的差异比较
  • 更完善的分支系统
  • 速度极快

Git工作模式

Git文件存储

集中式

分布式

Git与其他版本控制工具不同的地方

  • 直接记录快照,而非差异比较
  • 近乎所有操作都在本地执行
  • 时刻保持数据完整性
  • 多数操作仅添加数据

2.Git基础

2.1 初次运行Git前的配置

Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。 这些变量存储在三个不同的位置:

  1. /etc/gitconfig 文件: 包含系统上每一个用户及他们仓库的通用配置。 如果使用带有 --system选项的 git config 时,它会从此文件读写配置变量
  2. ~/.gitconfig~/.config/git/config 文件:只针对当前用户。 可以传递 --global 选项让 Git 读写此文件
  3. 当前使用仓库的 Git 目录中的 config 文件(就是 .git/config): 针对该仓库

配置用户名称和邮件地址

1
2
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

检查配置信息

1
git config --list

2.2 文件状态

文件的三种状态

  • 已修改(modified)
  • 已暂存(staged)
  • 已提交(committed)

Git文件

  • 已被版本库管理的文件

已修改

  • 在工作目录修改的Git文件

已暂存

  • 对已修改的文件执行Git暂存操作,将文件存入暂存区

已提交

  • 将已暂存的文件执行Git提交操作,将文件存入版本库

2.3 本地版本库与服务器版本库

2.4 Git安装

1
yum install -y git

2.5 Git常用指令

创建本地仓库

1
2
3
mkdir mygit
cd mygit
git init

输出

1
Initialized empty Git repository in /xxx/xxx/xxxx/mygit/.git/

查看隐藏目录

1
ls -al .git

在当前工作目录创建文件

1
touch test.txt

查看当前工作目录状态

1
git status

输出

1
2
3
4
5
6
7
8
9
10
On branch master

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)

test.txt

nothing added to commit but untracked files present (use "git add" to track)

将已修改的文件纳入到暂存区当中

1
git add test.txt

查看当前工作目录状态

1
git status

输出

1
2
3
4
5
6
7
8
On branch master

No commits yet

Changes to be committed:
(use "git rm --cached <file>..." to unstage)

new file: test.txt

从暂存区回退到已修改状态

1
git rm --cached test.txt

将暂存文件提交到本地版本库

1
2
#git commit -m 'comment info'
git commit

查看提交历史

1
git log

修改文件内容

1
vim test.txt

查看当前工作目录状态

1
git status

输出

1
2
3
4
5
6
7
8
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: test.txt

no changes added to commit (use "git add" and/or "git commit -a")

丢弃工作目录文件的修改

1
git checkout -- test.txt

删除误提交文件

1
git rm test.txt

查看当前工作目录状态

1
git status

输出

1
2
3
4
5
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

deleted: test.txt

将删除文件移动到暂存区

1
git reset HEAD test.txt

输出

1
2
Unstaged changes after reset:
D test.txt

查看当前工作目录状态

1
2
3
4
5
6
7
8
9
10
git status

On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

deleted: test.txt

no changes added to commit (use "git add" and/or "git commit -a")

恢复误删除文件

1
git checkout -- test.txt

文件重命名

1
git mv test.txt test2.txt

重写上一次commit log

1
git commit --amend -m 'test2 file'

2.6 查看提交历史

  • 查看提交历史

    1
    git log
  • 显示每次提交的内容差异

    1
    git log -p
  • 仅显示最近的n条log

    1
    git log -n
  • 显示简要的增删改行数统计

    1
    git log --stat
  • 简要单行显示

    1
    git log --pretty=oneline
  • 自定义显示格式

    1
    git log --pretty=format:'#h -%an, %ar : %s'

3.Git文件忽略

有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们

在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,

Git就会自动忽略这些文件

创建并编辑.gitignore,加入要忽略的文件名

1
2
3
4
5
6
7
vi .gitignore

test.txt
*.b #忽略.b结尾的文件
!a.b #除了a.b文件
build/ #忽略build/下所有文件

提交.gitignore

1
2
git add .gitignore
git commit .gitignore -m 'add .gitignore'

4.Git分支

2.1 分支的简单操作

几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。

在使用git init创建本地仓库时,git就为我们创建了一个默认的分支master,这个master分支是git的主分支,也是通常用于发布项目的分支

查看当前版本分支

1
git branch

创建新的分支

1
git branch new_branch

切换分支

1
git checkout new_branch

在当前分支创建文件并提交

1
2
3
touch test4.txt
git add .
git commit -m 'commit test4.txt to new_branch'

切换分支到master

1
git branch master

删除分支

1
git branch -d new_branch

创建并切换到新分支

1
git checkout -b new_branch

分支合并

1
git merge new_branch

遇到冲突时的分支合并

1
2
3
4
5
6
7
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> new_branch:index.html

上述冲突的解决方案是仅保留了其中一个分支的修改,并且 <<<<<<< , ======= , 和 >>>>>>> 这些行被完全删除了在你解决了所有文件里的冲突之后,对每个文件使用 git add 命令来将其标记为冲突已解决。 一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决

2.2 分支的本质

当使用 git commit 进行提交操作时,Git 会先计算每一个子目录(本例中只有项目根目录)的校验和,然后在 Git 仓库中这些校验和保存为树对象。 随后,Git 便会创建一个提交对象,它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针。如此一来,Git 就可以在需要的时候重现此次保存的快照。

做些修改后再次提交,那么这次产生的提交对象会包含一个指向上次提交对象(父对象)的指针

Git 的分支,其实本质上仅仅是指向提交对象的可变指针。 Git 的默认分支名字是 master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。 它会在每次的提交操作中自动向前移动

Git 的 “master” 分支并不是一个特殊分支。 它就跟其它分支完全没有区别。 之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,并且大多数人都懒得去改动它

那么,Git又是怎么知道当前在哪一个分支上呢?也很简单,它有一个名为 HEAD 的特殊指针,用于指向当前

所在的本地分支

2.3 版本回退

  • 回到上一版本

    1
    2
    3
    git reset --hard HEAD^
    git reset --hard HEAD~1
    git reset --hard commit_id
  • 返回到某一版本

  • ```
    git reflog

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # 5.Git打标签

    像其他版本控制系统(VCS)一样,Git可以给历史中的某一个提交打上标签,以示重要

    比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 等等)

    - 列出标签

    - ```
    git tag
  • 创建标签

    Git使用两种主要类型的标签:轻量标签(lightweight)与附注标签(annotated)

    创建轻量标签

    1
    git tag v1.0

    创建附注标签

    1
    git tag -a v1.4 -m 'my version 1.4'
  • 删除标签

  • ```
    git tag -d v1.0

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    <font color=red>注:tag与分支无关,tag在所有分支都会显示</font>

    # 6.GitLab

    ## 6.1 GitLab安装

    官方网站:http://about.gitlab.com/downloads

    新建 `/etc/yum.repos.d/gitlab-ce.repo`,内容为

    ```shell
    [gitlab-ce]
    name=Gitlab CE Repository
    baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/
    gpgcheck=0
    enabled=1

再执行

1
2
sudo yum makecache
sudo yum install -y gitlab-ce

启动

1
gitlab-ctl start

停止

1
gitlab-ctl stop

重启

1
gitlab-ctl restart

编辑/etc/gitlab/gitlab.rb

1
vi /etc/gitlab/gitlab.rb

重新配置

1
gitlab-ctl reconfigure

6.2 开启邮件服务

vi /etc/gitlab/gitlab.rb

1
2
3
4
5
6
7
8
9
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.qq.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "281894787@qq.com"
gitlab_rails['smtp_password'] = "gabclqguaunhbifg"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = '281894787@qq.com'

重新配置

1
gitlab-ctl reconfigure

测试

1
gitlab-rails console
1
Notify.test_email('xxxx@qq.com', 'gitlab', 'gitlab').deliver_now

关闭用户注册功能

Admin Area/Settings/General/Sign-up restrictions 取消勾选Sign-up enabled

点击save change

6.3 创建用户对应SSH Key

打开Git Bash,输入如下内容

1
ssh-keygen -t rsa -C "xxxx@xxxx.com"

连续三次回车

进行.ssh目录,并复制xxx.pub中的内容

登录Git Lab,选择settings/SSH Keys,将xxx.pub中内容粘贴到Key中,并保存