Git 的正确使用姿势与最佳实践 | 豆包MarsCode AI刷题

72 阅读12分钟

一.git的介绍

git是世界上最先进的分布式版本控制系统(没有之一);

Git 简介

Git 是一个分布式版本控制系统(DVCS),用于跟踪文件的变化,通常用于软件开发中的源代码管理。它允许开发者协同工作,记录代码的每一次变更,并支持回滚到任意历史版本。Git 的设计目标是速度、数据完整性和对非线性开发流程的支持。

主要特点
  1. 分布式:每个开发者的工作副本都是一个完整的代码库,包含项目的完整历史记录。这意味着即使中央服务器发生故障,开发者也可以继续工作。

  2. 分支与合并:Git 允许开发者轻松创建和管理分支,使得并行开发变得简单。合并分支也很方便,有助于管理不同的开发路线。

  3. 轻量级:Git 在创建分支和标签时非常快速,几乎不产生额外的开销。

  4. 数据完整性:使用 SHA-1 校验和确保数据的完整性,避免文件的损坏或篡改。

  5. 非线性开发:支持复杂的开发流程,包括多个并行分支,适合敏捷开发和持续集成。

基本概念
  • 仓库(Repository):存储项目的所有文件和历史记录的地方。
  • 工作目录(Working Directory):开发者正在进行工作的本地目录。
  • 暂存区(Staging Area):用于准备提交的文件的临时存储区域。
  • 提交(Commit):记录文件的变更,包含一个唯一的 SHA-1 校验和。
  • 分支(Branch):指向某次提交的指针,可以用来创建不同的开发路线。
  • 合并(Merge):将一个分支的更改应用到另一个分支。
常用命令
  • git init:初始化一个新的 Git 仓库。
  • git clone [url]:从远程仓库克隆一个项目到本地。
  • git add [file]:将文件添加到暂存区。
  • git commit -m "message":提交暂存区的文件到本地仓库。
  • git pull:从远程仓库获取最新的更改并合并到当前分支。
  • git push:将本地仓库的变更推送到远程仓库。
  • git branch:列出所有分支。
  • git checkout [branch-name]:切换到指定分支。
  • git merge [branch-name]:将指定分支的更改合并到当前分支。

1.什么是版本控制系统?

什么是版本控制系统?

以下内容摘自<<Git和GitHub使用教程>>第6页;

比如如果你用Microsoft Word写过长篇大论, 那你一定有这样的经历: 想删除一个段落, 又怕将来想恢复找不回来

怎么办? 有办法, 先把当前文件“另存为……” 一个新的Word文件, 再接着改, 改到一定程度, 再“另存为……” 一个新文件, 这样一直改下去, 最后你的Word文档变成了这样:

image.png

过了一周, 你想找回被删除的文字, 但是已经记不清删除前保存在哪个文件里了, 只好一个一个文件去找, 真麻烦。看着一堆乱七八糟的文件, 想保留最新的一个, 然后把其他的删掉, 又怕哪天会用上, 还不敢删, 真郁闷。 更要命的是, 有些部分需要你的财务同事帮助填写, 于是你把文件Copy到U盘里给她(也可能通过Email发送一份给她) , 然后, 你继续修改Word文件。 一天后, 同事再把Word文件传给你, 此时, 你必须想想, 发给她之后到你收到她的文件期间, 你作了哪些改动, 得把你的改动和她的部分合并, 真困难。 于是你想, 如果有一个软件, 不但能自动帮我记录每次文件的改动, 还可以让同事协作编辑, 这样就不用自己管理一堆类似的文件了, 也不需要把文件传来传去。 如果想查看某次改动, 只需要在软件里瞄一眼就可以, 岂不是很方便? 这个软件用起来就应该像这个样子, 能记录每次文件的改动:

image.png

这样,你就结束了手动管理多个"版本"的史前时代,进入到版本控制的20世纪.

2.git的诞生

git是Linux的创始人 Linus Torvalds 写的;这里有一个传说,先用别人免费的去管理自己的内核版本,后来别人不给他用了,自己写了一个;两周时间就自己写出来了git;

这个故事详见<<Git和GitHub使用教程>>第8页

3.集中式VS分布式

集中式的svn:历史版本在服务器上,本地没有;如果没有连上服务器,就无法提交;如果服务器坏掉了,那么历史版本就没有了; 有时候我们是需要历史版本的,比如我们的客户A,B需要的功能都是类似的,所以你开发完A的,可能会需要A的历史版本拉下来(拉到本地)再修改一下就变成客户B的需求;

git:分布式 本地保留历史版本(虽然本地看到的是最新版); 每一台电脑都会把历史版本存一份;如果服务器坏掉了,那么历史版本还有; 分布式与 集中式的区别如下图:

集中式:

image.png

分布式:

image.png

先说集中式版本控制系统, 版本库是集中存放在中央服务器的, 而干活的时候, 用的都是自己的电脑, 所以要先从中央服务器取得最新的版本, 然后开始干活, 干完活了, 再把自己的活推送给中央服务器。 中央服务器就好比是一个图书馆, 你要改一本书, 必须先从图书馆借出来, 然后回到家自己改, 改完了, 再放回图书馆。

那分布式版本控制系统与集中式版本控制系统有何不同呢?

首先, 分布式版本控制系统根本没有“中央服务器” ,每个人的电脑上都是一个完整的版本库,

这样, 你工作的时候, 就不需要联网了, 因为版本库就在你自己的电脑上。 既然每个人电脑上都有一个完整的版本库, 那多个人如何协作呢? 比方说你在自己电脑上改了文件A, 你的同事也在他的电脑上改了文件A,

