一、什么是 Git
在日常开发中,多人共同开发程序可能导致文件版本混乱、修改冲突或误删文件。Git 的出现解决了这些问题,通过管理文件版本,我们可以轻松回退版本,进行多人同时开发并降低代码冲突,更好地对大型项目进行梳理。
二、Git 的安装与配置
在 Linux 下安装 git 通常只需一行命令。
CentOS:
yum install git -y
Ubuntu:
本文介绍了 Git 版本控制系统的核心原理与常用操作。涵盖安装配置、工作区暂存区版本库概念、基本增删改查、分支管理策略、远程仓库协作及企业级开发模型。通过实例演示了版本回退、冲突解决、标签管理及多人协作流程,帮助开发者高效管理代码历史与团队协作。

一、什么是 Git
在日常开发中,多人共同开发程序可能导致文件版本混乱、修改冲突或误删文件。Git 的出现解决了这些问题,通过管理文件版本,我们可以轻松回退版本,进行多人同时开发并降低代码冲突,更好地对大型项目进行梳理。
二、Git 的安装与配置
在 Linux 下安装 git 通常只需一行命令。
CentOS:
yum install git -y
Ubuntu:
apt-get install git -y
三、Git 的原理
首先创建一个 Git 本地仓库,使用 git init 命令。

使用 ll -a 指令可以查看当前目录下存在一个 .git 的隐藏文件,该文件不要随意破坏,以免影响正常使用。

可以用 tree .git/ 命令查看 Git 仓库的一些细节。

完成仓库创建后,需要对 Git 仓库进行配置,设置用户名和邮箱。global 参数将该用户名和邮箱设置为全局,意味着后续创建的 Git 仓库默认都是该名字和邮箱。若你有多个 Git 仓库且希望不同用户名和邮箱,则不需要加 global。

配置完成后,可以通过 git config -l 命令来查看当前仓库配置。

若希望删除这些配置,可以用 git config [--global] --unset user.name 或者 user.email 命令删除配置。
通常编写、修改、删除代码都在工作区当中;将改好的文件放入到暂存区当中,暂存区存放准备提交到版本库中的文件;确认文件无误后,将文件从暂存区传到版本库当中,此时就形成了一个新的版本,也可以在版本库当中追溯到先前的任意一个版本。
创建版本库时,Git 会为我们创建一个 Master 主分支,用一个 HEAD 指针指向这个主分支。当对工作区修改文件进行 git add 操作时,暂存区目录树索引更新;当 git commit 时,master 分支会进行更新,将暂存区的目录树写入 master 主分支中。
四、Git 的使用
首先在 .git 目录下创建一个 README 文件,接着使用 git add 文件名 的方式,将文件添加进入暂存区,接着用 git commit -m "备注",将该文件进行解释备注后存入到 master 分支当中。

到目前为止,已经完成了将自己写的代码上传到了仓库当中。可以使用 git log --pretty=oneline 的命令查看历史提交记录。

此时查看到了历史记录,其中这一串数字就是 commit 时产生的 id 版本号。若后续版本不断迭代,但今天突然需要这一版的代码,可以拿着这串版本号回退找到之前的代码。
Git 对于文件是对于文件的修改进行管理而不是对文件进行管理。现在对 README 文件进行修改往里面添加内容。紧接着通过 git status 来查看。

上面的意思是,完成了修改但是还没有进行 add 和 commit 操作进行同步。只需要再进行 add 和 commit 操作就可以同步了。
若想得知与先前版本哪些地方被修改了,可以用 git diff 文件 的方式查看。它会区分暂存区和工作区之间的差异,之后再进行对版本库提交就更加安全了。

