type
status
date
slug
summary
tags
category
icon
password
Git 前世今生
1991 年,Linus Torvalds 开发了开源的 Linux 内核。随着越来越多全球志愿者参与,Linux 项目的规模迅速扩大。2002 年以前,这些志愿者通常将自己修改的代码通过 diff 文件发送给 Linus,由 Linus 手动合并到代码库中。这种方式不仅低效,而且很容易出错。
Linus 一直反对使用 CVS、SVN 这类集中式版本控制系统,因为它们速度慢,还必须联网。而市面上虽然有一些更好用的商用系统,但它们大多是收费的,不符合 Linux 的开源精神。到了 2002 年,出于管理压力,Linus 选择了一个免费的商业工具 —— BitKeeper,其公司 BitMover 出于人道主义精神,允许 Linux 社区免费使用。
Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。安定团结的大好局面在2005年就被打破了,原因是开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。危机之下,Linus 在两周内用 C 语言写出了一个全新的分布式版本控制系统——Git。一个月内,整个 Linux 内核项目已完全迁移至 Git 进行管理。这就是 Git 的起点。
Git 问世之后,很快因其高效、灵活而被广泛采纳。2008 年,GitHub 上线,它为开源项目提供免费的 Git 托管服务,极大地推动了 Git 的流行。许多知名项目如 jQuery、PHP、Ruby 等也陆续迁移到 GitHub,Git 由此成为最受欢迎的版本控制系统之一。
了解了 Git 的由来,那么 Git 到底是什么呢?Git 是一个开源的、分布式的版本控制系统,用于高效地管理各种类型的项目文件,尤其适合代码的版本管理与团队协作开发。版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态。代码管理工具的用途:防止代码丢失,做备份。项目的版本管理和控制,可以通过设置节点进行跳转。建立各自的开发环境分支,互不影响,方便合并。在多终端开发时,方便代码的相互传输
举个生活中的例子,假设你用 Microsoft Word 撰写一份报告,你可能会担心修改后找不回原来的内容,于是你不断地另存为多个版本,比如:
报告_v1.docx
、报告_v2_改了前言.docx
、报告_最终版(真的最后一版).docx
。最后你面对一堆文档,根本不知道哪个才是想要的版本。而你还得把文档发给同事,等她修改完再发回来,你又要手动对比和合并她的更改,累且混乱。过了一周,你想找回被删除的文字,但是已经记不清删除前保存在哪个文件里了,只好一个一个文件去找,看着一堆乱七八糟的文件,想保留最新的一个,然后把其他的删掉,又怕哪天会用上,还不敢删。更要命的是,有些部分需要你的财务同事帮助填写,于是你把文件Copy到U盘里给她(也可能通过Email发送一份给她),然后,你继续修改Word文件。一天后,同事再把Word文件传给你,此时,你必须想想,发给她之后到你收到她的文件期间,你作了哪些改动,得把你的改动和她的部分合并,真困难。于是有一个软件,不但能自动帮我记录每次文件的改动,还可以让同事协作编辑,这样就不用自己管理一堆类似的文件了,也不需要把文件传来传去。如果想查看某次改动,只需要在软件里瞄一眼就可以,岂不是很方便?版本 | 文件名 | 用户 | 说明 | 日期 |
1 | service.doc | 张三 | 删除了软件服务条款5 | 7/12 10:38 |
2 | service.doc | 张三 | 增加了License人数限制 | 7/12 18:09 |
3 | service.doc | 李四 | 财务部门调整了合同金额 | 7/13 9:51 |
4 | service.doc | 张三 | 延长了免费升级周期 | 7/14 15:17 |
首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件。因为文本是有编码的,比如中文有常用的GBK编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。
集中式 VS 分布式:
集中式版本控制系统
:版本库是集中存放在中央服务器的,干活的时候,用的都是自己电脑上的工作副本,所以得先从中央服务器获取最新的版本,然后才能开始工作,干完活再把修改推送回中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后带回家自己修改,改完再还回图书馆。而且,集中式版本控制系统必须联网才能使用。如果在局域网内还好,带宽够大,速度也快;但如果是在互联网上,遇到网速慢的情况,比如提交一个10M的文件,可能就要等上好几分钟。
分布式版本控制系统
:它没有一个单独的中央服务器,每个人的电脑上都有一个完整的版本库,包括代码和历史记录。所以你干活的时候,根本不需要联网,版本库就在你本地。那多人协作的时候怎么办呢?比如你在自己的电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时候,只需要你们互相把各自的修改推送给对方,就可以看到彼此的更改了。和集中式版本控制系统相比,分布式的安全性更高。因为每个人电脑上都有一份完整的版本库,就算某个人的电脑坏了,也没关系,随便从别人那里拷贝一份就能恢复。而集中式系统要是中央服务器挂了,所有人都得停工,啥也干不了。不过在实际使用分布式系统的时候,很少是你把代码直接推送到你同事的电脑上。一方面你们可能不在一个局域网里,互相访问不了;另一方面,他今天可能还病了,电脑压根没开机。所以,虽然分布式系统理论上不需要中央服务器,但大家通常还是会设置一个
中央服务器(比如GitHub或Gitee)
,只是为了方便集中交换各自的修改。这个服务器的作用就是中转站,没有它也可以干活,只不过同步更新不那么方便而已。Git 安装
Windows环境下安装Git
下载Git,以下两种下载方式任选其一:
方法一:清华大学镜像网站 https://mirrors.tuna.tsinghua.edu.cn/github-release/git-for-windows/git/LatestRelease 下载安装包,点击64位的安装包下载

