git概述

P1 版本控制概述

关于版本控制

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

- 有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都退回到过去某个时间点的状态

- 可以比较文件的变化细节,查出是谁最后修改了什么地方,从而造成某些怪异问题,又是谁在何时报告了某个功能缺陷

本地版本控制系统

- 人们很久以前就开发了许多种本地版本控制系统

- 大多都是某种简单的数据库来记录文件的历次更新差异

- 其中最流行的一种叫做 rcs

- 它的工作原理基本上就是保存并管理文件补丁(patch)

#所有的项目版本都在本地服务器上,只能在本地从版本库中获取代码,无法协同工作。

集中化的版本控制系统

- 集中化的版本控制系统允许不同的开发者可以协同工作

- 此类系统有 CVS,Subversion 以及Perforce 等

- 它们都单一拥有集中管理的服务器,保存所有文件的修订版本

- 协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新

#1》所有的项目版本数据都存储在统一的服务器上;

#2》协同工作的人,都需要通过客户端远程连接到这台服务器上,取出文件或提交更新;

#3》服务器故障或断网情况下,无法使用;

分布式版本控制系统

- 客户端并不只提取最新版本的文件快照

- 而是把原始的代码仓库完整的镜像下来

- 任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复

- 每一次的提取操作,实际上都是一次对代码仓库的完整备份

Git 的历史

- Linux 内核开源项目有着为数众多的参与者

- 1991-2002年间,绝大多数 Linux 内核维护工作都花在提交补丁和保存归档的繁琐事务上

- 2002年,整个项目组开始启动分布式版本控制系统 BitKeeper 来管理和维护代码

- 到 2005 年的时候,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回来免费试用 BitKeeper 的权力

Git的特点

- 直接快照,而非比较差异

- 近乎所有操作都可本地执行

- 时刻保持数据完整性。在保存到 Git 之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引

Git 状态

- 任何一个文件,在 Git 内都只有三种状态**

  - [x] 已提交(committed):  表示该文件已经被安全的保存在本地数据库中了

  - [x] 已修改(modified):  表示修改了某个文件,但还没有提交保存

  - [x] 已暂存(staged):  表示把已修改的文件放在下次提交时要保存的清单

工作区:   #编写代码,工作的目录;

暂存区:   #临时存储的区域,可以返回,重复修改;

版本库:   #将暂存区中的文件,提交到版本库中,进行永久性存储;

安装及配置:Git 安装后需配置用户相关信息

pycharm主机,安装git,实现git命令的自动补全功能

[root@kube-node1 ~]# yum -y install git

[root@kube-node1 ~]# rpm -q bash-completion #git的命令补全通过 bash-completion实现,没有则需要安装

[root@kube-node1 ~]# source /etc/bash_completion.d/git #使用source 在当前解释器下加载git,让立刻生效,否则需要重启虚拟机

[root@kube-node1 ~]# git #git<空格>可以列出git的可以使用的命令

[root@kube-node1 ~]# git config --global user.name 'MrZhangzhg' #指定提交代码或程序的作者

[root@kube-node1 ~]# git config --global user.email '[email protected]' #指定提交代码或程序的作者邮箱

[root@kube-node1 ~]# git config --global core.editor vim #指定使用git时的默认编译器为vim【例如编写提交日志信息时,自动使用vim】

[root@kube-node1 ~]# git config --list #查看git的全局配置信息

[root@kube-node1 ~]# cat ~/.gitconfig #git的全局配置信息存放在 ~/.gitconfig中

git基础应用

P1 管理仓库

创建仓库:尚不存在项目时,可以直接创建,在pycharm主机上操作

[root@kube-node1 ~]# mkdir git_lesson #创建目录,用于进行git的演示操作

[root@kube-node1 ~]# cd git_lesson/ #进入到目录下

[root@kube-node1 git_lesson]# git init devops #初始化一个空的git仓库 devops

在已有项目的目录中创建仓库

[root@kube-node1 git_lesson]# mkdir  myweb #先创建一个目录