Git 能够管理文件的历史版本,当发现之前工作出现了很大的问题,需要从某个特定的版本开始,这个时候就可以使用版本回退功能。
用 git reset 命令可以进行版本回退,回退的本质是将版本库中的内容进行回退,工作区和暂存区的内容是否回退由命令参数决定:
git reset [--soft | --mixed | --hard] [HEAD]
--mixed为默认选项,使用时可以不带参数。该参数将暂存区的内容退回为指定提交版本内容,工作区文件保持不变。--soft对于工作区和暂存区的内容不变,将版本库回退到某个指定版本。--hard将暂存区和工作区退回到指定版本。若工作区当中有未提交的代码不要使用这个命令,容易造成代码丢失。HEAD 版本: 可以直接写成 commit id 表示指定退回的版本。 HEAD 表示当前版本,HEAD^ 表示上一个版本,HEAD^^ 表示回退两个版本。 HEAD
0 表示当前版本,HEAD1 表示上一个版本,HEAD~2 表示上两个版本。
下面对 README 进行三次版本修改。

若当前想从版本 3 回退到版本 1 中,该如何操作呢?
用 git reset --hard 版本号 的方式回退到了版本 1 中。

若不清楚该文件的版本号,或者版本号找不到了,可以通过 git reflog 的方式来查找先前的本地命令。

其中 00f4980,就是 commit id 的一部分,也可以通过该 id 来找回目标版本。
Git 的版本回退速度非常快,在 Git 内部存在一个 master 分支中的 HEAD 指针,refs/heads/master 文件里保存当前 master 分支的最新 commit id。当回退版本的时候,Git 仅仅是给 refs/heads/master 中存储一个特定的 version。

各个版本就像一串珠子一样,通过 HEAD 指针指向来指向不同的 version 版本。
当在工作区当中想撤回到上一个版本的代码,该如何操作呢?
git checkout -- 文件 的方式回退到最近一次 add 或 commit 时的状态。切记 -- 后面需要添加空格!!!!
对于已经 add 但没有 commit 的,可以用 git reset --mixed HEAD README 进行拉回。
对于已经 add 并且也 commit 了的代码,可以用 git reset --hard HEAD^ 的方式回退到上一个版本,不过这个代码还不能推送到远程端,若推送到远程端那就麻烦了。
删除文件时,除了在自己的工作区当中删除,还需要在版本库中进行删除。
删除文件时,无非是两种情况,第一种情况是删错了,第二种情况是确实需要删除文件。分别讨论如下:
发现删除错文件后,可以用 git checkout -- 文件 的方式,回退到最近一次 add 操作的文件。
对于第二种情况,首先用 git rm 文件 将文件从暂存区和工作区当中删除,接着用 git commit -m "备注" 的方式对版本库进行同步。

这样文件就从版本库当中删除了。
一个 Git 仓库中至少存在一个分支也就是主分支 master,它就像一条时间线,随着不断的提交代码,时间线慢慢往前推移,而 HEAD 指针指向 master 分支,可以操控 HEAD 指针回退到先前的时间结点,也就是穿越回之前的时空。而分支呢就相当于又开辟了另一个时空,它与主分支不相干,但当在一定的结点时,可以进行主分支和分支之间进行合并,也就是两个时空在某一时刻同步了。此时,主分支同时拥有了两个分支的内容。

首先使用 git branch 查看当前本地所有分支,接着用 git branch 分支名 创建新的分支。

当前已经完成了 dev 分支的创建,此时的 dev 分支和 master 分支指向同一个结点。
使用 git checkout 分支名 来进行切换分支,再用 git branch 来查看分支切换。

其中分支名后面的 * 表示当前所在分支。
当在 dev 分支修改了内容,并且进行 add 和 commit 操作,回到 master 主分支的时候却看不见修改的内容。

为什么会出现这样的现象呢?

原因是 master 指向了前面的结点,而 dev 指向的是后面的结点,它们并没有同步在一块。
为了能在 master 分支上看见 dev 修改的东西,需要在 master 上进行分支合并。
首先切换到 master 分支上,接着输入指令 git merge 分支名 就可以完成分支合并了。

完成合并分支后,dev 分支对于我们来说没有用处了,那么就可以删除该分支。删除某个分支时不能在要删除的分支下删除,需要切换到其他分支。用 git branch -d 分支名 的方式就可以完成分支删除。