方法二:<a href="https://git-scm.com/downloads">Git官网下载</a>,下载地址来源于Github,速度较慢,选择Windows系统安装包下载

选择64位安装包下载

1、双击打开安装包,此时会弹出GNU通用公共协议界面,点击Next:

2、点击Browse选择安装路径,这里我安装在D盘。选择好路径以后,点击Next:

3、如果出现下图的弹窗提示文件夹已经存在,点击是即可。没有此提示的小伙伴直接跳转到下一步:

4、选择要安装的组件:按照默认勾选即可,后面两个以(NEW!)开头的可以不勾选,完成后点击Next:

5、选择开始菜单文件夹,如果你对此操作不熟悉的话,就不用修改任何内容。完成后点击Next:

6、默认编辑器选择Vim。点击Next:

7、设置新仓库初始分支的名字,按照系统默认选择Let Git decide(让Git自己决定),完成后点击Next:

8、调整环境变量,按照系统推荐选择
Git from the commond line and alos from 3rd-party software
。勾选上述选项的作用是将Git添加到环境变量中,后续你可以在Windows的命令行、PowerShell、Git Bash和其他第三方软件中使用Git命令。点击Next:
9、选择可执行的SSH工具,这里按照默认勾选Use bundled OpenSSH(使用Git自带的SSH工具),点击Next:

10、选择HTTPS连接时,Git使用的是SSL还是TLS库,这里按照系统默认勾选Use the OpenSSL library,点击Next:

11、换行风格选择,按照系统默认勾选Checkout Windows-style, commit Unix-style line endings:

12、按照系统默认勾选Use MinTTY(the default terminal of MSYS2),点击Next:

13、 配置从服务器拉取代码的默认操作,按照系统默认勾选Fast-forward or merge,点击Next:

14、按照系统默认勾选Git Credential Manager,点击Next:

15、配置额外选项,按照系统默认勾选Enable file system caching(开启文件系统缓存),点击Next:

16、配置实验性选项,这里全部不勾选,点击Install开始安装:

17、安装完成,上方内容全部取消勾选,点击Finish。至此,Git安装完成:

完成安装之后,就可以使用命令行的git工具,已经自带了 ssh 客户端

当你点击 git bash Here 菜单之后,可以看到一个终端窗口,在终端里面输入命令
git --version
,如果可以看到 git 的版本信息,则说明安装成功
Linux系统上安装Git
使用 yum 安装 Git
如果需要安装特定版本的 Git,或者想要最新版本,可以选择从源代码编译安装。下载 Git 源代码
安装必要的依赖包
编译并安装 Git
验证安装
在线Git交互式
这份30.6K start的Git交互式教程你值得拥有,涵盖的内容足够让你应对工作需求,更重要的是对于新手来说这份教程直接把Git命令操作给你画出来了。不信你还会看不懂Git命令到底做了什么,网站地址:<a href="https://learngitbranching.js.org/?locale=zh_CN&NODEMO=">https://learngitbranching.js.org/?locale=zh_CN&NODEMO=</a>

Git使用入门
Git基本流程
Git的工作流程核心就下面几个步骤,掌握了就可以开始写Bug了。
0、准备仓库:创建或从服务端克隆一个仓库。
1、搬砖:在工作目录中添加、修改代码。
2、暂存(git add):将需要进行版本管理的文件放入暂存区域。
3、提交(git commit):将暂存区域的文件提交到Git仓库。
4、推送(git push):将本地仓库推送到远程仓库,同步版本库。
5、获取更新(fetch/pull):从服务端更新到本地,获取他人推送的更新,与他人协作、共享。

初始化配置 git config
在一台新的电脑上使用 Git 之前,通常需要做一次基础配置。这些配置只需执行一次,以后即使升级 Git,也会自动沿用。Git 提供了
git config
命令用于查看或设置 Git 的环境变量。这些变量会影响 Git 的行为,比如你是谁、默认编辑器是什么、换行符如何处理等。Git 的配置可以存在三个不同的层级,优先级从低到高如下:
/etc/gitconfig
:系统级,系统中对所有用户都普遍适用的配置
~/.gitconfig
或~/.config/git/config
:用户级,当前用户所有仓库都使用这个配置
仓库目录下的.git/config
:项目级,仅对当前 Git 仓库生效,优先级最高因为 Git 是分布式版本控制系统,每台电脑都保存完整的版本历史。每次提交时,Git 会记录作者信息(名字和邮箱),这就需要你自报家门了。说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录。使用下面命令设置当前用户的名字和邮箱,建议添加
--global
,表示对所有仓库有效:查看用户名和邮箱
删除配置信息
如果你想查看当前配置了哪些内容,可以用以下命令
或者查看具体配置文件
创建仓库
仓库也叫版本库,英文名是 repository。你可以把它简单理解为一个
被 Git 管理的目录
。这个目录中的所有文件,包括它们的修改记录、删除操作,Git 都会自动进行跟踪。一旦你把一个目录变成了 Git 仓库,Git 就能记录下这个目录里每个文件的历史变化。这样不仅可以随时查看过去的改动记录,还可以在需要时将文件恢复到之前的某个状态。创建一个 Git 仓库非常简单。只需要在你想要管理的目录下执行
git init
命令。比如你想在/data目录下创建一个名为 git_repository 的目录作为你的项目仓库,可以按以下步骤操作:初始化仓库 git init
执行
git init
之后,这个目录就变成了一个 Git 仓库,Git 会在当前目录中自动创建一个名为 .git
的隐藏文件夹,所有的版本记录、配置和元数据都会保存在这个 .git
文件夹中。首先要明确下,所有的版本控制系统,只能跟踪文本文件的改动,比如txt文件,网页,所有程序的代码等,Git也不列外,版本控制系统可以告诉你每次的改动,但是图片,视频这些二进制文件,虽能也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是知道图片从1kb变成2kb,但是到底改了啥,版本控制也不知道。
注意:不要手动删除或修改
.git
文件夹,否则可能导致版本库损坏。如果你想判断一个目录是不是 Git 仓库,看一下里面有没有 .git
文件夹就知道了工作区/暂存区/仓库
Git 会把它要管理的源代码放在一个目录中,这个目录的名字通常就是项目的名字,因此,这个目录也就被称为项目的根目录(起始位置)。在这个目录里,Git 会为版本控制机制划分出三个核心空间:
工作区
:当前工作目录,项目目录内部的空间即为工作区。
暂存区
:这是 Git 开始正式跟踪和记录更改的地方。你在工作区做了一些修改之后,需要用命令 git add
把这些更改提交到暂存区。
版本库
:在项目目录下,有一个叫 .git
的隐藏目录,Git 所有的核心数据都藏在这里,包括版本库
和暂存区
其实都在这个目录中。工作区、暂存区、版本库是Git最基本的概念,关系如下图:

Git本地版本控制的基本工作流程:
开始使用git时,需要先于项目目录中运行
git init
命令,生成.git
目录结构,完成版本库初始化。暂存和提交两个步骤是周期类操作,可根据城要重复运行。随着用户在工作区编码工作的展开,可随时按需运行 git add
命令将工作区中的更改暂存,该区域通常也称为索引,暂存区累积的更改操作,可由用户使用 git commit
命令一次性地提交到版本库中,每次提交操作完成后会生成一个反映到提交操作这一该工作区的状态快照,并可拥有名称和标识,即commit name
和commit id
。
添加到暂存区 git add
在Git版本控制系统中,
git add
命令是非常关键的一步,它用于将工作区的更改添加到暂存区,为随后的提交做准备。该命令的基本语法如下:添加所有更改:使用
.
作为参数,表示添加所有工作区中的更改。这是一种快捷方式,适用于你想要一次性添加所有更改的情况。示例:在工作区新增一个文本文件
新文件从来没有被添加过,所以它的状态是Untracked
把文件添加到暂存区
再次执行查看状态
现在,暂存区的状态就变成这样了:
git add
命令实际上就是把要提交的所有修改放到暂存区(Stage),然后执行git commit
就可以一次性把暂存区的所有修改提交到分支。
添加到本地仓库 git commit
把文件提交到仓库,需要使用
git commit
命令,格式如下:其中
-m
后面跟的是本次提交的说明文字,你可以输入任何内容,但强烈建议写清楚本次提交做了什么修改。这样做的好处是方便你以后查看提交历史,能快速定位到每次改动的目的和内容,尤其在多人协作或者回溯调试时特别重要。一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是干净的
现在版本库变成了这样,暂存区就没有任何内容了

检查当前文件状态 git status
在使用
git add
之前,建议先通过 git status
查看当前工作区和暂存区的状态,以确保你要添加的是正确的更改。Git 中的文件状态可以分为两大类:已跟踪(Tracked)
和未跟踪(Untracked)已跟踪(Tracked)
:已纳入 Git 管理的文件,这些文件在上一次提交的快照中已经存在。在开发过程中,它们可能处于以下三种状态之一:
已提交:文件已经被提交到了版本库中。
已修改:文件内容被更改,但尚未放入暂存区。
已暂存:更改已通过 git add 放入暂存区,准备提交。
未跟踪(Untracked)
:这些是 Git 尚未管理的文件:
没有纳入任何一次提交快照;
不在当前暂存区中;
通常是新创建的文件。可以通过
git status
一眼看出哪些是未跟踪文件。比如我们修改readme.txt文件git status
命令可以让我们时刻掌握仓库当前的状态,文件被修改过了,但还没有准备提交查看哪些修改还没有暂存
添加到暂存区
查看当前工作区和暂存区的状态
提交
再次查看状态
撤回工作区中的修改 git checkout
只在本地工作区修改了文件A,包括删除文件A,但还没有使用
git add
把 A 的修改暂存到暂存区。这时我们可以撤销对文件内容的修改,也可以撤销对文件 A 的删除,但是新建的文件无法撤销。撤销工作区修改命令:下面我们来修改文件,文件修改后还没有被放到暂存区
把文件在工作区的修改全部撤销
文件修改后,还没有放到暂存区,使用撤销修改就回到和版本库一模一样的状态
撤回暂存区中的修改git reset
有时候我们提交了一些错误的或者不完善的代码,需要回退到之前的某个稳定的版本,面对这种情况有两种解决方法:
解决方法1:修改错误内容,再次commit一次。适合轻微错误的场景,直接改代码 → git add → git commit。
解决方法2:使用 git reset 命令撤销这一次错误的commit,彻底撤销一次提交的情况,不想留下错误记录。
第一种方法比较直接,但会多一次commit记录,同时并不是所有场景都可以这么做。所以建议使用第二种方法,因为错误的commit没必要保留下来。
git reset
命令用于回退版本,可以指定退回某一次提交的版本。reset 命令的原理是根据 commitId 来恢复版本,因为每次提交都会生成一个 commitId,所以说 reset 可以帮你恢复到历史的任何一个版本。命令格式如下:git reset 主要有三种模式:
模式 | HEAD(指针) | 暂存区(Index) | 工作区(文件) | 适用场景 |
--soft | ✅ 移动 | ✅ 保留 | ✅ 保留 | 撤销提交但保留更改 |
--mixed | ✅ 移动 | ❌ 清除 | ✅ 保留 | 清除暂存但保留文件修改(默认) |
--hard | ✅ 移动 | ❌ 清除 | ❌ 清除 | 撤销提交并清空修改,非常危险! |
回退所有内容到上一个版本,默认 mixed 模式
指定文件回退到上个版本,比如回退test.txt这个文件的版本到上一个版本
在Git中,HEAD指向的版本就是当前版本,上一个版本就是
HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100。比如向前回退到第3个版本回退到某个版本51363e6
如果你已经把错误的 commit push 到远程仓库,再用 reset 回退,是不会自动同步远程的。你需要用强制推送
git push -f
,但这非常危险!!因为会覆盖远程分支历史。一定先用git pull
确保不会覆盖别人最新提交。现在我们来修改文件内容,可以自形进行演示
通过
git log
指令可以查看提交记录日志,可以很方便的查看每次提交修改了哪些文件,改了哪些内容,从而进行恢复等操作Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是改变HEAD指向

