git命令使用教程

痛定思痛,本篇文章也是为了教会更多跟我一样的新手快速入门git这个神奇的东西,本篇将包括,仓库创建,分支管理,协作拉取,冲突解决,标签发布,代码回滚,尽可能地让你通过本篇来快速入门,话不多说直接开始:

然后我们先说一下前情提要:

你是开发者A,你的同事是开发者B,你们两个需要共同开发一个项目,这个项目需要用到WiFi配置和蓝牙模块

第一阶段:初始化仓库&基础配置

步骤一:我们先创建本地仓库

我们先用mkdir创建了一个esp32-idcard的文件夹,然后在这个文件夹中使用指令git init . 这里的点表示的是当前目录(D:\esp32-idcard)这个指令是用来初始化Git仓库,然后我们继续执行git status 来查看当前状态,根据根据反馈信息我们得到

  • Initialized empty Git repository:已初始化一个空的Git仓库

  • in D:/esp32-idcard/.git/ :Git仓库存储在D:/esp32-idcard/.git/目录中

  • .git目录:这是Git的核心目录,包含所有版本控制所需的数据(提交历史、分支信息、配置等)

On branch master的意思是当前是在master这个分支上,No commits yet 的意思是还没有任何提交,nothing to commit (create/copy files and use "git add" to track)

这一句的意思是没有需要提交的内容,

  • 括号中的提示

    • create/copy files:创建或复制文件到当前目录

    • use "git add" to track :使用git add命令来开始跟踪这些文件

  • 意思:工作目录是空的,还没有任何文件被Git跟踪

步骤二:创建初始文件

接下来我们创建一个main.c文件并填写适当的内容,这里内容实现不做详细介绍,主要就是为了随便填点内容

步骤三:添加远程仓库配置

在这里我们选择在gitee上新建一个仓库作为演示并且复制HTTPS路径

接下来我们输入git remote -v 这条命令来查看远程仓库配置,我们可以看到啥也没有,然后我们使用git remote add origin https://gitee.com/xiaofei05/esp32-idcard.git 这条命令来添加我们的远程仓库,这里的https地址需要换成你自己的,最后再次输入git remote -v指令,发现我们以及添加成功。其中有几个注意的点是

  • git remote add:添加一个新的远程仓库

  • origin :远程仓库的别名(约定俗成使用origin作为主远程仓库的名称)

我们还发现这里好像显示了两个仓库,一个是括号fetch结尾,另一个是以括号push结尾,这两个区别是

  • (fetch):获取(拉取)操作的URL

  • 意思 :当执行git fetch origingit pull origin时,会从这个地址拉取代码

  • (push):推送操作的URL

  • 意思 :当执行git push origin时,会向这个地址推送代码

拉取和推送我们后面会讲到,这里先仅做了解,我们可以看到,在我们的文件夹中已经出现了main.c这个程序,但是在仓库中还没有,因为这个只是已经被创建存在了,还没有被git跟踪添加

本地文件系统 Git工作区 Git暂存区 Git本地仓库 Git远程仓库

main.c ──未跟踪──> 空 ────> 空 ────> 空

(已存在) (未add) (未commit) (未push)

主要的流程是先添加到暂存区,在提交到本地仓库,最后再推到远程仓库

这个时候我们再使用git status可以看到我们在主分支master,还没有提交记录,Untracked files表示未跟踪的文件,他会把当前目录没有跟踪的文件全部列在下面,就比如这个main.c文件

  • nothing added to commit :没有添加到暂存区准备提交的内容

    • but untracked files present:但是存在未跟踪的文件

    • (use "git add" to track) :使用git add来开始跟踪这些文件

  • 整体意思:暂存区是空的,但工作目录中有Git尚未跟踪的文件

步骤四:首次提交和推送

我们使用指令git add . 来将当前目录下所有文件和子目录添加到暂存区,就是为了开始跟踪所有未跟踪的文件,并暂存所有修改。Changes to be committed:表示有改变并将要提交的文件,也给你用绿色列出来了,就是我们刚添加到暂存区的main.c文件。然后我们调用git commit -m "feat: initial project setup for ESP32 ID card reader"这句命令来将暂存区的文件提交到本地仓库

  • git commit:将暂存区的文件提交到本地仓库

  • -m:指定提交消息

  • 引号中的内容:提交消息,使用了约定式提交格式

    • feat::表示这是一个新功能

    • initial project setup for ESP32 ID card reader:具体描述

