Git 是一种分布式版本控制系统,它可以不受网络连接的限制,加上其它众多优点,目前已经成为程序开发人员做项目版本管理时的首选,非开发人员也可以用 Git 来做自己的文档版本管理工具。

一、Git 基础

1.1 Git 与 SVN 区别

Git 不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。

如果你是一个具有使用 SVN 背景的人,你需要做一定的思想转换,来适应 Git 提供的一些概念和特征。

GitSVN 区别点:

  1. Git 是分布式的,SVN 不是:这是 Git 和其它非分布式的版本控制系统,例如 SVNCVS 等,最核心的区别。
  2. Git 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn.cvs 等的文件夹里。
  3. Git 分支和 SVN 的分支不同:分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。
  4. Git 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。
  5. Git 的内容完整性要优于 SVNGit 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。

1.2 版本控制

版本控制(Revision control)是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。一句话就是用于管理多人协同开发项目的技术。

  • 优点
  1. 实现跨区域多人协同开发;
  2. 追踪和记载一个或者多个文件的历史记录;
  3. 组织和保护你的源代码和文档;
  4. 统计工作量;
  5. 并行开发、提高开发效率;
  6. 跟踪记录整个软件的开发过程;
  7. 减轻开发人员的负担,节省时间,同时降低人为错误。

1.3 Git 工作区、暂存区和版本库

  1. 工作区:就是你在电脑里能看到的目录。

  2. 版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。

  3. 暂存区:本地版本库里存了很多东西,其中最重要的就是称为 stage(或者叫index)的暂存区。

下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

1.4 分支

分支是为了将修改记录的整个流程分开存储,让分开的分支不受其它分支的影响,所以在同一个数据库里可以同时进行多个不同的修改。

  • 主分支(Master)

是 Git 为我们自动创建的第一个分支,也叫主分支,其它分支开发完成后都要合并到 master

  • 分支合并(Merge)

将某分支上的更改联接到此主干或同为主干的另一个分支。

  • 合并冲突(Conflict)

多人对同一文件的工作副本进行更改,并将这些更改提交到仓库。

1.5 标签

标签是用于标记特定的点或提交的历史,通常会用来标记发布版本的名称或版本号(如:publish/0.0.1),虽然标签看起来有点像分支,但打上标签的提交是固定的,不能随意的改动。

1.6 头(HEAD)

头是一个象征性的参考,最常用以指向当前选择的分支。

二、四个区域

2.1 Workspace:工作区

  1. 程序员进行开发改动的地方,是你当前看到的,也是最新的;
  2. 平常我们开发就是拷贝远程仓库中的一个分支,基于该分支进行开发。在开发过程中就是对工作区的操作。

2.2 Index / Stage:暂存区

  1. .git 目录下的 index 文件, 暂存区会记录 git add 添加文件的相关信息(文件名、大小、timestamp...),不保存文件实体, 通过 id 指向每个文件实体。可以使用 git status 查看暂存区的状态。暂存区标记了你当前工作区中,哪些内容是被 Git 管理的;
  2. 当你完成某个需求或功能后需要提交到远程仓库,那么第一步就是通过git add 先提交到暂存区,被 Git 管理。

2.3 Repository:本地仓库

  1. 保存了对象被提交 过的各个版本,比起工作区和暂存区的内容,它要更旧一些;
  2. git commit 后同步 index 的目录树到本地仓库,方便从下一步通过 git push 同步本地仓库与远程仓库的同步。

2.4 Remote:远程仓库

远程仓库的内容可能被分布在多个地点的处于协作关系的本地仓库修改,因此它可能与本地仓库同步,也可能不同步,但是它的内容是最旧的。

2.5 四个区域的关系

  1. 任何对象都是在工作区中诞生和被修改;
  2. 任何修改都是从进入 index 区才开始被版本控制;
  3. 只有把修改提交到本地仓库,该修改才能在仓库中留下痕迹;
  4. 与协作者分享本地的修改,可以把它们 push 到远程仓库来共享。

三、Git 文件操作

版本控制就是对文件的版本控制:首先要知道文件当前在什么状态,然后才能对文件进行修改、提交等操作,不然可能会提交了现在还不想提交的文件。