分支
分支(Branch)
就是在原有代码的基础上,为自己创建一个独立的开发环境。每个人都可以在自己的分支上开发,互不干扰,开发完成后再把自己的分支合并回主分支。为什么要用分支?假设你要开发一个新功能,预计需要两周时间。第一周完成了 50% 的代码,但功能还不完整。如果这时提交代码,会影响团队其他成员使用这份代码继续开发。而如果等两周后再统一提交,又可能会因为意外情况导致代码丢失。这时候你可以创建一个属于自己的分支,在这个分支上随时提交、保存进度,别人看不到你的未完成代码,团队其他成员仍可在主分支上正常工作。功能开发完成后,再将你的分支合并回主分支即可。这样既保障了进度,又不干扰团队协作。
可以把分支想象成科幻电影中的平行宇宙:你在一个宇宙中学习 Git,另一个你在另一个宇宙中学 SVN,互不干扰。某个时间点,这两个宇宙合并了——你就同时掌握了 Git 和 SVN。

虽然其他版本控制工具(如 SVN)也支持分支,但创建和切换速度慢,用户体验差,导致分支功能很少被使用。而 Git 的分支非常轻量,创建、切换、删除都能在 1 秒内完成,无论你的项目中是 1 个文件还是 1 万个文件。也正因为如此,Git 鼓励开发者频繁使用分支来管理功能、任务和修复工作。
分支策略
分支策略是软件协作项目的灵魂,是软件协作模式和发布模式的风向标。选择一种符合 DevOps 开发模式的分支策略,对于 DevOps 的实践落地也会大有帮助,常见的分支策略:
主干开发,主干发布
:在master/main上开,直接在master/main发布
分支开发,主干发布
:在develop分支上开发,合并至master/main分支,经由main/master发布
主干开发,分支发布
:在master/main上直接开发,master/main拥有全量代码团队协作开发流程示例:假设 Tom 和 Jerry 是同一个项目团队的成员,项目使用一个名为 master 的分支来维护生产部署和源代码文件。其开发协作流程如下:
主分支职责明确
:master 分支用于跟踪部署到生产环境的源代码。
开发新功能
:每当需要开发新功能,Tom 和 Jerry 会分别从 master 分支创建各自的 feature 分支,如 feature/tom-login
、feature/jerry-report
等。
功能开发阶段
:在各自的 feature 分支中进行日常开发,并提交变更。
本地测试与构建
:功能开发完成后,在本地或测试环境中构建并测试代码,确保功能正常且不破坏原有逻辑。
合并回主分支
:测试无误后,将各自的 feature 分支通过 git merge 合并回 master 分支。
最终测试与验证
:代码合并回 master 后,再次进行完整的功能回归测试与验证,确保主分支代码稳定。
部署上线
:验证通过后,将 master 分支中最新的代码部署到生产环境,新功能正式上线。
清理分支
:所有相关功能分支(如 feature/tom-login、feature/jerry-report)在合并完成后会被删除,以保持仓库整洁,避免短期分支混乱版本历史。分支命令
git branch
:查看所有本地分支, 当前分支前面会有一个星号,-r
查看远程分支, -a
查看所有分支。
git branch <branch-name>
:创建一个新的分支。
git checkout <branch-name>
:切换到指定分支, 并更新工作区。
git checkout -b <branch-name>
:创建并切换分支
git merge <branch-name>
:合并分支
git branch -d <branch-name>
:删除一个已经合并的分支。
git checkout -D <branch-name>
:删除一个分支, 不管是否合并。
git tag <tag-name>:给当前的提交打上标签, 通常用于版本发布。
git merge --no-ff -m message <branch-name>指针
在 Git 中,HEAD 是一个特殊的指针,用来标记你当前所在的分支。比如你当前在 master 分支上工作,HEAD 就指向 master。第一次提交后,master 指向第一次提交,HEAD 仍然指向 master。每次提交,master 向前移动一格,HEAD 跟着它一起移动。当你切换到 dev 分支时,HEAD 会自动转向 dev。你可以把 HEAD 理解为我现在在哪条开发线上的标记。随着你不断提交,master 分支就像一条不断延伸的直线,而 HEAD 一直跟着这条线向前移动。
查看文件指示目前被检出的分支