这时, 你们俩之间只需把各自的修改推送给对方, 就可以互相看到对方的修改了。 和集中式版本控制系统相比, 分布式版本控制系统的安全性要高很多,

因为每个人电脑里都有完整的版本库, 某一个人的电脑坏掉了不要紧, 随便从其他人那里复制一个就可以了。 而集中式版本控制系统的中央服务器要是出了问题, 所有人都没法干活了。

详见<<Git和GitHub使用教程>>第9-10页;

4.git与github

很多人分不清GitHub和Git的关系,误认为Git等同于GitHub,其实它俩完全是两码事,不能相提并论。

github 是国外的代码托管,码云gitee是国内的代码托管; 用一句话形容这二者的关系:git是弓,你的代码是箭,github是靶子。 git是软件,它可在本地建立仓库,你写的代码的各个版本都可以存着 github是网上仓库,你写的代码的各个版本都可以存着。

版本控制(Version control):顾名思义,版本控制系统是任何能让你了解到一个文件的历史,以及它的发展过程的系统。 gitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名gitHub。

简单来说,Git只是一个命令行工具,一个分布式版本控制系统。正是它在背后管理和跟踪你的代码历史版本,好比一个时光机,让你在代码出错时不至于手忙脚乱,能快速回退之前的历史版本。 类似的工具还有SVN.

而GitHub是一个代码托管网站,背后使用Git作为版本管理工具(而非svn)。主要服务是将你的项目代码托管到云服务器上,而非存储在自己本地硬盘上。 类似的网站还有gitlab.com,bitbucket.com,coding.com(国内),gitee.com(国内)

二.git的使用

1.git的安装

首先在Ubuntu上测试有没有安装,如下图说明未安装.

安装完成之后可以查看版本,如果提示了版本,那么证明安装成功.
git version
git -v

2.四个工作区

git本地有三个工作域:工作区(working directory), 暂存区(stage/index), 资源库(repository)。如 果再算上远程服务器上的git仓库(remote directory)就可以分为四个工作域。其关系如下:

image.png

Workspace: 工作区,就是平时存放项目代码的地方. Index / Stage: 暂存区,用于存放临时的改动,事实上它只是一个文件,保存即将提交到文件列表信息. Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本 Remote: 远程仓库,托管代码的服务器,可以简单的认为是项目组中的一台电脑用于远程数据交换 .

2.工作流程及四种状态

git工作的一般流程:

1)在工作目录中添加,修改文件

2)将需要进行版本管理的文件放入暂存区

3)将暂存区的文件提交到git仓库

文件的四种状态

Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制.

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

3.git的初始化

我们先建立一个工作区,然后创建一个版本,然后把这个版本加入到本地仓库;
使用git init就把工作区,本地仓库,暂存区就做好了.
如下,我们使用git  init就在本地创建了一个空的git仓库(在.git中);(文件位置为当前位置,也就是git  init执行的时候的当前位置)

4.添加文件到暂存区

git add sfk.c #添加sfk.c文件到暂存区
git add . #添加当前的所有文件

(成功了是没有任何提示的);
我们可以查看状态,可以查看日志报表

image.png

5.git的基本命令


git init #初始化,该命令将其变为一个可以通过git管理的仓库

git add filename #添加文件到暂存区 (重点)

git commit -m "版本描述信息" #提交版本到仓库 (重点)

git status #查看仓库状态

git log #查看提交的历史记录

git reflog #查看对仓库的操作日志

git diff HEAD #比较当前内容与最后一次提交的版本的差异,

比如在main.c中添加了一行内容,显示添加的一行前面有‘+’号标识。

如果内容相同则该命令不显示输出结果。HEAD也可以省略默认就是与最近一次比较。

git checkout filename #放弃对工作区代码的修改。

git reset HEAD filename #从暂存区撤销

git rm filename #删除一个文件, 此时提交到暂存区,需要commit后才在版本库中删除

git reset --hard HEAD^ #回退版本 (重点)

6.git的分支命令

git branch #查看分支

git branch 分支名 #创建分支

git checkout 分支名 #切换分支

git checkout -b 分支名#创建并切换到该分支

git branch -d 分支名 #删除分支,不能删除当前所处分支,切换到其它分支再删除;

git merge 分支名 #合并某个分支到当前分支;合并时可能产生冲突,需要解决冲突。

#有时需要禁止快速合并,可执行:git merge --no-ff -m '描述' 分支名

git log --pretty=oneline #历史记录一行显示;

git log --graph #以图表形式显示分支:

git stash#保护现场,当前工作区有代码修改了,是不能切换到其他分支,可以先保存现场,再切换

git stash list #列出所有保存的现场信息

git stash pop "stash@{1}" # 取出某次的现场信息,继续工作;

默认是最近一次,如果有多个现场,也可以加上编号"stash@{1}"指定获取某一个。

不同分支的现场,应该回到对应分支再获取,否则会自动合并现场到当前分支的工作区。

7.git远程操作命令

#生成通信密钥:

ssh-keygen -t rsa -C "309179229@qq.com" ,生成的公钥在/home/stu/.ssh/下

#测试与github或者gitee(码云)有没有连通:

ssh -T git@github.com #测试与github是否连通

ssh -T git@gitee.com #测试与gitee是否连通;

#克隆项目:

git clone 项目地址

#提交分支到远程仓库:

git push origin 分支名

#提交分支到远程仓库,并跟踪分支: (重点)

git push -u origin 分支名

#拉取远程服务器上的分支更新到本地:

git pull origin 分支名 (重点)