[root@kube-node1 git_lesson]# cd myweb/

[root@kube-node1 myweb]# echo '

My Test Web Site

' > index.html #创建一个文件,作为项目文件

#在当前目录下进行,进行仓库的初始化,会将目录下的文件,加入到版本仓库中

[root@kube-node1 myweb]# git init

仓库说明

- 初始化后,在当前目录下会出现一个名为 .git 的目录

- 所有 Git 需要的数据和资源都存放在这个目录中

- 目前仅仅是按照既有的结构框架,初始化好了仓库中所有的文件和目录

- 还没有开始跟踪管理项目中的任何一个文件

还可以通过克隆现有仓库的方式获取版本库:直接克隆

[root@kube-node1 myweb]# cd ..

[root@kube-node1 git_lesson]# git clone https://github.com/schacon/grit

克隆时,指定本地目录

[root@kube-node1 git_lesson]# git clone https://github.com/schacon/grit  mygrit

记录更新到仓库

文件状态

- 工作目录下的所有文件都不外乎这两种状态:已跟踪或未跟踪

- 已跟踪的文件是指被纳入版本控制管理的文件,在上次快照中有他们的记录,工作一段时间后,它们的状态可能是未更新,已修改或者已放入暂存区

- 所有其他文件都属于未跟踪文件

文件状态生命周期:工作区中文件状态的改变

#0》被版本库管理的文件称为【已跟踪文件】,否则为【未跟踪文件】;

#1》【未修改】、【已修改】和【暂存区内文件】都属于【已跟踪文件】;

#2》其他文件都属于未跟踪文件;

#3》【未跟踪文件】通过 'git add' 可以变为【已跟踪文件】;

#4》【未修改文件】通过 '编辑文件' 可以变为【已修改文件】;

#5》【已修改文件】通过 'git add' 可以变为【暂存区内文件】;

#6》【暂存区内文件】通过 'commit'  存入版本库,文件又变为【未修改文件】;

检查状态

- 干净的工作区:当前没有任何跟踪着的文件,也没有任何文件在上次提交后更改过

- 信息还表明,当前目录下没有出现任何处于未跟踪的新文件

- 该命令还显示了当前所在的分支是 master, 这是默认的分支名称

#进入到git的grip仓库下

[root@kube-node1 git_lesson]# cd /root/git_lesson/grit/

[root@kube-node1 grit]# git status #查看git仓库的状态,干净的工作区

未跟踪文件

- Git 不会自动将工作区中的文件纳入跟踪范围

- 这些文件就是 Untracked  files

[root@kube-node1 ~]# cd /root/git_lesson/myweb/

[root@kube-node1 myweb]# ls #查看目录内容,'git init'不会将已存在的文件自动加入到版本库中

[root@kube-node1 myweb]# git status #查看工作区状态,index.html为未跟踪的文件

跟踪单个文件

[root@kube-node1 myweb]# git add  index.html #将单个文件index.html添加到暂存区中

跟踪所有文件

[root@kube-node1 myweb]# vim README #在当前目录下添加新的文件

git test

[root@kube-node1 myweb]# git add . #将当前目录下的所有文件,都添加到暂存区中

[root@kube-node1 myweb]# git status #当前目录下所有文件都处于暂存区中

忽略文件

- 可以创建一个名为 .gitignore 的文件

- gitignore 的格式规范如下

  - [x] 所有空行或者以注释符号 # 开头的行都会被 Git 忽略

  - [x] 可以使用标准的 glob 模式匹配【支持通配符】

  - [x] 匹配模式最后跟反斜杠(/)说明要忽略的是目录

  - [x] 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号 ( !)取反

将某些文件设置为忽略文件,【git add】时,这些文件不会添加到暂存区

[root@kube-node1 myweb]# vim function.txt #创建文件function.txt,用于演示

用户注册

留言

支付

[root@kube-node1 myweb]# echo function.txt > .gitignore #将文件名function.txt,写入到 .gitignore【忽略文件】中