创建分支
在一个 Git 仓库中,我们可以创建多个分支branch。大多数开发者在处理不同任务时,通常会为每个任务新建一个分支。这样做可以让各项工作互不影响,便于管理和协作。使用
git branch
命令可以用来创建一个新的分支。例如,创建一个testing分支这条命令会在当前提交的位置上创建一个名为 testing 的新分支,也就是添加一个新的指针指向当前提交。需要注意的是
git branch
只是创建分支,但不会自动切换到这个分支上
切换分支
git branch
只是创建分支,但不会自动切换到这个分支上。也就是说,你仍然停留在原来的分支上(比如 master),想要切换到新分支,需要使用 git checkout
命令。比如切换到testing分支这里也可以使用命令
git checkout -b testing
,加上-b
参数表示创建并切换,相当于以下两条命令:git branch testing
和 git checkout testing
每次在切换分支前最好先提交当前的修改,保持当前分支干净,也就是工作区没有未提交的更改。虽然 Git 在某些情况下允许你带着修改切换分支,但这种做法可能会把修改内容带到另一个分支中,导致混乱或代码污染,特别是在多人协作时更容易出问题。
查看当前分支引用的指针
查看当前分支,
git branch
命令会列出所有分支,当前分支前面会标一个*
号
切换分支只是修改了HEAD的指向,工作区的文件都没有任何变化。比如我们修改readme.txt文件内容,然后提交到testing分支,testing指针往前移动一步,而master指针不变

切回master查看 readme.txt 文件,发现刚才添加的内容不见了!因为那个提交是在 testing 分支上,而 master 分支此刻的提交点并没有变

合并分支
git merge
命令用于将一个或多个分支的变更合并到当前检出的分支中。合并完成后,当前分支的指针将会移动到新的合并结果上。一般用法如下:合并前,请确保你当前检出的是目标分支,也就是你想合并进哪个分支,就先 checkout 到它。比如我们把 testing 分支的工作成果合并到 master 分支上
人生不如意之事十之八九,合并分支往往也不是一帆风顺的。如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们,在合并它们的时候就会产生合并冲突。下面我们来创建一个新的 feature 分支,并切换到该分支
切换到master分支修改提交
现在 master 分支和 feature 分支各自都分别有新的提交,Git无法执行快速合并,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,变成了这样

文件存在冲突,必须手动解决冲突后再提交。Git用
<<<<<<<,=======,>>>>>>>
标记出不同分支的内容,我们修改如下后保存:我们修改如下后保存
修改完后再提交
现在 master 分支和 feature 分支变成了下图所示

如果有多个分支,那么我们该如何操作?
删除分支
不能在当前激活的分支上执行删除操作。首先切换到不同的分支,例如切换到master或main分支:
使用以下命令删除本地分支
如果该分支有尚未合并的更改,这个命令会失败。可以使用-D选项强制删除
标签管理
在发布一个版本时,我们通常会在 Git 仓库中打一个
标签(tag)
,用于标记此时的版本快照。这样就能唯一标识该时刻的版本状态,方便未来随时查找和恢复。远程仓库
Git 是一种
分布式版本控制系统
,这意味着一个 Git 仓库可以被完整地复制到多台计算机上,每个副本都是完整的仓库,没有主次之分。最开始时,可能只有一台电脑拥有原始仓库,其他人通过 git clone
命令把这个仓库完整复制到自己的电脑上。每台电脑上的仓库都拥有完整的历史记录和版本信息。虽然你只有一台电脑,也可以在不同目录下克隆多个仓库,但实际意义不大——如果硬盘坏了,所有本地仓库都会一起丢失,这也是为什么我们需要远程仓库
的原因。为了更好地进行团队协作,通常会有一台 24 小时在线的服务器,作为远程仓库的中心。每个人从这个服务器克隆仓库到本地进行开发。开发完成后,把修改
推送(push)
到服务器。同时也可以从服务器 拉取(pull)
他人的更新。你可以自己搭建一个 GitLab 私有仓库,但更方便的方式是使用 GitHub —— 全球最大的 Git 仓库托管平台。公有仓库GitHab
GitHub 提供了免费的 Git 仓库托管服务,只需要注册一个账号,就可以拥有自己的远程仓库。GitHub 是最大的 Git 版本库托管商,是成千上万的开发者和项目能够合作进行的中心。 大部分 Git 版本库都托管在 GitHub,很多开源项目使用 GitHub 实现 Git 托管、问题追踪、代码审查以及其它事情。 所以,尽管这不是 Git 开源项目的直接部分,但如果想要专业地使用 Git,你将不可避免地与 GitHub 打交道。
最后友情提示,在GitHub上免费托管的Git仓库,任何人都可以看到喔(但只有你自己才能改)。所以,不要把敏感信息放进去。如果你不想让别人看到Git库,有两个办法,一个是交点保护费,让GitHub把公开的仓库变成私有的,这样别人就看不见了(不可读更不可写)。另一个办法是自己动手,搭一个Git服务器,因为是你自己的Git服务器,所以别人也是看不见的。
注册登录
登入 GitHub 的官网,点击 sign up(注册)

填入相关的注册 GitHub 账号信息

上面的信息都填写完成后,点击Create an account,进入如下界面:

GitHub 的仓库分为两种,一种是public repositories公开免费版,一种是private repositories私有付费版。其中,私有仓库一般是由企业或者不希望自己的仓库公开的个人用户购买,这也是 GitHub 的主要收入来源。在这里,我们选择免费版就可以,然后点击Continue,进入如下界面:

下面这个步骤的主要作用就是收集用户的个人信息,如果感兴趣的话,可以对上面的“ 问答表 ”进行勾选,然后点击Submit提交;如果不感兴趣的话,则可以直接点击skip this step跳过这一步。无论点击两者之中的那个按钮,都将进入如下界面:

个人信息
点击Edit profile,可以编辑个人简历

Overview
:展示了我们账号的主要内容,包括仓库和贡献等;
Repositories
:简称Repo,可以理解为仓库,我们的项目就存放在仓库之中。也就是说,如果我们想要建立项目,就得先建立仓库;有多个项目,就建立多个仓库。
Star
:收藏了我们的点星,或者说是点赞过的项目。当我们感觉某一个项目做的比较好之后,就可以为这个项目点赞,而且我们点赞过的项目,都会保存到我们的Star之中,方便我们随时查看。在 GitHub 之中,如果一个项目的点星数能够超百,那么说明这个项目已经很不错了。
个人贡献记录
:表示的为我们最近一年来的contribution,用实心的小方格标记,小方格的颜色越深,表示我们的contribution越多。Issues
:可以理解为"问题",举一个简单的例子,如果我们开源一个项目,如果别人看了我们的项目,并且发现了bug,或者感觉那个地方有待改进,他就可以给我们提出Issue,等我们把Issues解决之后,就可以把这些Issues关闭;反之,我们也可以给他人提出Issue。
Fork
:可以理解为“拉分支”,如果我们对某一个项目比较感兴趣,并且想在此基础之上开发新的功能,这时我们就可以Fork这个项目,这表示复制一个完成相同的项目到我们的 GitHub 账号之中,而且独立于原项目。之后,我们就可以在自己复制的项目中进行开发了。
Pull Request
:可以理解为“提交请求”,此功能是建立在Fork之上的,如果我们Fork了一个项目,对其进行了修改,而且感觉修改的还不错,我们就可以对原项目的拥有者提出一个Pull请求,等其对我们的请求审核,并且通过审核之后,就可以把我们修改过的内容合并到原项目之中,这时我们就成了该项目的贡献者。
Merge
:可以理解为“合并”,如果别人Fork了我们的项目,对其进行了修改,并且提出了Pull请求,这时我们就可以对这个Pull请求进行审核。如果这个Pull请求的内容满足我们的要求,并且跟我们原有的项目没有冲突的话,就可以将其合并到我们的项目之中。当然,是否进行合并,由我们决定。
Watch
:可以理解为“观察”,如果我们Watch了一个项目,之后,如果这个项目有了任何更新,我们都会在第一时候收到该项目的更新通知。
Gist
:如果我们没有项目可以开源或者只是单纯的想分享一些代码片段的话,我们就可以选择Gist。不过说心里话,如果不翻墙的话,Gist并不好用。创建 GitHub 仓库
进入 GitHub 主页,如下界面点击 new 按钮

对创建的项目工程内容进行选择性的填写

到此仓库创建成功啦,仓库名为test,包含 1 个commit,也就是我们通过勾选
Initialize this repository with a README
,创建了一个初始化提交文件README.md,其中文件后缀为.md
,表示文件为 Markdown 格式;包含 1 个branch,为master分支,即主分支;包含 1 个contributor,为贡献者,也就是我们自己。
SSH 完成 Git 与 GitHub 的绑定
Git 本地库与远程库的传输协议包括:
HTTP / HTTPS
:常用,配置简单,但每次操作可能需要输入用户名和密码。
SSH
:最常用、最安全的一种方式,使用加密密钥认证。
Git 协议
:速度最快,但不加密,通常只用于只读访问,安全性较差。GitHub 使用 SSH Key 的原因是为了安全认证,当你向 GitHub 推送代码时,GitHub 需要确认这个操作确实是你本人发起的,而不是别人冒充你来修改代码。Git 本身支持 SSH 协议,而 SSH 使用的是密钥对认证机制:私钥保存在你电脑上由你自己保管,公钥上传到 GitHub 让 GitHub 用来验证你的身份。只要你的电脑拥有对应的私钥,GitHub 就可以确认这个操作来自你本人。
GitHub 允许你添加多个 SSH 公钥。所以如果你有多台设备,比如家里电脑、公司电脑、笔记本等,只要把每台电脑的公钥都添加到GitHub,就可以在每台电脑上往GitHub推送了。可以按照以下流程操作:
第1步:创建SSH Key。在用户主目录下,看看有没有
.ssh
目录,如果有,再看看这个目录下有没有id_rsa
和id_rsa.pub
这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下使用管理员身份运行Git Bash),创建SSH Key:然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。如果一切顺利的话,可以在用户主目录里找到
.ssh
目录,里面有id_rsa
和id_rsa.pub
两个文件,这两个就是SSH Key的秘钥对,id_rsa
是私钥,不能泄露出去,id_rsa.pub
是公钥,可以放心地告诉任何人。第2步:登陆GitHub,进入我们的 GitHub 主页,先点击右上角所示的倒三角▽图标或者点击我们的头像,然后再点击Settins,进行设置页面再点击SSH and GPG Keys进入此子界面,然后点击New SSH key按钮,填上任意Title(Titles的内容不填写也没事),在Key文本框里粘贴
id_rsa.pub
文件的内容,然后点击Add SSH key 即可。
添加完SSH key之后,可以通过在 Git Bash 中输入
ssh -T git@github.com
进行测试:私有仓库 GitLab
GitLab 是一个基于 Git 的开源版本控制平台,使用 Ruby on Rails 开发,支持用户自建服务器,用于管理代码仓库、协作开发项目。你可以把它理解为一个自托管的 GitHub。GitLab 提供了完整的 Web 界面,用户可以通过浏览器访问公开或私有项目,并进行多种操作,比如提交代码、管理团队权限、讨论问题等。
Gitlab服务构成
Gitlab有好多个东西一起构成的,我们可以使用
gitlab-ctl status
命令来查看各服务的状态,分别是:
Nginx
:Web应用服务器,用于处理通过HTTP或者HTTPS的用户界面操作
PostgreSQL
: 持久化数据存放
Redis
:缓存信息存放
Gitlab Shell
:处理通过SSH方式的操作要求,一般为Git命令等操作
GitLab Workhorse
:轻量级的反向代理服务器,它会处理一些大的HTTP请求,比如文件上传、文件下载、Git push/pull和Git包下载。其它请求会反向代理到GitLab Rails应用,即反向代理给后端的unicorn。
Unicorn
:GitLab是ROR的应用,符合Rack标准的应用所使用的HTTP应用服务器,GitLab Rails应用所托管的应用服务器
Sidekiq
:用于执行异步的后台队列任务的功能组件
logrotate
:日志文件管理工具主要配置文件目录
主配置文件: /etc/gitlab/gitlab.rb
文档根目录: /opt/gitlab
默认存储库位置: /var/opt/gitlab/git-data/repositories
Nginx配置文件: /var/opt/gitlab/nginx/conf/gitlab-http.conf
Postgresql数据目录: /var/opt/gitlab/postgresql/data

