开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情
Git的基础操作对于入门的开发人员来说是非常重要的,如果只是满足克隆代码、拉取代码、提交代码、推送代码这几个基本操作对于我们开发人员来说是远远不够的。所以,为了更好应用并理解Git工具以及操作,这里将以入门篇和进阶篇对Git进行一个充分的学习!
⭐ 基本概念
❓ 什么是Git(版本控制系统):
- Git:是目前最主流的
分布式版本控制系统,版本控制系统可以帮你保存文件的所有修改记录、并使用版本号进行区分;分布式是每位开发者都能在本地维护自己的代码和修改记录,并且还能和其他人的记录进行同步。
❓ 什么是GitHub(代码托管平台):
- GitHub:一个面向开源及私有软件项目的托管平台,因为
只支持git作为唯一的版本库格式进行托管,故名GitHub。于2008.4.10正式上线。
❓ Git和GitHub的作用:
- Git作用:随时浏览历史版本、将改错的文件还原到指定的版本,还可以对比不同版本的文件差异、防止旧版本覆盖新版本等,起到回复和保护作用。
- GitHub作用:相当于一个存放和管理代码的仓库,多个人可以共享和维护。
❓ Git和GitHub的联系与区别: Git是工具,GitHub是平台,两者没有必然联系,用Git工具向GitHub平台提交代码。
⭐ Git概念
🔨 工作区、暂存区、版本库
-
工作区(working directory):创建的项目文件夹,
当我们对文件做修改时(增删改),文件的改动发生在 工作区。 -
暂存区(stage index):可以理解为一个虚拟工作区,这个工作区位于.git文件夹下的
index文件。可以说暂存区是工作区与版本库的桥梁,暂存区跟踪记录了工作区的文件名和文件状态(修改时间,文件大小等信息),暂存区有时也叫索引,当我们执行 git add 时,对应的文件改动就会被送到暂存区。git还为我们自动生成了一个分支master以及指向该分支的指针HEAD。
-
版本库(Repository):项目目录下的
.git文件夹就是版本库,当我们执行 git commit 时,对应的文件改动才会进入本地仓库,并且使当前的分支向前长了一个 commit object。在任意空文件夹下,通过git init命令初始化仓库,即可在此文件夹下创建.git文件夹。.git的目录结构:// 文件夹 hooks // 用于在git命令前后做检查或做些自定义动作 info logs // 记录操作信息 objects // git的数据库 refs // 文件系统的软链接 // 文件 COMMIT_EDITMSG // 临时文件,存储最后一次提交的信息 FETCH_HEAD HEAD // 永远存储当前位置指针, git cat-file -p HEAD 显示详细的提交信息 ORIG_HEAD // 备份HEAD config // 存储项目本地的git配置 description // 用于GitWeb的描述 index // 暂存区 packed-refs- ORIG_HEAD:对git进行以下操作时会触发备份。
git reset // 重置当前指向版本 git merge // 合并版本 git rebase git pull // 拉取文件 git reset --hard ORIG_HEAD // 回滚到上一次的状态- FETCH_HEAD:追踪远程分支的拉取与合并。
- 文件夹info:文件夹有两个文件:
exclude(用于排除规则,与.gitignore)和refs(跟踪各分支信息)。
如何区分三者之间的区别?
-
比较工作区和暂存区的差别:已经提交暂存区的修改文件与工作区没提交暂存区文件的比对。如下图:提交暂存区的a.txt文件内容为
我是最新文件,没提交暂存区的a.txt文件内容为我是最新文件1。// 执行命令 git diff -
比较暂存区和版本库的差别:当前暂存区a.txt文件内容为
我是最新文件。版本库是还没有这个文件。// 执行命令 git diff --cached -
工作区和版本库的差别:当前工作区a.txt文件内容为
我是最新文件1。版本库是还没有这个文件。// 执行命令 git diff HEAD
🔨 本地版本库与远程仓库
- 本地版本库(repository):用于存储本地工作区和暂存区提交上来的变更(增删改)过的文件的地方。
- 远程库(Remote):托管代码的服务器,可以简单认为是项目组中的一台电脑用于远程数据交换。
🔨 Git四种文件状态
- Untracked:
未跟踪,此文件在文件夹中,但并没有加入git库,不参与控制。通过git add 状态变为Staged。 - Unmodify:文件已经入库,
未修改,即版本库中的文件快照内容与文件夹中完全一致。被修改后是Modified状态;通过git rm移出版本库是Untracked状态。 - Modified:文件已修改,仅仅是
修改,并没有进行其他操作。通过git add 状态变为Staged;通过git checkout状态变为Unmodify。 - Staged:
暂存状态,执行git commit将修改同步到库,此时版本库与本地文件状态一致为Unmodify;执行git reset HEAD filename取消暂存状态变为Modified。
❓ 这四个文件状态是怎么联系与转化的
❓ 这四个文件状态是如何查看的
执行下面的命令,可以获取工作目录和暂存区的状态,当执行命令后可以获取到什么结果:拟提交的变更(已放入暂存区,commit后)、未暂存的变更(工作目录与暂存区存在差异)、未跟踪的文件。
git status [options] // options为git status命令使用的参数
// 比如
git status // 显示工作目录和暂存区的状态
git status -s // 以精简的方式显示文件状态
git status -short // 以精简的方式显示文件状态
git status --ignored // 列出被忽略的文件
下面以a.txt、b.txt文件为例子,a.txt已提交暂存区的内容为
我是最新文件,未提交暂存区的内容为我是最新文件1。b.txt文件未提交暂存。
-
执行git status后:当前提交暂存区的a.txt状态,以及修改后未提交暂存的a.txt和未追踪的文件b.txt。
-
执行git status -s后:以更精简的方式获取文件状态信息,我们可以看出变化的文件信息前面都带了特殊字母以及字符,那么它们究竟代表了什么?
首先执行git status -s显示返回值的时候,返回格式为:
XY path2 -> path2。X和Y都是状态码,X表示暂存区和最近一次提交的差异,Y表示工作目录和暂存区的差异,path1表示最近一次提交的文件,->path2表示索引或工作目录中文件,注意地,当文件路径改变时才会有->path2。所以上面的例子中的AM是两个状态码分别是
A(added,已添加)和M(modified,已修改),而??(untracked,未追踪状态),其实除了这些状态码,git还提供其他的:'' // unmodified ,未修改 M // modified,修改 A // added,添加 D // deleted,已删除 R // renamed,重命名 C // copied,已复制 U // updated but unmerged ?? // untracked 未追踪 !! // ignored 已忽略如果我们够细心的话,我们使用vscode工作台时点击相关区域的文件最右边的字母就会显示工作区与暂存区的差异,并在打开的文件名中显示
带状态名称。 -
执行git status --ignored -s后:获取被忽略的所有文件和文件夹,也就是.gitignore文件内的忽略的文件。
🔨 HEAD
-
HEAD:指的就是
.git/HEAD文件,存储着当前工作区所处的某次commit,是当前分支引用的指针,默认指向上一次的commit。HEAD的指向是可以改变,比如你提交了commit、切换分支、仓库或回滚版本,切换tag。// HEAD文件内容 ref: refs/heads/master // master里内容是一段字符串:版本号
🔨 Git分支
-
Git分支:本质上是指向提交对象的可变指针。Git默认分支是master。当执行
git branch testing命令时就可以新建一个分支。怎么区分Git当前分支是哪一个分支,HEAD指向的就是当前分支。当执行git checkout testing就可以切换当前分支并且HEAD指向也会改变。这两个命令合并为git checkout -b testing代表创建并切换分支。
⚙ Git安装
🔨 安装Git工具
- 下载git工具:git-scm.com/download/wi…
- 安装流程:这里就不一一手把手了😀!
🔨 配置项目Git
- 拉取代码:
git clone 远程仓库地址,远程仓库地址主要分为HTTPS、SSH传输。- HTTPS:不受限制clone,push需要验证用户名和密码;
解决每次需要验证信息:
git config --global credential.helper store只需要输入一次用户名和密码就会在c盘用户下生成一个.git-credentials,上边记录你的账号和密码。- SSH:clone必须是拥有者或者管理员,clone前需要SSH Key,在push的时候是不需要输入用户名的,如果配置SSH key的时候设置了密码,则需要输入密码,否则不需要。
创建SSH key:
ssh-keygen -t rsa -C "邮箱地址";然后在电脑c盘的C:\Users\admin.ssh文件夹下找到.pub后缀文件打开并复制内容到远程仓库的私钥中。
⚙ Git常见配置
Git配置分为三种:仓库级别(local)、用户级别(global)、系统级别(system),优先级从高到低。
// 查看所有配置
git config -l
-
仓库级别(local):配置文件存储于.git/config。
// 查看仓库级别的配置 git config --local -l -
用户级别(global):C盘中的个人C:\Users\宿主.gitconfig文件。
// 查看用户级别的配置 git config --global -l -
系统级别(system):Git工具安装目录下的etc/gitconfig文件。
// 查看用户级别的配置 git config --system -l
❓ 配置文件如何增删查改:
// --add 添加配置
git config [local|global|system] --add key value
// --unset 删除配置
git config [local|global|system] --unset key value
// --get 查询配置
git config [local|global|system] --get key value
// -e 查询配置
git config [local|global|system] -e key value
⭐ Git基本操作(开发流程)
-
🏷 初始化仓库:创建一个Git仓库,在一个空文件夹下执行下面命令后使当前当前文件夹成为一个Git仓库,会生成一个.git隐藏文件。
git init -
🏷 克隆代码:一般都是选择远程的HTTPS或SSH远程地址去克隆代码。
git clone 远程地址 -
🏷 暂存代码:把代码添加到暂存区。
git add * // 添加所有文件到暂存区 git add . // 添加所有文件到暂存区 git add -u . // 添加已追踪文件中的修改和删除文件到暂存区,不包括新增加的文件 git add -A . // 添加已追踪文件中的修改和删除文件到暂存区,包括新增加的文件 git add *.html // 添加指定类型文件到暂存区 git add index/ // 添加指定文件夹所有文件到暂存区 git add index/index.html // 添加指定文件到暂存区 -
🏷 提交代码:提交代码到本地版本库,还没提交到远程仓库。
git commit -m [message] git commit [file1][file2]... -m [message]// 提交暂存区的指定文件到仓库区 git commit -a -m [message] // 不需要执行git add 直接提交 -
🏷 推送代码:将本地当前分支代码提交到远程指定的分支上。
git push // 与远程主机建立关联 git push origin dev:testing // 将本地dev分支推送到远程主机名为origin中testing分支上。如果testing不存在,则被创建 git push origin dev // 远程分支命名与本地分支命名一致 git push origin // 远程分支命名与本地分支命名都是master -
🏷 拉取合并代码:先从远程获取最新版本代码到本地,然后自动合并分支。
git pull // 默认行为git fetch + git merge git pull --rebase // 默认行为git fetch + git rebasegit fetch:将更新git remote中所有的远程仓库所包含分支的最新commit-id,并将其记录到.git/FETCH_HEAD文件中。
git rebase: 有点类似merge,但是一般推荐使用merge,执行rebase操作,git会从两个分支的共同祖先开始提取待变基分支上的修改,然后将待变基分支指向基分支的最新提交,最后将刚才提取的修改应用到基分支的最新提交的后面。
-
🏷 查看状态:显示工作目录和暂存区的状态(详情上面已说)。
git status -
🏷 查看历史:查看提交的日志。
git log // 查看所有 git log -num // 查看指定数量num git log commit_id // 查看指定版本 git log commit_id --name-only // 查看指定版本提交的文件列表 git log commit_id -p // 查看指定版本提交的详细信息。 git log author=xxx // 过滤提交用户
⭐ 分支操作
-
🏷 创建分支:在当前分支创建新分支,但不会自动切换到新分支上。
git branch [分支名]注意地,为了应对业务需要,有时候为了更好区分,新分支命名会有如下规范:
production分支:用于发版,不会直接改master(main)分支:只能从其他分支合并,不能直接在这个分支修改。develop分支:主要开发分支,包含所有要发布到下一个release地代码。feature分支:新功能开发,开发完成,合并回develop分支进入下一个release。release分支:偏向测试,当需要发布新release,基于develop分支创建release分支,完成release后,合并回master和develop分支。hotfox分支:production分支发现新bug,需要创建一个hotfix,完成hotfix后,合并回master和develop分支。topic分支:特性分支,短期分支,被用来实现单一特性或其相关1工作。
-
🏷 查看分支:
git branch -v // 查看分支最新提交 git branch --merged // 查看已合并分支 git branch -a // 查看本地和远程所有分支 git branch -r // 查看远程所有分支 -
🏷 切换分支:
git checkout [分支名] -
🏷 删除分支:
git branch -d [分支名] // 删除指定的已修改且已合并/未修改的子分支。 git branch -D [分支名] // 强制删除指定的未合并分支。 -
🏷 合并分支:
git merge [分支名] // 合并分支 git merge --abort // 中止合并
⭐ GitHub Flow协作流程
-
🏷 克隆/Fork分支:Fork出来的仓库完全属于我们自己,可以任意修改代码和配置,如果想要向主仓库提交pull request且被接受通过,才可以把fork仓库修改的代码合并到主仓库。
-
🏷 创建分支:当项目功能迭代开发时,首先要基于develop分支,新建一个分支出来。
-
🏷 提交Pull Request:即PR,中文意思是拉请求,注意地,是"拉(pull)"不是推(push),这个请求的目的是让仓库所有者来拉'取'变化,由仓库所有者来决定合并还是拒绝,所有者可以根据功能是否合理、代码是否正确等信息进行判断,这实际就是CodeRview的过程。
git request-pull -p 版本号 主仓库地址 分支名 // 仓库所有者(作者) git remote add 主仓库 远程仓库地址 // 作者添加贡献者的远程仓库 git fetch 主仓库 分支名 // 拉去主仓库 git diff master 主仓库/分支名 // 代码比对 git merge 主仓库/分支名 // master分支合并主仓库/分支名 git push // 推送 -
🏷 Code Review:即CR,代码评审,是一种通过复查代码来提高代码质量的过程,一般体现在一个团队的开发过程中。CodeReview需要注意:
git提交规范:也就是提交的代码需要有一些描述信息。代码风格:可读性、文件或变量命名等。架构/设计:代码健壮性、是否有重复代码等。
Git常用的GUI工具
上面都介绍了原生Git命令的基础操作,这种属于原生命令模式,其实还有GUI模式,GUI主要是针对GIT的命令进行封装然后提供看一些更便利的功能来简化使用、提高开发效率。
- 💻 SourceTree:一个开源的Git的GUI工具,提供了对git flow的支持。
- 💻 GitHub For Desktop:GitHub的GUI客户端,可以通过它直接提交pull request(GitHub的PullRequest)。
- 💻 Visual Studio:vs在团队资源管理器中集成了Git的支持。
总结
本篇文章主要介绍了Git基本概念,可以帮助我们更好入门使用Git相关命令。介绍了Git的基本操作,对于Git的相关命令有一定的了解并掌握,将会大大提升我们的提交效率。更重要的是,作为一个开发人员,了解代码提交基本流程、以及团队的协作流程将对我们意义重大。