这里还涉及到了约定是提交(Conventional Commits),除了feat表示新功能之外还有很多常用的,比如说fix表示修复bug,docs表示文档更新,style表示代码样式调整(不影响功能),refactor表示代码重工(不添加功能也不修复bug),perf表示性能优化,revert表示撤销之前的提交,merge表示合并分支,还有很多这里就不过多举例了,请自行查询

然后还显示了

On branch master

nothing to commit, working tree clean

这说明工作目录跟暂存区都是干净的,所有更改都已经提交了,然后我们调用git push -uorigin main指令尝试推送到main分支,然后报错了,这是因为gitee这个仓库默认生成的是master分支,所以我们应该是推送到master分支上才对,现在我们再来看一下远程仓库就会发现多了一个main.c文件

第二阶段:创建dev分支&开发功能

步骤五:创建并切换到dev分支

我们使用指令git branch可以查看当前本地所有分支发现只有一个master分支并且前面有个*(星号),星号表示的是当前所在的分支,然后我们调用git checkout -b dev指令创建了一个新的分支dev,其中 -b 是--branch的简写,表示创建了新分支,这一句指令相当于执行了 git branch dev # 创建分支 git checkout dev # 切换到该分支 这两个指令

步骤六:在dev分支开发(wifi功能)

这里请自行创建一个wifi.c的文件吧,这里内容就随便写写了然后我们可以看到有引得准备提交的文件wifi.c,然后我们进行提交并使用 -m 来叙述,然后用git status来查看发现已经提交完了并且当前是在dev分支上

步骤七:推送dev分支到远程仓库

ok我们成功的把dev分支上的wifi.c代码也推到了远程仓库上,下面是对指令git push -u origin dev的拆分解析

  • git push:将本地提交推送到远程仓库

  • -u--set-upstream的简写,建立跟踪关系

  • origin:远程仓库别名

  • dev:要推送的本地分支名

  • 整体意思:将本地的dev分支推送到origin远程仓库,并建立跟踪关系

然后根据这三张照片我们可以看到,我们现在是有两个分支的,因为我们现在是在dev分支开发,远程仓库的main分支是独立的,只有git merge dev 合并之后再git push origin main,远成main才会更新,这是git分支隔离的设计核心------dev的代码不会自动污染main,确保主分支始终稳定,后面会讲到什么是合并如何合并,这里有个大体印象就行。

第三阶段:模拟同事修改

这种情况总是无法避免的,所以我们要学会如何解决,如果修改了同一份文件就需要merge,没有改的文件不影响,冲突就是远程仓库文件版本与你本地的文件版本不同了,就意味着两个人改了同一个文件,接下来我们模拟一下

步骤八:同时克隆仓库&修改main

这里模拟同事使用git clone克隆远程仓库到本地,Already on 'master'表示已经在master分支上,Your branch is up to date with 'origin/master'.这句话的意思是你的分支与"origin/master"是最新的,本地master分支与远成origin/master分支完全同步,也就是说不需要拉取更新,代码是最新的。

这里输入的时候出了点小错误,毕竟我也是菜鸡,请原谅,更改之后我们发现两次的main.c内容已经被更改了,也就是说我们在dev分支修改了main.c的loop()函数,但是现在我们的同事在measter分支也修改了这个loop()函数,这也就出现了我们一开始说的冲突问题,当我们合并时,git就会检测到重读,需要我们手动解决

Changes not staged for commit:表示已修改但未添加到暂存区的文件,modified: main.c这个表示已修改的文件,Untracked files:这个表示未跟踪的文件

当我们提交代码并推送之后我们发现,我们的主分支master多了个ble.c文件和main.c文件被修改了

第四阶段:你拉取更新&检测变更

步骤九:定期fetch检查远成变更