常用命令
gitlab-ctl start/stop/restart
:启动/停止/重启所有 gitlab 组件
gitlab-ctl start/stop redis/postgresql/gitlab-workhorse/logrotate/nginx/sidekiq/unicorn
:启动/停止指定模块组件
gitlab-ctl reconfigure
:生成配置并启动服务
gitlab-ctl status
:查看服务状态
gitlab-ctl tail
:实时查看所有日志
gitlab-ctl tail redis/postgresql/gitlab-workhorse/logrotate/nginx/sidekiq/unicorn
:实时查看某个组件日志部署gitlab
gitlab官方rpm包下载地址:https://packages.gitlab.com/gitlab/gitlab-ce
国内清华源下载地址:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum
关闭防火墙
安装相关依赖
postfix支持gitlab发信功能,设置postfix开机自启,并启动
下载gitlab安装包
安装gitlab
修改gitlab配置
重载配置及启动gitlab,修改完配置文件要执行此操作,使配置文件生效
在安装gitlab的时候,如果卡在
ruby_block[wait for redis service socket] action run
,然后等了很久也没有看到这个控制台输出的日志信息发生变化。在另外开启一个终端启动如下命令验证 gitlab 启动完成
启动成功后,登录页面需要输入账号密码,默认的账号是root,查看密码的方式如下

卸载
1、停止 gitlab
2、卸载 gitlab,注意这里写的是 gitlab-ce
3、查看 gitlab 进程

4、杀掉第一个进程,就是带有好多…………. 的进程
杀掉后,在执行
ps aux | grep gitlab
确认一遍,还有没有 gitlab 的进程5、删除所有包含 gitlab 文件
docker部署gitlab
下载镜像
创建数据目录
启动gitlab
修改
/data/gitlab/config/gitlab.rb
文件关于邮箱发邮件的配置如下
重启docker
进入docker容器里,修改端口号,将端口修改为映射后的端口,我们这里映射的是80,不需要修改
修改好端口后,直接在docker中重启gitlab
在浏览器打开
ip:端口
即可访问
关闭账号注册
默认情况下可以直接注册账号,一般都关闭此功能

取消勾选,取消账户注册功能之后点save

登录页面,验证是否还有注册选项

邮件通知
开启QQ邮箱的SMTP服务,这里使用的是qq邮箱,依次点击 设置-->账户-->smtp-->密保验证-->验证成功后返回授权码。保存好授权码

配置邮件服务
修改好配置文件后,要使用 gitlab-ctl reconfigure 命令重载一下配置文件,否则不生效
进入控制台,然后发送邮件进行测试
然后打开邮箱,就可以看到刚刚收到的测试邮件

设置页面中文

创建账户
方法一:通过管理员用户进行账号创建

第一次使用新账号登录,可以通过邮箱修改密码

通过邮件设置密码登录

方法二:在首页进行用户注册

注册完成以后,无法登录,需要管理员批准注册。使用管理员账号登录,批准注册

然后再使用注册的账号进行登录即可登录成功

输入要修改的密码,然后点击保存

创建组
使用管理员 root 创建组,一个组里面可以有多个项目分支,可以将开发添加到组里面进行设置权限,不同的组就是公司不同的开发项目或者服务模块,不同的组添加不同的开发即可实现对开发设置权限的管理。

填写新建项目组信息,设置组名,描述简要描述组的用途等,访问级别根据实际情况填写,比如公司内部可以设置为私有,如果开源的可以设置为public等。Gitlab中的组和项目有三种访问权限:Private、Internal、Public
Private:只有组成员才能看到
Internal:只要登录的用户就能看到
Public:所有人都能看到