通常将任务编写用多个分支来进行,最后在合并到主分支中。
首先在 master 分支上的 TEST 文件修改内容进行提交,此时转换到 dev 分支上修改内容并且提交,此时再回到 master 分支上修改内容进行提交,完成后,在对分支进行合并,此时就会发生合并冲突,编译器会显示告诉我们有些不同的地方,此时需要手动进行修改,然后再提交,此时就解决了冲突。
先在 master 上修改文件。

再切换到 dev 上修改文件,进行提交。

完成修改后,切换回 master 主分支上,再次修改文件内容,然后将 dev 分支进行合并,此时就会出现合并冲突。

cat 一下文件,此时 <<<<<<< 到 ======= 直接就是存在冲突的部分,需要手动进行修改后再次提交就完成了冲突解决。

画图来解释这个过程。

两边都进行了修改,导致两个分支不同步。

解决代码不重合的问题后,再次提交,此时两个分支就完成了合并,冲突解决。
先前进行的分支合并都是 Fast forward 模式下的,这样合并之后会将两个分支的最新结点合并成一个结点,也就是说在 dev 分支上不会备份一份出来,这就很容易导致版本丢失。通常不建议使用 Fast forward 模式进行合并,推荐使用 git merge --no-ff -m "备注" 分支名 的形式进行分支合并。--no-ff 表示禁用快速模式,并且创建一个新的 commit,用图来解释。

当在分支上进行代码书写的时候,此时发现主分支上有一个地方出现了 bug,可以重新创建一个新的分支,然后在新的分支上修改主分支上的代码,完成工作后,再与主分支进行合并。此时当前分支正在进行代码开发,需要将当前分支储藏起来。
使用 git stash 命令储藏工作区信息,将来可以在某个时间点重新拿回信息。
接着切换回 master 主分支上,创建一个新的分支 dev2,进行临时修复 bug,完成修复后,返回到 master 主分支进行合并,删除 dev2 分支即可。
此时回到先前分支的工作区,使用 git stash list 命令查看先前储藏的内容。再使用 git stash pop 命令进行现场恢复。
此时,在 master 分支上已经完成了 bug 的修复,但是在当前的分支上还是使用的原先的代码,如果此时在主分支上再进行合并,容易导致出错,应该在当前分支,拉取主分支内容进行合并。在完成当前分支代码后,再切换回主分支进行分支合并。

若分支在进行开发的过程中,产品经理突然说不需要当前功能了,那么需要对该分支进行删除,但是该分支不能合并到 master 分支上,所以不能用 git branch -d 分支 的方式删除。首先切换回主分支,用 git branch -D 分支名 的方式表示强制删除该分支。
先前的所有操作都是在本地计算机中进行的,而 Git 是分布式版本控制系统。分布式管理系统中存在一个'中央服务器',若其中任意一个人损失了文件都可以通过'中央服务器'来找回内容。
远程仓库是多人团队开发的基础设施,用于进行代码管理,版本追溯等。下面用 Gitee 来创建远程仓库。
首先找到下载 Gitee,进行注册,找到新建仓库按钮。

点击新建仓库按钮,输入你的仓库名称。

完成仓库创建后,点击初始化文档。

点击管理,可以对仓库进行设置。

点开代码,上面有一个分支按钮,上面默认只有一个 master 分支。

将远端仓库进行克隆下载,然后到本地仓库进行 git clone。

此时存在着两种协议,一种是 SSH 协议,SSH 协议使用了公钥加密和公钥登陆机制,安全性较高。另一种是 HTTPS 方式,没有要求可以直接克隆下来。这里直接使用 HTTPS 的形式,将网址复制下来后,git clone 克隆。
首先,确保之前设置的全局 name 和 email 和 Gitee 上配置的一致。先创建文件,add 和 commit 后,再使用 git push 命令,此时就将本地仓库内容推送到远程仓库里了。
git push 会默认传递当前分支与远程仓库存在追踪关系的分支;如果没有设置追逐关系,那么就会传递给同名的分支。

如果说,要将本地分支上传到远程分支,可以用 git push 远程主机名 本地分支名:远程分支名 的方式传递。
若在远程仓库当中修改了文件,但是在本地没有修改文件,此时需要进行远程和本地同步操作。
使用指令 git pull 命令拉取远程仓库到本地仓库中。