我们使用指令git fetch origin发现

  • 8ed2286..a993cac:从提交8ed2286到a993cac

    • master -> origin/master:更新了origin/master分支的指向
  • 含义:远程master分支现在指向a993cac提交

说明远程仓库已经变更了,然后我们调用git --no-pager log master..origin/master --oneline

这个指令的意义是查看在origin/master中有,但在本地master中没有的提交

  • a993cac:提交的哈希值(前7位)

  • (origin/master):这个提交现在在origin/master分支上

  • feat: add BLE module and update main loop:提交信息

现在说明同事推送了新代码,你必须同步后在合并你的dev分支

步骤十:尝试合并前,先同步你的main分支

我们先用pull拉取代码,显示两个文件被更改,create mode 100644 ble.c表示创建了ble.c文件,然后使用git status确认同步完成,Your branch is up to date with 'origin/master'.表示本地与远程完全相同

然后调用git --no-pager log --oneline -3 master查看提交历史

  • 显示两个提交

    1. a993cac:同事的BLE提交(当前HEAD)

    2. 8ed2286:你的初始提交

  • 标签

    • HEAD -> master:当前HEAD指向本地master分支

    • origin/master:也与远程master分支相同

步骤十一:给当前稳定状态打标签

我们调用git tag -a v1.0 -m "Stable before dev branch merge"这句指令

  • git tag:标签管理命令

  • -a--annotated的简写,创建带注解的标签

  • v1.0:标签名称(遵循语义化版本号)

  • -m:指定标签消息

  • "Stable before dev branch merge":标签的描述信息

你的标签消息说明:"Stable before dev branch merge"

  • 意义:在合并dev分支到master之前创建一个稳定点

  • 作用:如果合并出问题,可以快速回退到这个版本

标签与分支的区别:

特性 标签 (Tag) 分支 (Branch)
移动性 固定,不移动 随着提交移动
用途 标记特定版本 开发线
示例 v1.0, v2.0 master, dev
可修改 否(通常)
推送 需要显式推送 随提交推送

然后调用git push origin v1.0推送标签到远成仓库

然后我们就可以看到在这个仓库中多了个标签,我们也可以下载这个版本

步骤十二:在dev分支开发(wifi功能)

我们现在捋一下当前是什么状态,我们一开始是创建了个master分支,里面只有一个main.c文件,并且内容是这样的

然后我们创建了dev分支,打算在这个分支里面开发wifi的功能,并且已经创建了wifi.c且推送到了远程仓库,注意这时候我们dev分支下的main.c文件是跟master分支下的main.c文件是一样的,之后呢我们的同事gitc lone了这个仓库的代码,并且呢我们的同事创建了ble.c文件和修改了master分支的main.c里的内容,并且推送到了远成仓库上面

这个时候呢我们使用fetch发现远程仓库被同事修改了,也就造成了冲突,所以我们就需要拉取然后合并

通过这张图片我们可以很清晰很直观的感受一下,左边是同事当前的工作项目,右边是我们拉取之后的工作项目,我们发现拉取之后的master分支跟远程仓库里的代码是一样的。

ok现在基本捋清楚了,没懂的再仔细体会一下,然后我们开始继续在dev分支开发wifi功能:

ok我们现在对dev分支下的main.c进行了修改,当我们push到远程仓库之后然后进行合并,我们的dev分支下的main和master下的main产生冲突因为他修改了同一个文件的代码,因为你现在修改之后的main是

但你master分支里的main是

所以说在你合并的时候第三行一定会有冲突

刚刚我又犯了个小错误就是我们现在在合并前应该需要切换到master分支再pull一次,以保证这是最新的代码,结果我不小心没切换master分支就直接pull拉取了,我们可以调用git reset --hard HEAD~1彻底丢弃最近一次提交,包括它的所有文件修改,回到上一个提交的状态,(如果你用的是--soft的话他不会丢弃刚刚的文件修改),因为我们刚刚已经推送过了,所以这里我们再git pull origin dev从仓库拉一下我们将要合并前的样子

然后我们发现再合并的时候出现了冲突

Auto-merging main.c

  • Git尝试自动合并main.c文件