添加组成员
为组增加维护者角色的用户,选择用户,然后设置角色,点击添加即可
Gitlab用户在组中有五种权限:Guest、Reporter、Developer、Master、Owner
Guest:可以创建issue、发表评论,不能读写版本库
Reporter:可以克隆代码,不能提交,QA、PM可以赋予这个权限
Developer:可以克隆代码、开发、提交、push,RD可以赋予这个权限
Master:可以创建项目、添加tag、保护分支、添加项目成员、编辑项目,核心RD负责人可以赋予这个权限
Owner:可以设置项目访问权限 - Visibility Level、删除项目、迁移项目、管理组成员,开发组leader可以赋予这个权限
在项目中添加成员


配置GitLab中的SSH key
由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置:
第1步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步。如果没有,打开Shell(Windows下打开Git Bash),创建SSH Key:
然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
查看公钥并复制
登录gitlab,最右边下拉,点击“Settings”去User Setting页面,点击左边的SSH Keys去添加

将本地文件推送到Gitlab
制定开发计划
创建开发计划项目:app01版本:v1.0

先在admin中创建一个pm账号,用pm账号登录gitlab后,根据开发计划来创建里程碑




根据开发计划创建issue,创建4个issue,分派给dev1和dev2这两个开发人员






开发者登录账号查看分派的任务。然后开发dev1登录gitlab,就能看到任务已经分配过来了

公司里的开发开始任务
合并分支
开发dev1发送合并分支请求给pm



pm收到开发的Merge请求后进行处理。使用pm登录,就可以看到pm已经收到了合并请求merge request




开发dev1确认任务完成。退出pm账户,登入dev1账户:

或者点进去后,在侧边栏进行标识Done,然后已经完成的issue,可以将其Close

这个时候Milestones的进度已经往前进了一些了:

项目上线。当所有工作完成之后,就可以进行上线了

上线先打个标签



然后删除已经合并到主干中的不必要的分支,如index、pay等。最后一定要注意时间一定要同步,不然会错乱
备份与恢复
可以通过修改/etc/gitlab/gitlab.rb配置文件来修改默认存放备份文件的目录
备份格式:EPOCH_YYYY_MM_DD_GitLab_version_gitlab_backup.tar
如备份文件:1542603058_2018_11_19_11.4-ce_gitlab_backup.tar
手动使用命令备份gitlab
查看下备份文件(文件权限是设定好的644)
加入到crontab中
恢复
GItlab只能还原到与备份文件相同的gitlab版本。假设在上面gitlab备份之前创建了test项目,然后不小心误删了test项目,现在就进行gitlab恢复操作:
1、停止相关数据连接服务
2、通过之前的备份文件进行恢复
最后再次启动Gitlab
查看gitlab状态
检查恢复情况
再次登录Gitlab,就会发现之前误删除的test项目已经恢复了!
Gitlab调优
gitlab对内存资源的消耗比较厉害,其中尤以 sidekiq队列 及 unicorn服务 两个组件对内存消耗最多,可以再容器启动时对相关参数进行微调:
配置调整后需要重载一下
远程仓库命令
从远程仓库克隆到本地
当我们本地还没有 Git 仓库时,可以通过
git clone
命令直接将远程仓库复制到本地。这样创建的本地仓库本身就是一个完整的 Git 仓库,无需再手动执行 git init
进行初始化操作。此外,git clone
会自动与远程仓库建立关联(通常命名为 origin),后续你在这个仓库内进行的修改、添加、提交等操作就可以像平时使用本地仓库那样进行。首先,打开你想要克隆的远程仓库(比如 GitHub、Gitee、GitLab 等)。在仓库页面中,找到一个名为 Code 的按钮,点击它后会弹出一个下拉框。在这个下拉框中,你会看到一段网址,一般是以
https://
或者 git@
开头的地址,这就是我们稍后用来克隆仓库的远程地址。点击旁边的复制按钮,将这个地址复制下来,接下来执行 git clone
命令时就会用到它。
新建仓库目录,建立一个要克隆的文件夹
执行
git clone
命令,将远程仓库下载到本地添加远程仓库
如果你已经有一个本地的 Git 仓库,并且已经关联了一个远程仓库(通常名为 origin),但此时你想再添加一个新的远程仓库地址,比如做镜像备份或同步到多个平台,可以使用以下命令完成操作:
举个例子,比如你想添加一个名为 backup 的远程仓库地址:
添加完成后,你可以运行以下命令查看已有的远程仓库地址,确认新的远程仓库已经添加成功:
这样你在推送代码时,可以根据需要选择远程仓库,例如:
修改远程仓库地址
向远程仓库提交代码
在我们向远程仓库提交代码的时候,一定要先进行pull操作,再进行push操作,防止本地仓库与远程仓库不同步导致冲突的问题,尤其是第二种提交代码的情况,很容易就出现问题。比如A对远程仓库做了修改,B不会知道远程仓库已经被A进行了修改,所以B推送的时候将会发生冲突,所以先使用git pull命令再使用git push。当然也可以建立远程跟踪分支,这样就可以得到相关变化信息
git pull 将远程分支下载到本地,并于本地分支进行合并,默认是master分支
git fetch 将远程分支数据下载到本地,不进行合并
git push 远程仓库名 all 代表将本地所有分支提交
git push 远程仓库名 分支名 把该分支上的所有本地提交推送到远程库
- 链接:www.qianshuai.cn/article/git
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。