[root@kube-node1 myweb]# echo .gitignore >> .gitignore #将忽略文件本身.gitignore,也写入到 .gitignore中

[root@kube-node1 myweb]# git status #查看工作区状态,设置为【忽略文件】的数据,不会在此显示

[root@kube-node1 myweb]# git add .

[root@kube-node1 myweb]# git status #设置为【忽略文件】的数据,也不会被添加到暂存区中

提交更新:直接提交会启动文本编辑器以便输入本次提交的说明

#【git commit】 提交时,需要输入【版本说明信息】 ——》这里为'project init'

#使用的编辑器为已经定义好的:【git config --global core.editor vim】

[root@kube-node1 myweb]# git commit

[root@kube-node1 myweb]# git status #【暂存区】数据提交成功,文件状态变为未修改

也可以使用 -m 参数提交说明的方式,在一行命令中提交更新

[root@kube-node1 myweb]# vim README #修改文件README

#git test

this is a test

[root@kube-node1 myweb]# git add . #将当前目录下的所有文件,都添加到【暂存区】中

[root@kube-node1 myweb]# git commit -m 'modified README' #提交

移除文件

- 要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除 (确切地说,是从暂存区域移除),然后提交

- 用git  rm 命令完成此项工作,并连带从工作目录中删除

[root@kube-node1 myweb]# git rm index.html #将index.html删除

[root@kube-node1 myweb]# git status #查看工作区状态,被删除的文件存在于暂存区【可以撤回】,commit提交后才会生效

移动文件,并进行重命名

[root@kube-node1 myweb]# git mv README README.md

[root@kube-node1 myweb]# git status

[root@kube-node1 myweb]# git commit -m 'rm index.html, mv README README.md' #提交

[root@kube-node1 myweb]# git status

查看提交历史

- 在提交了若干更新之后,又或者克隆了某个项目,回顾提交历史,使用 git  log 命令

- 每次更新都有一个 SHA-1 校验和、作者名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明

[root@kube-node1 myweb]# git log

取消已暂存文件

- 文件修改后,错误的提交到暂存区

- 希望将文件撤出暂存区,但是保留其修改的内容

[root@kube-node1 myweb]# vim README.md #在README.md文件中,添加新的行

#git test

this is a test

```python

print("Hello World!")

```

[root@kube-node1 myweb]# git add . #将修改的文件提交到【暂存区】

[root@kube-node1 myweb]# git reset HEAD README.md #取消已暂存的文件README.md

[root@kube-node1 myweb]# vim README.md #可以对README.md中的文件继续进行编辑

#git test

this is a test

```python

print("Hello World!")

print("Hello Tedu!")

```

取消对文件的修改

- 文件修改后,后悔所做出的修改

- 希望文件恢复为修改前的内容

[root@kube-node1 myweb]# git checkout  --  README.md #将版本库中的文件取出来,覆盖工作区的文件

[root@kube-node1 myweb]# cat README.md #工作区的修改都消失【谨慎操作】

git分支管理

P1 标签管理

标签概述

- 同大多数 VCS 一样,Git 也可以对某一时间点上的版本打上标签

- Git 可以给历史中的某一个提交打上标签,以示重要

- 在发布某个软件版本(比如 v1.0 等等)的时候,经常这么做

- 发布一个版本时,通常先在版本库中打一个标签(tag),这样就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。

#对某一个重要的版本打上标签,任何时候,都可以将打标签的历史版本取出来

列出标签

- 在 Git 中列出已有的标签是非常简单直观的

- 这个命令以字母顺序列出标签;但是它们出现的顺序并不重要

查找标签:可以使用特定的模式查找标签

标签分类

- Git 使用两种主要类型的标签

  - [x] 轻量标签(lightweight): 它只是一个特定提交的引用 ——》 指针指向该版本

  - [x] 附注标签 ( annotated): 是存储在 Git 数据库中的一个完整对象。其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU  Privacy  Guard (GPG) 签名与验证

附注标签