CONFLICT (content): Merge conflict in main.c

  • 冲突:main.c文件内容冲突

  • 类型:内容冲突(文件内容不一致)

Automatic merge failed; fix conflicts and then commit the result.

  • 自动合并失败

  • 指示:需要手动解决冲突,然后提交结果

按理来说你现在再调用cat main.c来查看应该是会有类似这种的冲突标记的

但是我这个在powershell中,Set-Content 默认使用 UTF-16 LE(带 BOM)编码 写入文件这种编码在文件开头会插入不可见的字节(BOM) Git 会误判为"二进制文件",拒绝在二进制文件中插入冲突标记,你也可以自己重新复制粘贴到记事本改一下编码另存为UTF-8编码的程序,然后重新push到远程仓库,这里由于发生的冲突比较简单,我就直接手动编辑了

我直接手动编辑master分支下的main.c程序,这里已经编辑好了如上图所示。

然后我们调用git add main.c 标记冲突已解决,告诉git我已经处理好了main.c的冲突,实际上就是将main.c从"未合并状态",移到"已暂存准备提交"。All conflicts fixed but you are still merging.表示你已经解决了冲突,但还需要提交来完成合并。[master 6e07750] Merge branch 'dev'表示在master分支创建了新的合并提交6e07750

我们也可以通过调用git log --oneline --graph --all来查看一下完整的提交历史

然后确认无误之后你就可以调用git push origin master来推送最终的结果了

然后你就可以打开你的gitee仓库看看是不是都有以上图片的东西

最后我们再来稍微学一下代码回滚

我们第一步先调用了git --no-pager log --oneline -2来查看当前状态,这一句的作用是快速查看最近2个提交

6e07750 (HEAD -> master, origin/master) Merge branch 'dev' ← 当前 HEAD

a2d8d7b (origin/dev, dev) fix: update main loop...

意义是确认你处于"合并完成后的状态",这是我们进行代码回滚实验的起点

然后我们调用git reset HEAD~1来执行回滚,也就是撤销最近一次提交,从6e07750回退放到了a993cac(即v1.0)

Unstaged changes after reset:

M main.c

说明文件修改还在,只是"提交"被撤销了

然后我们调用git status查看状态

  • 输出解读
    • Your branch is behind 'origin/master' by 3 commits
      → 因为本地回退了,但远程 origin/master 仍在 6e07750
    • modified: main.c
      → 合并带来的代码修改还在工作区
    • untracked: wifi.c
      → Git 认为这是新文件(因为回退后它不再属于任何提交)
    • 这说明:git reset 只改变提交历史,不删除工作区文件

然后我们调用了git --no-pager log --oneline -1输出a993cac (tag: v1.0)这代表我们确实回到了打标签的状态(合并前)

然后我们调用git reset --hard 6e07750强制回到指定提交(6e07750),他的作用是我们又恢复到合并提交,工作区和暂存区也会完全重置为6e07750的状态,git status 会显示 "nothing to commit"。所以通过这个我们可以学到只要记住 commit ID,就能随时回到那个历史状态

相关推荐
历程里程碑6 小时前
4 Git远程协作:从零开始,玩转仓库关联与代码同步(带实操代码讲解)
大数据·c++·git·elasticsearch·搜索引擎·gitee·github
金銀銅鐵8 小时前
[git] 浅解 git reset 命令
git·后端
zhangfeng11338 小时前
部署到服务器上 宝塔系统 使用宝塔在线编辑器 FTP 批量上传 Git 部署 打包上传 codebudyy 编程程序开发
服务器·git·编辑器
学习是种信仰9 小时前
Git工作流
git·深度学习
yuanyuan2o211 小时前
Git merge 的几种不同模式
git·github
视觉小萌新11 小时前
关于Vscode配置企业Git
git
zh_xuan11 小时前
使用命令行把安装包上传到github
c++·git·libcurl·c++工程打包
zhangfeng113313 小时前
适合 5人以内小团队的Git 工作流 + Code Review + 自动化部署方案 FastAdmin +linunx服务器宝塔系统 外包项目 —
服务器·git·自动化·php·代码复审
念一不念二17 小时前
[Git]git仓库管理的使用
git