在进行仓库创建的时候,存在着一个 .gitignore 文件,该文件用于屏蔽某些特定的文件,让他们不参与版本控制,可以保证我们的仓库不冗余,仓库更加简洁。

如果想上传被 .gitignore 文件屏蔽的类型,可以使用 git add -f 文件 进行强制上传。
有时候,git 命令特别的长,可以对命令进行别名方便操作。例如现在想将 git status 简化为 git st。

其中添加了 global 意味着所有的仓库对于该别名都生效。
标签 tag,简单理解就是给 commit 一个标识,相当于起一个别名。例如针对某个版本可以起一个 v1.0 的标签,标签的用处就是用来替代 commit id 的,相较于 id,标签可读性更强更高。
首先需要切换到打标签的分支上,使用命令 git tag 标签名 的方式打一个新标签。使用 git tag 可以查看所有标签。在默认情况下,打的标签会打在最新 commit 上的文件当中。若希望对指定文件打标签,可以用 git tag 标签 文件 id 的方式对特定文件进行标签。

使用 git show 标签名 的方式可以查看标签文件信息。

若希望删除标签,可以使用 git tag -d 标签名 的方式删除。

标签默认是存在本地的,若希望上传到远程仓库中,需要将标签进行 push 操作。

上传到远程仓库中的标签若希望删除标签,那么需要先在本地删除,然后再进行 push 操作进行远程同步即可。
依据远程仓库为主服务器,向每个开发成员分配相同的一份代码,用户通过 clone 来将远端服务器拷贝到每个用户当中。完成多人开发。
点开远程仓库的管理,找到仓库管理员开发者。

可以进行用户邀请,这里有三种邀请方式。

接着在远端创建分支,在通常情况下,是不能在 master 主分支上进行开发的,因为容易导致主分支的混乱,通常都是在分支上进行开发,开发完成后再进行合并。
在远端创建完成分支,在本地仓库进行 pull 拉取就能同步远端仓库了。
通常情况下,开发一个程序时,每个人会负责一个分支,会在分支上进行开发,开发完成后再合并到主分支当中。当有一天,同事生病没有来上班,那么只需要切换到同事所开发的分支上,进行开发,后续只需要在同事电脑进行本地拉取,就能完成同步操作。
五、企业级开发模型
在一个大型企业项目开发部署往往是进行精细划分的。
软件开发工程师负责代码规划写代码等工作,测试工程师测试代码,运维工程师需要部署维护代码发布上线等。那么就需要各个板块进行合作协商,那么 Git 的重要性就体现出来了。
对于开发人员来说,需要了解几个常用的开发环境。
开发环境是专门用于日常开发的服务器,一般会打开所有的错误报告和测试工具,是最基础的环境;测试环境是开发环境到生产环境的过渡环境,需要对其进行测试;在测试环境后,要进行预发布环境部署,这是为了避免线上和线下的差异;最后就是生产环境进行部署。
有了环境概念后,对于开发人员来说,一般会针对不同的环境来设计分支。

master 分支
master 分支为只读且唯一分支,会将 release 分支实现代码后进行合并到 master 分支中。master 分支不可删除,可以对 master 的一些重要结点进行标签记录。
release 分支
release 分支是预发布分支,基于本次线上所有的 feature 分支合并到 develop 分支之后,基于 develop 分支创建。该分支主要提供给测试人员,用于进行测试。
develop 分支
基于 master 分支创建的只读且唯一分支,始终保持最新完成以及 bug 修复后的代码,通常都是由 feature 分支对其进行合并。
feature 分支
开发人员用于对新特性新功能进行开发。
hotfix 分支
用于修复分支或进行分支补丁,主要用于线上版本进行 bug 修复。
总结:
Git 作为主流的分布式版本控制系统,能高效追踪代码全量历史变更,支持多人并行开发。本地仓库完整可离线操作,结合远程仓库实现协作同步,分支管理灵活,可快速回溯版本,是团队开发与个人项目管理的必备工具,深刻改变了代码管理模式。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online