- 简单的方式是当你在运行 tag 命令时指定 -a  选项

轻量标签

- 创建轻量标签,不需要使用选项,只需要提供标签名字

[root@kube-node1 myweb]# git tag #列出已有的标签

给最近的版本打标签

[root@kube-node1 myweb]# git log #在日志中,查看版本信息

[root@kube-node1 myweb]# git tag 1.0 #tag  给最近的版本打轻量标签为 1.0

[root@kube-node1 myweb]# git tag #列出已有的标签

[root@kube-node1 myweb]# git tag v1.0 -m 'my version 1.0' #给最近的版本打附注标签

[root@kube-node1 myweb]# git tag

[root@kube-node1 myweb]# git show 1.0 #调出详细版本信息【包括做了哪些修改】

[root@kube-node1 myweb]# git show v1.0

删除标签:git   tag  -d  < tagname >

[root@kube-node1 myweb]# git tag

[root@kube-node1 myweb]# git tag -d 1.0 #删除标签1.0

[root@kube-node1 myweb]# git tag

分支概述

- 几乎所有的版本控制系统都以某种形式支持分支

- 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线

- 在很多版本控制系统中,这是一个略微低效的过程

- Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成

- 在不同分支之间的切换操作也是一样便捷

##1》开发项目时,每一个人都会从版本库的主分支下,分离一个子分支,在子分支下编写代码;

##2》代码编写完成后,将子分支合并到主分支即可;

核心原理

- 当使用 git  commit 进行提交操作时,Git 先计算每一个子目录的校验和

- 然后在 Git 仓库中,将这些校验和保存为树对象

- 随后,Git 便会创建一个提交对象,它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针

- 如此一来,Git 就可以在需要的时候,重现此次保存的快照

#1》计算要提交的每个文件的校验和(md5值),统一保存在对象变量tree中;

#2》commit 提交时,提交的是对象变量tree;

#3》对象变量tree中的每个md5值,都有对应文件;

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

#第一次提交:指针指向98ca9;

#第二次提交:指针指向34ac2,但提交对象中包含98ca9【parent】;

#第三次提交:指针指向f30ab,但提交对象中包含34ac22【parent】;

- Git 的分支,其实本质上仅仅是指向提交对象的可变指针

- Git 的默认分支名字是 master

- 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支

- 它会在每次的提交操作中自动向前移动

- master 并不是一个特殊分支,与其他分支没有区别

- Git 有一个名为 HEAD 的特殊指针,指向当前所在分支

master始终会指向最新的提交,HEAD指针指向当前所在的分支

创建分支:创建分支只是为你创建了一个可以移动的新的指针

[root@kube-node1 myweb]# git branch #查看所有的分支,'*'为当前所处的分支

[root@kube-node1 myweb]# git branch testing #创建新的分支testing,并不会切换分支

[root@kube-node1 myweb]# git checkout testing #切换到新的分支testing下

在新的分支testing下,产生文件并提交

[root@kube-node1 myweb]# cp /etc/hosts . #拷贝文件到当前目录下

[root@kube-node1 myweb]# git add . #新增或修改的所有文件,提交到暂存区

[root@kube-node1 myweb]# git commit -m 'add hosts' #提交到版本库

[root@kube-node1 myweb]# ls #查看当前目录下的文件hosts

在master主分支下,产生文件并提交

[root@kube-node1 myweb]# git checkout  master

[root@kube-node1 myweb]# cp /etc/passwd .

[root@kube-node1 myweb]# git add .

[root@kube-node1 myweb]# git commit -m 'add passwd'

[root@kube-node1 myweb]# ls #查看主分支master下的文件,和其他分支不冲突

合并分支

[root@kube-node1 myweb]# git checkout master

[root@kube-node1 myweb]# git merge testing #将子分支testing合并到主分支下

删除分支

[root@kube-node1 myweb]# git branch -d testing #-d 删除分支testing  

[root@kube-node1 myweb]# git branch #查看所有的分支, 分支删除成功

你可能感兴趣的:(git,git)