Git从入门到精通
Git 是什么
Git 是一个分布式版本控制系统,主要用于跟踪和管理文件(尤其是代码)的变更。
Git的下载与安装
- 进入git官网下载界面,选择
Windows
系统。
- 点击选择
Git for Windows/x64 Setup
,进行安装。
注意:
Git GUI
是Git提供的一个图形界面工具,Git Bash
是Git提供的一个命令行工具,Git Bash中可以使用linux命令。
Git环境配置
- 安装好
git
后,鼠标右键,打开Git Bash
。
2.设置用户信息(用户名和邮箱)。
输入命令 :
git config --global user.name "用户名"
-----设置用户名git config --global user.email "邮箱"
-----设置邮箱
基本概念
- 仓库(Repository) :存储项目所有文件和版本历史记录的目录。
- 提交(Commit) :
保存一次修改
,包含唯一 ID、作者和描述,将此修改保存在本地仓库,同时提交推送到远程仓库。 - 分支(Branch) :从主线分离的独立开发线,默认分支通常叫
main
或master
,即主线。 - 远程仓库(Remote) :托管在网络上的共享仓库(如 GitHub)。
在项目当中,每个开发人员都有自己的一个本地仓库,用来存储项目的文件和修改记录,同时,项目中还有一个共享仓库(远程仓库),该仓库可以供所有开发者访问,其同样存放着项目的文件和修改记录,如果共享仓库崩溃,各个开发者还有各自的本地仓库,可以继续开发项目,这样不会因为远程仓库崩溃而导致整个项目的数据全部丢失,这就是 分布式 的意义
。
当多人协作开发同一个项目时,大家都各自从远程仓库上将文件或代码 拉取(pull) 到自己的本地仓库中,然后再对文件或代码进行增删改(前提:本地要创建仓库且必须要与远程仓库连接),完成后,将修改内容提交推送(push) 到 远程仓库。
本地仓库
- 本地仓库就是在本台主机上的一个用于存放远程仓库中的项目相关文件的目录。
- 创建本地仓库-----首先创建一个文件夹,在该文件夹中打开Git Bash,输入命令:
git init
,当命令行后面出现master
时,表明仓库创建成功,即该文件夹就是新建的本地仓库。
本地仓库的基本使用
在本地仓库中,对文件进行修改(增加,删除,更新)
会存在几个状态,这些修改的状态会随着我们执行Git命令而发生变化。
如上图所示,本地仓库分为3个部分,分别为工作区,暂存区,仓库
。
- 当我们使用指令创建一个文件(
touch 文件名
)时,该文件此时的状态就是未追踪(untracked
),如果我们直接修改一个现成的文件,则文件的状态就变成未暂存(unstaged
),所有文件的修改都是在工作区进行,这时候这些文件并没有与git产生联系。 - 使用指令
git add 文件名
可以将指定文件的修改从工作区转到暂存区(可以理解为一个缓冲区)。 - 暂存区可以通过使用指令
git commit 文件名
将其内的指定文件的修改提交给本地仓库,此时,就产生了联系,开始由Git来管理该文件,对该文件的修改变成了一条提交记录(换句话说,仓库中每一条提交记录,都对应着一个对应文件的版本)。 - 我们可以通过使用命令
git rm --cached 文件名
将暂存区的文件修改转到工作区,此时文件状态变成了未存储
(unstaged)。 - 使用指令
git commit -m "该条记录的注释"
,将暂存区的内容提交到仓库的当前分支,这时候,文件的修改是以一条记录的形式记录在仓库的日志中,-m
后面加的是对应记录的注释,目的告诉其他人此次修改干了什么。 - 以上,3个部分相互交互,它们交互的内容可以理解为就是指定文件的修改版本。
注意: 整个仓库的所有文件的版本都是以仓库中最新记录为准,我们可以通过日志中记录回滚到指定的仓库文件版本。
主线与分支
在 Git 中,主线(Main Branch) 和分支(Branch) 是代码管理的核心概念,用于组织不同版本的代码和并行开发。一个项目可以有多个分支,但是只能有一个主支。
- 主线:就是整个项目的 "官方"版本 ,是项目的稳定版本,始终保持可用。所有经过测试的、可发布的代码最终会合并到主线。
- 分支:是从主线(或其他分支) 分离出来的 独立开发线,用于在不干扰主线的情况下进行功能开发、Bug 修复或实验性修改。每一个开发者都各自对应着一条分支,互不干扰,独立开发,修改,当开发者完成各自任务,经测试没问题后,就会将分支合并到主线上,算是得到了 “项目官方的认可”。
- 主线与分支极大地方便了多人协作开发同一个项目,而共享仓库(远程仓库) 一般都是在网上(如GitHub,代码托管平台),这表明开发者可以远程开发项目。
注意:同一时刻,只能操作一条分支——即当前分支,仓库里面的文件与当前所在的分支有关,分支切换,仓库中的文件也会跟着切换(主线也是一条分支)。
如上图所示,HEAD->
指向哪条分支,哪条分支就是当前分支(master是主线)。
本地分支合并冲突
当两个分支都对同一个文件的同一行进行修改后,在与主线合并时,就会产生冲突,即主线到底以哪个版本为主?
这时候,我们就需要手动的去解决冲突:
- 处理文件中冲突的地方(打开冲突文件,其中的冲突标识如下,HEAD表示当前分支)。
<<<<<<< HEAD 你的修改 ======= 远程的修改 >>>>>>> 发生冲突的分支名
- 将解决完冲突的文件加入暂存区(
git add .
)。 - 提交到仓库(
git commit .
)。
开发中分支使用原则和流程
在开发中,分支一般有如下使用原则:
master (生产)分支
: 主分支(主线),整个项目工程最终上线使用的分支。develop(开发)分支
:是从master创建的分支,一般作为开发部门的主要分支,用于开发新的功能,阶段开发完成后,需要合并到master分支,准备上线。future/xxx分支
:是从develop创建的分支,因为develop分支作为开发部门的主要分支,我们不可能在上面直接进行开发(部门不止你一人),因此需要再建分支进行开发代码的编写,最后将所有的开发代码全部提交到develop(开发)分支
上。hotfix/xxx分支
:一般作为线上bug修复使用,修复完成后将该分支合并到所有的其他主要分支当中,如master分支,develop分支,test分支。test分支
:一般是用来做测试的分支。
远程仓库
远程仓库即共享仓库,通常我们会借助网上的代码托管平台来创建远程仓库,比如Github
,码云
,GitLab
等,以下以码云为例。
远程仓库的创建
- 登录码云官网,注册码云账号。
- 点击加号,创建远程仓库。
- 设置完仓库的相关信息,点击创建即可。
远程仓库身份认证
当我们要对远程仓库进行操作(拉取和推送代码)时,需要先进行身份认证,一般采用公私钥对的方式来验证身份。
配置SSH公钥
- 在本地仓库生成公钥:在Git Bash中输入命令
ssh-keygen -t rsa
,然后一路回车,如果公钥已存在,则会自动覆盖。 - 查看公钥:输入命令
cat ~/.ssh/id_rsa.pub
。 - 将公钥复制下来,在登录码云官网,点击右上角用户->点击设置->找到
ssh公钥设置
- 验证是否成功:在Git Bash中输入命令
ssh -T git@gitee.com
,回车,输入yes,再回车,出现以下信息表示成功:
通过以上方式,就将本地仓库与gitee平台的对应账号绑定,本地仓库在操作该账号对应的远程仓库时,无需再输入用户名和密码进行身份验证。
添加指定远程仓库
一个账号中可能会有很多的远程仓库,因此我们要告诉本地仓库,它对应的远程仓库具体是哪一个,绝大多数情况下,同一时刻,本地仓库只与一个远程仓库对应。
- 获取到远程仓库的地址。
- 在本地仓库中输入命令
git remote add 远程仓库的名字 远程仓库的地址
,添加远程仓库到本地,其中仓库名字可以随便取,一般命名为origin
。 - 通过 命令
git remote
,查看当前的本地仓库对应的远程仓库的名字(可能不止一个)。
远程仓库克隆
当我们想要获取到指定远程仓库中所有的内容时,我们只需要在本地Git Bash
中输入命令git clone 远程仓库的地址 本地仓库的名字
即可,该指令的作用为在本地创建一个仓库并拉取指定远程仓库中的所有内容到本地。
远程合并冲突
在一段时间,A,B修改了同一个文件,同一行代码,此时会发生合并冲突。
A在本地修改完代码后,优先提交推送到远程仓库,此时B在本地修改代码,然后也需要提交推送到远程仓库,因为B用户是晚于A用户的,因此需要先拉取远程仓库,经合并后才能进行推送,此刻就发生了远程合并冲突。
远程合并冲突的解决方式与本地合并冲突方式一致,在我们拉取并合并(pull
)到远程分支时,发生冲突,这时候,我们找到冲突的文件,进行删改,解决完冲突后,重新提交并推送。
多人协作使用远程仓库流程
在使用 Git 时,如果多人协作开发同一分支,通常需要遵循以下流程:
拉取远程更新 → 合并冲突 → 提交并推送。
如果跳过拉取直接推送修改,可能会导致以下问题:
- 推送被拒绝(最常见)-----如果远程仓库的分支已经有新提交(
其他人推送过代码
),而你的本地分支未同步(未拉取
),直接运行git push
会收到错误。 - 覆盖他人代码(危险!)-----如果强制推送(
git push -f
),会用你的本地提交覆盖远程分支,导致其他人的提交丢失。
注意:此操作非常危险,仅限特殊场景(如修复误提交),团队协作中严禁随意使用!
- 后续合并更复杂-----即使你强制推送成功,其他人在拉取代码时会发现历史冲突,需要手动解决,增加协作成本。
正确步骤:
- 拉取远程最新代码
git pull origin <分支名>
# 等同于 git fetch + git merge
-
git pull
会做两件事:- 从远程仓库下载最新代码(
git fetch
)。 - 自动合并到当前分支(
git merge
)。
- 从远程仓库下载最新代码(
- 解决合并冲突(如果有)
-
如果多人修改了同一文件的同一部分,Git 会提示冲突,需手动编辑文件解决冲突。
-
冲突标记示例:
<<<<<<< HEAD 你的修改 ======= 远程的修改 >>>>>>> commit_id
删除冲突标记,保留正确代码,然后保存文件。
- 提交并推送
git add . # 添加解决冲突后的文件
git commit -m "解决合并冲突"
git push origin <分支名> # 推送更新到远程
Git常用命令
Git 基础指令
git add 文件名
----- 将指定文件的修改由工作区转到暂存区,git add .
,工作区所有修改全部转移。git rm --cached 文件名
----- 将指定文件的修改由暂存区转到工作区,git rm --cached .
,暂存区所有修改全部转移。git status
-----获取到当前仓库工作区和暂存区中的各个文件修改信息。git commit -m "注释内容"
-----将暂存区内容提交到本地仓库的当前分支。git log
-----查看提交日志,--all
查看所有分支,--pretty=oneline
将提交信息显示为一行,--abbrev-commit
使得输出的commitId
(每条记录的唯一ID号) 更简短,--graph
以图的形式显示。git reset --hard commitID(提交记录的唯一ID)
----- 将仓库中所有文件的版本切换为指定记录提交时刻的版本,切换后,原来在该记录之后的所有记录全部被删除,该记录成为最新记录。git reflog
-----查看仓库的所有相关操作记录,从操作记录中,我们可以获取到已经被删除的记录的ID号,从而恢复到已经被删除的版本:git reset --hard 已被删除的ID号
。git branch
----- 查看所有分支。git branch 分支名
----- 创建新分支。git checkout 分支名
----- 切换到指定分支(该分支已存在)。git checkout -b 分支名
----- 创建并切换到指定分支(该分支原先不存在)。git merge 分支名
----- 将指定分支合并到当前分支(一般都是合并到master分支)。git branch -d 分支名
----- 删除指定分支,需要做检查。git branch -D 分支名
----- 强制删除指定分支,不需要做检查。git remote add 远程仓库的名字 远程仓库的地址
----- 添加远程仓库到本地。git remote
----- 查看当前的本地仓库对应的远程仓库的名字(可能不止一个),其中仓库名字可以随便取,一般命名为origin
。git push 远程仓库名 本地分支名
----- 将本地的某个分支提交推送到远程仓库。git push 远程仓库名 本地分支名:远程分支名
----- 将本地的某个分支提交推送到远程仓库,并命名,如果远程分支名与本地分支名相同,则可以省略远程分支名。
git push -f --set-upstream 远程仓库名 本地分支名:远程分支名
参数
-f
表示强制提交推送,当远程仓库对应的分支上有修改时,系统是不会让你提交的,这个时候就可以使用-f
,强制提交。参数
--set-upstream
表示让本地的该分支与对应的远程分支建立关联,这样该本地分支就与该远程分支绑定在了一起。
git push
-----将当前分支提交推送到已建立关联的远程分支上。git pull 远程仓库名 远程分支名
----- 将远程分支的更新拉到本地,并自动与当前分支进行合并。git fetch 远程仓库名 远程分支名
----- 将远程分支的更新拉到本地,但不会与当前分支进行合并。
若没有远程仓库名和远程分支名,则默认抓取与当前分支相关联的远程分支的更新内容。
忽略指定文件
当我们在提交修改时,有时候并不想把所有文件都提交,只想提交指定类型的文件,这时候,我们可以采用以下方式解决:
- 创建文件.gitignore (
touch .gitignore
)。 - 使用
vim编辑器
对文件.gitignore进行编辑,在其中添加提交时要忽略的文件,可以使用通配符,如*.jpg
表示忽略所有的jpg文件。