3.1 文件的四种状态

  1. Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到 Git 库, 不参与版本控制.通过 git add 状态变为 Staged;
  2. Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为 Modified. 如果使用 git rm 移出版本库, 则成为 Untracked 文件;
  3. Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处,通过 git add 可进入暂存 staged 状态, 使用 git checkout则丢弃修改过, 返回到 unmodify 状态, 这个 git checkout 即从库中取出文件, 覆盖当前修改;
  4. Staged: 暂存状态.执行 git commit 则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为 Unmodify 状态. 执行 git reset HEAD filename 取消暂存, 文件状态为 Modified

3.2 查看文件状态

git status # 添加指定文件到暂存区;
git add (dir) # 添加当前目录的所有文件到暂存区。

3.3 移除文件与目录(撤销 add)

git rm --cached # 直接从暂存区删除文件,工作区不做出改变
git checkout . # 用赞寻去全部或指定文件替换工作区的文件,这个操作很危险,会清楚工作区中未添加到暂存区的改动。
git clean # 一般会加上参数 -df,-d 表示包含目录,-f 表示强制清除;

3.4 查看文件修改后的差异

git status # 只能查看对哪些文件做了改动,如果要看改动了什么,可以用;
git diff (files) # 查看文件修改后的差异

此外,还有以下两个常用命令:

git diff --cached # 比较暂存区的文件与之前已经提交过的文件
git diff HEAD~n # 比较 repo 与工作空间中的文件差异

3.5 签出

  • 使用情景

该文件已经存在仓库中,工作区已经对其进行修改过了,如果想撤销修改,可以使用 checkout

检出命令git checkout 是 git 最常用的命令之一,同时也是一个很危险的命令,因为折腾命令会重写工作区。

3.6 提交

通过 add 只是将文件或者目录添加到 index 即暂存区,使用 commit 可以实现将暂存区的文件提交到本地仓库。

git commit -m [message] # 提交暂存区到仓库区
git commit [file1] [file2] ... -m [message] # 提交暂存区的指定文件到仓库区
git commit -a # 提交工作区自上次 commit 之后的变化,直接到仓库区,跳过了 add,对新文件无效
git commit -v # 提交时显示所有 diff 信息

3.7 撤销更新

  • 撤销暂存区更新
git reset HEAD [filename] # 将暂存区指定文件移出到工作区
  • 撤销本地仓库更新

放弃工作区和暂存区的改动,同时 HEAD 指针指向前一个 commit 对象:

git log  #查看提交日志,
git reset --hard HELD~1 #撤销了上一次的提交,这里的上一次提交日志就不存在了。
cat [filename] #查看文件内内容
git revert #把指定的提交修改回滚,并同时生成一个新的提交

3.8 日志与历史

git log #查看所有提交日志;
git log [filename] #查看某文件提交日志;
history #查看在 bash 下输入过的指令;
git reflog #查看仓库中所有分支的所有更新记录,包括已经撤销的更新。

四、Git 配置

4.1 分类介绍

Git 配置文件有三个级别,分别是系统级别、全局级别以及仓库级别。下面的表格展示了各个级别的配置的具体信息:

配置级别 文件位置 配置命令 优先级别
系统 Git 安装目录\etc\gitconfig git config --system
全局 用户文件夹.gitconfig git config --global
仓库 仓库文件夹.git\config git config --local

4.2 Git 常用配置命令

  • 对全局的 Git 用户名和邮箱进行配置
git config --global user.name "xxxx" :设置所有仓库提交的用户名
git config --global user.email "xxxx@example.com":设置所有仓库提交的邮箱
  • 查看所有配置或某一项配置:
git config --global  --list;
git config --global --get user.name;
git config --global --get user.email;

系统和当前项目的命令同上,仅需将global改为system/local即可。

五、本地仓库

创建本地仓库的方法有两种:一种是创建全新的仓库,另一种是克隆远程仓库。

5.1 创建全新仓库

  • 使用当前目录作为 Git 仓库

只需使它初始化:git init ;执行后可以看到,仅仅在项目目录多出了一个.git 目录;

  • 使用指定目录作为 Git 仓库

使用如下命令,可以把创建目录与仓库一起完成:

git init [project-name] # 新建一个目录,将其初始化为 Git 代码库

5.2 克隆远程仓库

  1. 将远程服务器上的仓库完全镜像一份至本地,而不是取某一个特定版本,所以用 clone 而不是 checkout,语法格式为:
git clone (url)

例如:我们要从克隆的远程仓库托管在 Github 上,首先,我们先前往 Github 上拷贝地址如:

https://github.com/vanDusty/Java-Note,然后执行:

git clone https://github.com/vanDusty/Java-Note```

克隆远程仓库到当前目录。

### 5.3 Git 仓库目录结构

- 初始化仓库使用 `git init` 命令,初始目录(`.git`)结构:

```xml
.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags 9 directories, 13 files
  • 这个初始化后的仓库,当创建完分支 dev-branch,并 push 后的目录结构:
.git/
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ ├── heads
│ │ ├── dev-branch
│ │ └── master
│ └── remotes
│ └── origin
│ └── master
├── objects
│ ├── 2d
│ │ └── d2c71b69c837a7459f4bd9c9f7db6520731d06
│ ├── 5c
│ │ └── 7b8eda18a75e13d27c31e65a54b0abd7948510
│ ├── 77
│ │ └── cad3aecf7c2754231095598119979d62a1e1da
│ ├── info
│ └── pack
└── refs
├── heads
│ ├── dev-branch
│ └── master
├── remotes
│ └── origin
│ └── master
└── tags 19 directories, 25 files

5.4 目录结构说明

  • branches 目录

一种不常用的存储速记方式,用于指定 git fetchgit pullgit pushURL ,目前已基本不用。

  • COMMIT_EDITMSG 文件

commit 编辑信息,仅记录最近一次提交的 commit 编辑信息。

  • config 文件

存储当前仓库的配置信息

  • description 文件

用于在 GitWeb 中展示项目的描述信息。

  • HEAD 文件

存储 HEAD 指针,指向当前分支,即:记录当前活动分支。

  • hooks 目录

目录下存储了许多钩子文件(一些脚本),这些文件是各种 Git 命令使用的自定义脚本,可以在 Git 特定阶段自动执行。

  • index 文件

暂存区(stage),二进制文件。

  • info 目录

存储库的其他信息将记录在此目录中。

  • logs 目录

保存所有更新的引用记录。

  • objects 目录

简单理解就是:objects 目录是 Git 的数据库,存储所有数据内容。

  • refs 目录

(1)heads 目录

目录有以各个本地分支名命名的文件,保存对应分支最新提交的 ID,是通过 SHA1 算法计算的一个字符串。

(2)remotes 目录

目录有以各个远程分支名命名的文件,保存对应分支最新提交的 ID,和 heads 目录一个原理。

(3)tags 目录

存储在开发过程中打的标签,里面的文件以标签名命令,文件内容为对应的 ID

六、远程仓库

Git 是分布式版本控制系统,同一个 Git 仓库,可以分布到不同的机器上,即发布到不同的远程仓库上。

6.1 常见的托管平台

  • GitHub

对,就是那个“全世界最大同性交友网站”。https://github.com

绝大多数好的开源项目都来自 GitHub,但是 GitHub 只能新建公开的 Git 仓库,私有仓库要收费,有时候访问比较卡,如果你做的是一个开源项目,可以首选 GitHub。

  • Gitlab

提到 GitHub 就会自然的想到 Gitlab,Gitlab 支持无限的公有项目和私有项目。https://about.gitlab.com

  • Bitbucket

Bitbucket免费支持 5 个开发成员的团队创建无限私有代码托管库。https://bitbucket.org

  • Gitee 码云

前面说的都是国外的,下面来说几个国内的。码云,个人开发者可免费创建 1000 个项目(不限公有、私有),提供最多 5G 的免费代码存储空间。http://git.oschina.net

  • Coding.net

谈到 Coding.net,首先必须提的是速度快,同样一个账号最多可以创建 1000 个项目(5 个私有),也支持任务的创建等。https://coding.net

6.2 远程仓库操作

申请到了 Git 远程仓库的帐号并创建了一个空的远程仓库现在我们就可以结合本地的仓库与远程仓库一起协同工作了,多人协同开发,这也是我们工作时的情形,这里我们全部使用命令完成(实际开发中很多开发工具例如:IDEA 等,无需命令操作)。

  • 克隆项目

远程操作的第一步,通常是从远程主机克隆一个版本库,这时就要用到 git clone 命令,例如:

git clone https://github.com/vanDusty/Java-Note

该命令会在本地主机生成一个目录,与远程主机的版本库同名。如果要指定不同的目录名,可以将目录名作为 git clone 命令的第二个参数。

git clone <版本库的网址> <本地目录名>

git clone 支持多种协议

除了 HTTP(s)以外,还支持 SSHGit、本地文件协议等。通常来说,Git 协议下载速度最快,SSH 协议用于需要用户认证的场合。各种协议优劣的详细讨论请参考官方文档。

  • git remote

为了便于管理,Git 要求每个远程主机都必须指定一个主机名。git remote 命令就用于管理主机名。

不带选项的时候, git remote 命令列出所有远程主机名。

git remote -v  #参看远程主机的网址。

结果表示,当前只有一台远程主机,叫做 origin,以及它的网址。

origin  git@github.com:jquery/jquery.git (fetch)
origin git@github.com:jquery/jquery.git (push)

克隆版本库的时候,所使用的远程主机自动被 Git 命名为 origin 。如果想用其他的主机名,需要用 git clone 命令的 -o 选项指定:

git clone -o dusty https://github.com/vanDusty/Java-Note

上面命令表示,克隆的时候,指定远程主机叫做 dusty

更多命令如下:

$ git remote show <主机名>  #查看该主机的详细信息
$ git remote add <主机名> <网址> #添加远程主机
$ git remote rm <主机名> #删除远程主机
$ git remoterename<原主机名> <新主机名> #远程主机的改名
  • git fetch

一旦远程主机的版本库有了更新,需要将这些更新取回本地,这时就要用到该命令。

git fetch  #将某个远程主机的更新,全部取回本地。
git fetch <远程主机名> <分支名> #取回指定主机名的指定分支

所取回的更新,在本地主机上要用"远程主机名/分支名"的形式读取。比如 origin 主机的 master,就要用 origin/master 读取。

git checkout -b newBrach origin/master  #在 origin/master 的基础上,创建一个新分支。

也可以使用 git merge 命令或者 git rebase 命令,在本地分支上合并远程分支。

git merge origin/master #或者$ git rebase origin/master
  • git pull

git pull 命令的作用是,取回远程主机某个分支的更新,再与本地的指定分支合并。它的完整格式稍稍有点复杂。

git pull <远程主机名> <远程分支名>:<本地分支名>

示例:取回 origin 主机的 master 分支,与本地的 develop 分支合并:

git pull origin master:develop

如果远程分支( master)要与当前分支合并,则冒号后面的部分可以省略。可以简写为:

git pull origin master

上面命令表示,取回 origin/master 分支,再与当前分支合并。实质上,这等同于先做 git fetch ,再做 git merge

git fetch origin
git merge master/develop
  • git fetchgit pull 的区别
git fetch:相当于是从远程获取最新版本到本地,不会自动合并。
git pull:相当于是从远程获取最新版本并merge到本地

七、Git 命令

偷个懒,发现一个很全的【Git常用命令参考手册

【Git 系列】基础知识全集的更多相关文章

  1. Git入门——基础知识问答

    问题一:为什么要选择Git作为Android开发的版本控制工具?     答:1)git是android项目和社区的统一语言.            2)高通版本发布频繁,需要与平台及时同步,快速re ...

  2. DOM系列基础知识

    DOM (Document Object Model) 即文档对象模型, 针对 HTML 和 XML 文档的 API (应用程序接口) .DOM 描绘了一个层次化的节点树,运行开发人员添加.移除和修改 ...

  3. git的基础知识

    git 分布式版本控制工具 具备的功能 协同开发 多人并行不悖修改服务器端的同一个文件 数据备份 不仅保持目录和文件当前状态,还能保存每一个提交的历史版本 版本管理 保存每一个版本的文件信息的时候做到 ...

  4. html5系列.基础知识

    兼容性问题 创建一个html5页面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...

  5. selenium+python自动化测试系列---基础知识篇(1、HTML基础知识1)

    1.什么是HTML HTML是一种描述网页的语言.HTML指超文本标记语言(Hyper Text Markup Language),它不是一种编程语言,而是一种标记语言(markup language ...

  6. ldap系列-基础知识

    来源:关键字排名 ldap 是什么? LDAP(Lightweight Directory Access Protocol)即轻量级目录访问协议,提供信息服务.那啥是目录服务呢? 目录服务是一种特殊的 ...

  7. JVM菜鸟进阶高手之路十(基础知识开场白)

    转载请注明原创出处,谢谢! 最近没有什么实战,准备把JVM知识梳理一遍,先以开发人员的交流来谈谈jvm这块的知识以及重要性,依稀记得2.3年前用solr的时候老是经常oom,提到oom大家应该都不陌生 ...

  8. 【Xamarin开发 Android 系列 4】 Android 基础知识

    原文:[Xamarin开发 Android 系列 4] Android 基础知识 什么是Android? Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Li ...

  9. .NET面试题系列[1] - .NET框架基础知识(1)

    很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...

随机推荐

  1. 【vue】使用 Video.js 播放视频

    目录 安装 引入 使用 参考文档 环境: vue 2.0+ element ui (这里的代码用了elmentui的按钮样式,可以不用elment ui的样式) 安装 在项目中安装 video.js. ...

  2. NOIP 模拟七 考试总结

    T1匹配 签到大水题,这里有hash,kmp,ac自动机,还有后缀数组,后缀自动机任您挑选. 不过这个数据范围有些坑啊,re就很不爽.做法我还是比较倾向hash的,毕竟不论神魔字符算法,hash大都能 ...

  3. Bert文本分类实践(一):实现一个简单的分类模型

    写在前面 文本分类是nlp中一个非常重要的任务,也是非常适合入坑nlp的第一个完整项目.虽然文本分类看似简单,但里面的门道好多好多,作者水平有限,只能将平时用到的方法和trick在此做个记录和分享,希 ...

  4. 无法解析的外部符号"void_cdecl caffe::caffe_gpu_dot<double>(int,double........)"

    将源码中的.cu文件添加到项目中即可,即使创建的就是NVIDIA的项目,也需要把这些个.cu文件添加进来

  5. 2020.10.9--vj个人赛补题

    B - A Tide of Riverscape 题意:给出一组字符串,由'0','1',' . '组成,' . '可以换成 0或1,判断第 i  个和第 i+p 个字符是否可以不相等,如果可以则输出 ...

  6. ❤️【Python从入门到精通】(二十七)更进一步的了解Pillow吧!

    您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦. 进一步介绍Pillow库的使用,详细了解 干货满满,建议收藏,需要用到时常看看. 小伙伴们如有问题及需要,欢迎踊跃留言哦~ ~ ~. 前言 本文是 ...

  7. docker初探和基础搭建

    个人博客 docker中文手册 Docker 是什么? docker是一个开源的软件部署解决方案: docker也是轻量级的应用容器框架: docker可以打包.发布.运行任何的应用. 在我的粗浅理解 ...

  8. WIFI Deauth攻击-爬坑笔记

    这里用Aircrack这款工具进行介绍: 准备工作:无线网卡连接电脑或者虚拟机(免驱的最好),如需驱动请自行安装驱动 1.将无线网卡接入测试电脑Linux虚拟机(装有Aircrack-ng) 2.测试 ...

  9. MongoDB中如何优雅地删除大量数据

    删除大量数据,无论是在哪种数据库中,都是一个普遍性的需求.除了正常的业务需求,我们需要通过这种方式来为数据库"瘦身". 为什么要"瘦身"呢? 表的数据量到达一定 ...

  10. [对对子队]Beta阶段项目展示博客

    Beta阶段项目展示博客 1 团队成员的简介和个人博客地址 成员 头像 岗位 博客 个人介绍 黄贤昊 PM 17373253 喜欢玩游戏和做游戏,项目经验基本都和游戏相关,擅长摸鱼,偶尔敬业. 吴桐雨 ...