当前位置: 首页 > news >正文

掌握Git:版本控制与高效协作指南

 一、初始Git

提出问题:无论是在工作还是学习,我们在编写各种文档的时候,更改失误,失误后恢复到原来版本,不得不复制出一个副本。

每个版本由各自的内容,但最终只有一个报告需要被我们使用。

但在此之前的工作都需要这些不同版本的报告,难道每次都要去复制粘贴文本吗?随着版本数量的不断增多,你还能记得这些版本各自都是修改了什么内容吗?

于是有了--

版本控制器

为了能够方便的管理这些不同版本的文件,便有了版本控制器。所谓的版本控制器,就是让你了解到一个文件的历史,以及他的发展过程的系统。通俗的讲就是一个可以记录工程的每一次改动和版本迭代的一个管理系统,同时也方便多人系统工作。

注意事项

还需要明确一点,所有的版本控制系统,其实只能跟踪文本文件的改动。比如TXT文件,网页,所有的程序代码等等。本版控制系统可以告诉你每次的改动,比如在第某一行加入/删除了某个单词

而这些图片、视频这些二进制文件,虽然也能由版本控制系统管理,但是没法跟踪文件的变化,只能把二进制文件每次改动穿起来,也就是只要图片从100KB到了120KB,但是修改了什么,版本控制器是不知道的。

二、Git的安装

Linux-Ubuntu

sudo apt install git

Linux-Centos

sudo yum -y install git

三、Git的基本操作

创建Git的本地仓库

仓库是进行版本控制的一个文件目录。要想对文件进行版本控制,就必须先创建一个仓库出来。

命令:

git init

查看一下.git目录的内容,后续进行介绍:

配置Git

安装Git之后最需要做的就是设置你的用户名称和e_mail地址,这是非常重要的。配置命令为:

配置:
git config [--global] user.name "Your Name"   
git config [--global] user.email "email@example.com" 
删除:
git config [--global] --unset user.name
git config [--global] --unset user.email
查看:
git config -l

--global 是一个可选项,如果使用了这个选项,表示这台机器上所有的Git仓库都会使用这个配置。如果你希望在不同的仓库中使用不同的name和e_mail,可以不加--global选项,但要注意的是,执行命令时必须要在仓库中

认识工作区、暂存区、版本库

  • 工作区:是你要写代码或文件 的目录
  • 暂存区:stage/index。一般存放在.git目录下的index文件,也把暂存区叫做索引
  • 版本库:又名仓库。工作区里有一个隐藏的.git,它不算是工作区,它是Git的版本库。这个版本库里面的所有文件都可以被Git管理起来,每个文件的修改,删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

  • 图中左侧为⼯作区,右侧为版本库。Git的版本库⾥存了很多东西,其中最重要的就是暂存区。
  • 在创建Git版本库时,Git会为我们⾃动创建⼀个唯⼀的master分⽀,以及指向master的⼀个指针叫HEAD。(分⽀和HEAD的概念后⾯再说)
  • 当对⼯作区修改(或新增)的⽂件执⾏ git add 命令时,暂存区⽬录树的⽂件索引会被更新。
  • 当执⾏提交操作 git commit 时,master分⽀会做相应的更新,可以简单理解为暂存区的⽬录树才会被真正写到版本库中。

所以:通过新建和粘贴进目录的文件,并不能称之为仓库中的新增文件,而只是在工作区中新增了文件罢了。必须通过使用git add git commit 命令才能将文件添加到仓库中进行管理!!!

添加文件--场景一

在包含.git的⽬录下新建⼀个ReadMe⽂件,我们可以使⽤git add 命令将文件添加到暂存区:

  • 添加⼀个或多个⽂件到暂存区:git add [file1] [file2] ...
  • 添加指定目录到暂存区,包括子目录 git add [dif]
  • 添加当前目录下的所有文件改动到暂存区:git add .

再使用 git commit 命令把暂存区内容添加到本地仓库中:

  • 提交暂存区全部内容到本地仓库中:git commit -m "message"
  • 提交暂存区的指定⽂件到仓库区:git commit [file1] [file2] ... -m "message"

-m 选项,要更上描述本次提交的message,由用户自己完成,这部分内容不能省略,要好好描述,是用来记录你的提交细节,是给人看的。

把代码直接提交到本地仓库之后,可以使用 git log 命令来查看一下历史提交记录

这条命令显示从近到远的提交日志,并且可以看到我们commit的日志消息

如果先输出信息太多的话,可以加上 --pretty=oneline 参数

查看.git文件

在执行 git add 之后会默认生成一个index,也就是我们的暂存区,add后的内容就是“添加”到了这里(事实上是索引被添加到了这里,内容在objects库中)

HEAD就是我们默认指向的master分支的指针,而默认的master分支里的一连串的内容就是保存当前最新的commit id:

查找Object时要将commit id分成2部分,前2位是文件夹的名称,后38位是文件名称

找到这个文件之后,一般不能直接看到里面是什么,该类文件是经过sha(安全哈希算法)加密郭的文件,但是我们可以使用git cat-file命令来查看版本库对象的内容。

小结

在本地的git仓库中,有几个文件或者目录很特殊

  • index:暂存区,git add后会更新这个内容
  • HEAD:默认指向master分支的一个指针
  • refs/heads/master:文件里保存当前的master分支的最新的commit id
  • objects:包含了创建的各种版本库对象及其内容,可以简单理解为放了git维护的所有的修改
添加文件--场景二

现在创建两个文件file4file5

touch file4 file5

把file4加入到暂存区中

git add file4

然后执行这条命令,发现只有一个文件发生了修改,而我们本意是想要同时管理file4和file5。这是因为git commit只能把暂存区中的文件加入到本地仓库中

git commit -m "add file"[master 1a15c78] add file1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 file4
修改文件

Git比其他的版本控制系统设计得优秀,因为Git跟踪的是修改,而非文件。

什么是修改?⽐如你新增了⼀⾏,这就是⼀个修改,删除了⼀⾏,也是⼀个修改,更改了某些字符, 也是⼀个修改,删了⼀些⼜加了⼀些,也是⼀个修改,甚⾄创建⼀个新⽂件,也算⼀个修改。

对ReadMe文件进行一次修改

cat ReadMehello git
hello world

此时仓库中的ReadMe和我们工作区中的ReadMe是不同的,如何查看当前仓库的状态呢?可以使用 git status

可以看出,ReadMe确实被修改了,但是没有完成添加和提交

目前,只是知道了文件被修改了,但是哪些地方被修改了呢?可以通过 git diff 命令来查看

git diff ReadMe

git diff [file] 命令用来心事暂存区和工作区文件的差异,显示的格式是Unix通过的diff格式,也可以使用git diff HEAD [file]命令来查看版本库和工作区文件的区别

在进行git add ReadMe之后,进行git commit之后的状态分别为

版本回退

之前我们也提到过,Git能够管理⽂件的历史版本,这也是版本控制器重要的能⼒。如果有⼀天你发现 之前前的⼯作做的出现了很⼤的问题,需要在某个特定的历史版本重新开始,这个时候,就需要版本 回退的功能了。

git reset命令用来回退版本,可以指定退回某一次提交的版本。回退的被指就是向版本库中的内容进行回退,工作区或者暂存区是否回退由命令参数决定:

git reset [--soft | --mixed | --hard] [HEAD]

  • --mixed为默认选项,使用时可以不同这个参数。该参数只是将暂存区的内容退回为指定提交版本内容,工作区文件保持不变
  • --soft参数对于工作区和暂存区的内容都保持不变,只是将版本库回退到某个指定的版本
  • --hard参数将暂存区和共过去都回退到指定版本。切记工作区有未提交的代码时不要用这个命令,因为工作区会回滚,没有提交的代码就在要找不回来,所以使用这个参数一定要慎重
  • HEAD说明:
    • 可以直接写成commit id,表示指定退回的版本
    • HEAD表示是当前版本
    • HEAD^上一版本
    • HEAD^^上上一版本
    • ......
  • 可以使用~数字表示
    • HEAD~0表示当前版本
    • HEAD~1上一版本
    • HEAD~2上上一版本
    • ..

版本回退本质是这样的

撤销修改

看图理解即可

删除文件

在Git中,删除也是一个修改操作,如果要删除文件,直接rm删除,只是在工作区中删除,后续还需要再暂存区和版本库中删除

推荐使用 git rm 指令,将文件从暂存区和工作区中删除,然后再commit

分支管理

理解分支

创建分支

Git支持查看和创建其他分支,这里来创建一个自己的分支dev,对应的命令为:

git branch devgit branchdev
* master

当我们创建新的分支后,Git新建了一个指针叫做dev,*表示当前的HEAD指向的分支是master分支。

切换分支的命令

git checkout dev

再master分支上,合并两个分支的内容

git checkout master
git merge dev

删除分支

合并完成之后,dev分支对我们来说就没用了,就可以被删除掉,但是如果当前正处于dev下,就不能删除dev分支,需要切换到其他分支

命令为:

git branch -d dev
合并冲突

在实际分⽀合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。

这里比较简单,就是在marge之后手动调整冲突的代码,并且再次提交修正后的结果!!

分支管理策略

通常合并分支时,如果可能,Git会采用Fast forward模式。

在这种模式下,删除分支后,查看分支历史时,会丢掉分支信息,看不出来最新提交到底是merge进来的还是正常提交的。

但是在合并冲突部分,我们看到通过解决冲突问题会再进行一次新的提交,最后的状态为

那么这就不是fast forward模式了,这样的好处是,冲分支历史上就可以看出是分支信息。

Git支持强制禁用fast forward模式,那么就会在merge时生成一个新的commit,这样从分支历史上就可以看出分支信息。 比如:

创建新的分支,对ReadMe文件进行修改,添加到暂存区,版本库,切回master分支,开始合并两个分支的内容

git merge dev2 --no-ff -m "merge dev2"

再使用这个命令查看一下

git log --graph --pretty=oneline --abbrev-commit*   dd30dcb (HEAD -> master) merge dev2
|\  
| * fbf25f7 (dev2) md ReadMe
|/
分支策略

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平常不能再上面干活

干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,再把dev分支合并到master上

bug分支

假如现在正在dev2分支上进行开发,突然发现master分支上有bug,需要解决。给i他Git中,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

当然我们可以直接再dev2分支上对代码进行修改,但是这样违背了我们创建dev2的初心,所以还是更建议再创建一个分支去单独完成这个修改的任务。于是现在我们需要切换到master分支去新建一个分支,但是现在dev2的代码在工作区中开发了一半,还无法提交,该怎么办?

Git提供了git stash命令,可以将当前的工作区信息进行储藏,被储藏的内容可以在将来某个时间恢复出来。

git stashSaved working directory and index state WIP on dev2: 41b082f modify ReadMe

查看一下当前的状态

git statusOn branch dev2
nothing to commit, working tree clean

这样就可以切换到master分支去创建一个新的分支fix_bug,再切换到fix_bug分支去完成修改任务。

fix_bug分支中完成对错误的修改任务之后,再次切换到master分支和fix_bug分支进行合并。合并之后,可以删除掉fix_bug分支,然后再次切换到dev2分支进行刚才为未完成的任务。

切换到dev2分支之后,我们首先需要恢复现场,命令:

查看:git stash list删除:git stash pop

在dev2中完成任务之后我们有两个选择

  1. 直接在master分支合并dev2分支,但是这样有一个问题就是,dev2master分支是存在冲突的,玩意修改不当,可能会有更大的问题出现,所以还是更加建议第二种方法
  2. dev2分支合并master分支,然后再切换到master分支去合并dev2分支

最后检查一下有没有把dev2bug_fix分支删除

删除临时分支

添加一个新功能的时候,肯定不希望因为一些代码把主分支搞乱了,所以每次添加一个新的共呢个,最好新建一个分支,我们将其称之为feature分支,在上面开发,完成之后,合并,最后,删除这个分支。

可是,有时候我们在这个分支上开发了一半,可能会被叫停。这个时候我们需要把我们开发的整个新功能删掉,这时候用传统的git branch -d 命令删除分支是不行的,因为没有合并。

其实直接使用强制删除就行了

git branch -D [分支名]

小节

分支在实际中有什么作用呢?假设你准备开发一个新的功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还有没完成,不完整的代码库会影响别人。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。

所以有了分支,据不用怕了。你创建了一个属于自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上工作,想提交就提交,知道开发完毕后,再一次性合并到原来的分支上,这样既安全还不影响别人的工作。

远程操作

理解分布式版本控制系统

目前所说的全部的内容都是在本地的,也就是在一台主机上。但是GIt是分布式版本控制系统,这是什么意思呢?

可以简单理解为,我们每个⼈的电脑上都是⼀个完整的版本库,这样你⼯作的时候,就不需要联⽹ 了,因为版本库就在你⾃⼰的电脑上。既然每个⼈电脑上都有⼀个完整的版本库,那多个⼈如何协作 呢?⽐⽅说你在⾃⼰电脑上改了⽂件A,你的同事也在他的电脑上改了⽂件A,这时,你们俩之间只需 把各⾃的修改推送给对⽅,就可以互相看到对⽅的修改了。

分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就行了。

在实际开发中,分布式版本控制系统更普遍的是有一台充当“中央服务器”的电脑,但这服务器的作用是方便大家交换修改,没有他也没有关系,只是交换不方便罢了。有了这个中央服务器的电脑,这样就不用怕本地出现什么故障了。

远程仓库

GitHub访问不方便,这里使用gitee。gitee可能有的校园网会禁止访问,可以切换成其他网络。

自行新建一个开源的远程仓库,填写一下介绍即可。

克隆远程仓库

克隆/下载远端仓库到本地,需要使用git clone命令,后面跟上哦我们的远端仓库的链接,远端仓库的链接可以从仓库中找到:点击克隆/下载

SSH协议和HTTPS协议是Git最常使⽤的两种数据传输协议。SSH协议使⽤了公钥加密和公钥登陆机 制,体现了其实⽤性和安全性,使⽤此协议需要将我们的公钥放上服务器,由Git服务器进⾏管理。使 ⽤HTTPS⽅式时,没有要求,可以直接克隆下来。

SSH协议和HTTPS协议都是Git最常用的两种数据传输协议。SSH协议是以哦那个了公钥加密和公钥登陆机制,特体现了实用性和安全性,使用此协议需要将我们的公钥放在服务器上,由Git服务器进行管理。使用HTTPS方式的时候,没有要求,可以直接克隆下来。

使用HTTPS方式,直接执行下面这段代码就行了:

git clone [HTTPS的克隆链接]

使用SSH方式:

git clone [SSH的克隆链接]

如果直接使用这个命令的话,服务器会拒绝clone链接,因为我们没有设置公钥。

  • 创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,看看这个目录下有没有id_rsaid_rsa.pub这两个文件,有的话,直接跳到下一步;没有的话,需要创建SSH Key:
ssh-keygen -t rsa -C "gitee上绑定的邮箱地址"

顺利的话,可以在⽤⼾主⽬录⾥找到 个就是SSHKey的秘钥对, .ssh ⽬录,⾥⾯有 id_rsa 和 id_rsa.pub 两个⽂件,这两 id_rsa 是私钥,不能泄露出去, id_rsa.pub 是公钥,可以放⼼地告 诉任何⼈。 

  • 添加⾃⼰的公钥到远端仓库。

之后再执行第一条命令就行了

向远程仓库推送

本地已经clone成功了远程仓库,我们就可以向仓库中提交内容,例如新增一个文件。

提交时要注意,如果我们之前设置过全局的name和e-mail,这两项配置需要和gitee上配置的⽤⼾ 名和邮箱⼀致,否则会出错。或者从来没有设置过全局的name和e-mail,那么我们第⼀次提交时也 会报错。这就需要我们重新配置下了,同样要注意需要和gitee上配置的⽤⼾名和邮箱⼀致。如何配置 已讲过,在这⾥就不再赘述。 到这⾥我们已经将内容提交⾄本地仓库中,如何将本地仓库的内容推送⾄远程仓库呢,需要使⽤ push 命令, 该命令⽤于将本地的分⽀版本上传到远程并合并,命令格式如下:

git push <远程主机名> <本地分支名>:<远程分支名># 如果本地分支名和远程分支名相同,可以省略冒号后面的内容
git push <远程主机名> <本地分支名>
拉取远程仓库
Git既然可以多人开发,那么就必然有远程仓库的版本新于我本地版本的情况,这时候我想要和远程版本保持一致的话,我就需要使用拉取远程仓库的指令--
git pull <远程主机名> <远程分支名>:<本地分支名>#如果远程分支是与当前分支合并,则冒号后面的内容可以省略。
git pull <远程主机名> <远程分支名>

 配置Git

忽略特殊文件

在日常开发中,往往有一些文件不想/不应该被提交到远端,怎样让Git知道呢?其实再Git的工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件的名字填进去,GIt就会自动忽略这些文件了。

当初在创建仓库时就可以为我们生成,不过需要我们勾选一个选项。

如果当初没有勾选也没有关系,在工作区创建一个也行。

vim .gitignore

可以在文件中写入以下内容 

*.so
!c.so

这个意思是忽略掉所以的 .so 文件,除了 c.so

这时如果我想要添加一个b.so被管理是不行的,因为会被忽略掉。

这时候可以向c.so一样在.gitignore配置,也可以使用(但不推荐)

git add -f b.so

随着.gitignore中的内容增多,我们在添加某些文件的时候可以无法添加成功,不知其所以然,觉得可能是被忽略了。所以来查看一下是否是因为.gitignore。由于内容太多,直接看肯定是不方便的,所有有这样的指令。

git check-ignore -v [file]

这样可以找出文件被忽略的原因 

配置命令

说白了,就是起别名。

举个例子,把git status简化成git st

git config --global alias.st status

 标签管理

理解标签

标签tag,可以简单理解为是对某次commit的一个标识,相当于起了一个别名。例如,在项目发布某个版本的时候,针对最后一次commit起一个v1.0这样的标签来标识里程牌的意义。

相较于难以记忆的commit id,tag能很好的解决这个问题,因为tag一定要给人一个让人容易记住的,有意义的名字。当我们需要回退到某个重要的版本的时候,直接使用标签就能很快定位。

创建标签

首先要切换到相应的分支(需要打标签的分支)上,然后--

# 创建标签
git tag [name]#查看所有标签
git tag

 默认标签是打在最新提交的commit上的。那如何在指定的commit上打标签呢?方法是找到历史提交的commit id,然后打上就行了。

git tag [name] [commit id]

注意,git tag的标签不是按时间顺序列出,⽽是按字⺟排序的。 

还可以通过这条命令来查看标签信息

git show [tagname]

Git还提供可以创建带有说明的标签,用-a指定标签名,-m指定说明文字,格式为:

git tag -a [name] -m "XXX" [commit id]

除此之外,打完标签之后,.git库中也有多出tag目录,tag目录下有我们创建的标签

操作标签

如果标签打错了,也可以删除,比如说我们要删除v1.0这个标签,可以使用命令

git tag -d v1.0

因为创建的标签都储存在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。

如果需要推送某个标签,使用命令:
 

git push origin <tagname>

当然,如果本地有多个标签的话,可以使用命令,一次性的全部推送到远端

git push origin --tags
删除码云上的标签
  • 先在本地删除这个标签,比如说我们要删除v1.0
git tag -d v1.0
  • 然后把这个删除信息推送到远程仓库即可
git push origin :v1.0

 多人协作

多人协作一

实现多人协作开发!

目标:在远程master分支下的file.txt文件新增代码"aaa"、"bbb"

实现:由开发者1新增"aaa",由开发者2新增"bbb"

条件:在一个分支下协作实现

来分析一下,既然要在一个分支下实现,那这个分支一定不可能是master,因为之前我们就知道amster分支上的代码一定的稳定的,所以我们需要创建一个新的分支。

可以直接在仓库里创建一个新的分支--dev,步骤如下

master->管理->新建分支->名称随意-常规分支

然后开始在两个主机上实现目标

插曲

来说明一下这个git push命令。这个命令是把本地的分支上的内容推送到远程仓库的某一个分支的操作。既然是从一个分支,到另一个分支,总得知道是谁给谁吧。于是,命令为

git push <远程主机名> <本地分支名>:<远程分支名>

这时候,有人就会问了,这么长,能不能简化一下?答案是可以的。 

让本地的分支追踪远程仓库的分支之后,可以只使用git push命令即可完成推送任务

git branch --set-upstream-to=origin/<branch> dev#或者在创建dev分支的时候,使用这条命令
git checkout -b dev origin/dev

继续我们两台主机的操作:

首先主机1下,率先修改file.txt文件,在文件中写入aaa,并且进行add, commit, push操作

然后来操作一下主机2,对于主机2,我们按部就班的跟着主机1一样操作。但是在push操作的时候,我们出现了问题,因为Git的dev分支并不知道应该怎么处理冲突,所以干脆直接报错吧。

这个时候我们就需要在主机2上先使用git pull命令,把远程的dev分支下的最新的内容拉取到本地,类似于解决合并冲突一样,解决冲突之后,再把这个内容push到远程仓库中。

做到这一步,还没有完成,因为我们只是在远程仓库的dev分支中完成了目标,还没有把它合并到master分支上。

  1. PR,提交一个申请单给管理员,由管理员负责
  2. 采用本地的方法,master分支(需要保持最新的状态)合并dev分支,本地master分支推送到远程master分支
    1. 当然用master分支合并dev分支,之前我们就做过,而且为了保持master分支的稳定性,我们采用的是dev分支先来合并master分支,解决冲突,然后master分支再合并dev分支

虽然更推荐PR的方法,但是这里来描述一下本地的方法

首先,分别把master分支和dev分支更新的对应仓库的最新状态,本地master分支对应远程仓库的master分支,本地dev分支对应远程仓库的dev分支,说白了就是在两个分支下执行命令——

git pull

 然后在本地切换到dev分支,执行命令——

git merge master

然后切回到master分支,执行命令——

git merge devgit push

最后把本地和远程仓库中没用的分支都删除掉。

多人协作二

目标:远程master分支下新增function1和funciton2文件

实现:由开发者1新增funciton1,由开发者2新增funciton2

条件:在不同的分支下协作完成,各自让每个功能私有一个分支

这个步骤应该和上边的差不多,建议可以自己先锻炼一下

之前我们使用的是远程创建分支的方式,这里来介绍一下本地创建分支的方法

大致的操作就是在本地创建好分支之后,再推送到远程。

更推荐的是远程创建分支的方式

创建并切换feature-1分支

git checkout -b feature-1

新建function1文件,并写入一定内容,然后add。commit。之后直接使用 git push 会失败,因为没有和远程分支绑定,而且远程也没有与我们相对应的分支。所以我们使用命令——

git push origin feature-1

这个命令可以在远程创建相应的分支,并推送到这个分支上,但是不会绑定远程分支。

同理于feature-2

假如说现在负责feature-2的人临时有事,这个function2的开发工作给了你,你该怎么处理呢?

首先,明确一下,我本地(主机一)是没有关于feature-2分支的内容的,所以首先我需要从远程仓库pull

git pull有两种功能

  1. 从远程仓库中获取某个分支下的内容(这个需要建立连接)
  2. 获取远程仓库下的分支

git pull之后可以发现多出了远程仓库的feature-2分支,所以在本地创建一个feature-2分支并且和远程的分支相连接

git checkout -b feature-2 origin/feature-2 

然后进行更新即可。

最后的任务就是把feature-1和feature-2分支合并到master分支上。

--其实就是PR的操作罢了,当然在合并第二份分支的时候可以采用现在非master分支上合并再合并到master分支的方法,更加的安全。

着手删除分支,远程仓库的分支可以直接再管理分支中删除。至于本地的这些

  dev
* feature-1feature-2masterremotes/origin/HEAD -> origin/masterremotes/origin/devremotes/origin/feature-1remotes/origin/feature-2remotes/origin/master

可以使用这个命令,对分支进行修剪

git remote prune origin

完~

相关文章:

掌握Git:版本控制与高效协作指南

一、初始Git 提出问题&#xff1a;无论是在工作还是学习&#xff0c;我们在编写各种文档的时候&#xff0c;更改失误&#xff0c;失误后恢复到原来版本&#xff0c;不得不复制出一个副本。 每个版本由各自的内容&#xff0c;但最终只有一个报告需要被我们使用。 但在此之前的…...

ubuntu下配置vscode生成c_cpp_properties.json

-------------学习记录--------------- 在ubuntu下使用vscode时发现cpp文件无法读到头文件&#xff0c;明明头文件在合适的路径下&#xff0c;由于没有制定头文件的路径造成的这个问题。用这篇文章进行简单记录解决方法 ctrlshiftp打开命令面板&#xff0c;也可以点击左上角, …...

Qt读取Excel文件的技术实现与最佳实践

目录 一、成果展示二、核心方法及原理1. QAxObject&#xff08;基于COM接口&#xff09;2. 第三方库QXlsx3. ODBC数据库驱动 三、实现步骤详解1. QAxObject读取Excel&#xff08;需安装Excel/WPS&#xff09;2. QXlsx读取Excel&#xff08;跨平台方案&#xff09; 四、技术选型…...

双条件拆分工作表,一键生成独立工作簿-Excel易用宝

你是否遇到过这样的崩溃瞬间&#xff1f;面对一张密密麻麻的销售数据表&#xff0c;需要按指定维度拆分成工作簿和工作表&#xff0c;而你却只能手动复制粘贴到不同工作簿、工作表&#xff0c;改一个字段就花半小时&#xff0c;数据量大时甚至要熬夜加班&#xff1f; 别担心&a…...

iOS 蓝牙开发中的 BT 与 BLE

在 iOS 开发者的语境里,大家把 BT 和 BLE 当成两种不同的蓝牙技术在谈——它们来自同一个 Bluetooth 规范,但面向的场景、协议栈乃至 Apple 提供的 API 都截然不同。 缩写全称 / 技术名称规范层叫法iOS 支持现状典型用途BTBluetooth Classic(经典蓝牙)又叫 BR/EDR(Basic R…...

TCP和套接字SSL加密连接行为分析

目录 一、前言 二、背景 三、参数介绍 3.1、 have_openssl 3.2、have_ssl 3.3、require_secure_transport 四、--ssl-modemode 五、CREATE USER SSL/TLS选项 六、问题验证 6.1、使用套接字连接 6.2、使用TCP连接 七、分析与总结 一、前言 SSL&#xff08;Secure S…...

kafka 问与答

kafka Q&A How does the client connect to kafka and discovery the brokers. client 只需要知道一部分nodes(brokers)的地址既可以&#xff0c;client 会自动发现剩下的所有topic partition leader nodes, 然后连接上。 When a client connects:It uses the bootstrap…...

docker默认存储迁移

在容器化场景下默认存储路径为&#xff08;/var/lib/docker&#xff09;大多数平台根目录不支持系统盘扩容&#xff0c;会有空间不足风险隐患&#xff0c;因未配置持久化存储导致容器数据丢失。以迁移Docker存储路径至大容量/data目录说明 一、停止容器 systemctl stop docke…...

Ubuntu20.04系统下使用交叉编译工具链(aarch、x86)交叉编译opencv4.5.0

文章目录 0. 引言1. 准备交叉编译工具链2. 安装依赖工具3. 下载 OpenCV 源码4. 创建交叉编译工具链文件5. 配置 CMake 构建6. 构建 OpenCV7. 安装 OpenCV8. 验证9. 问题及解决办法 0. 引言 Ubuntu20.04系统下使用交叉编译工具链&#xff08;aarch、x86&#xff09;交叉编译ope…...

R语言数据可视化

R note book 文档–输出html格式文档&#xff0c;plotly不能生成PDF文件 --- title: "R语言数据可视化" output: html_notebook ---在R语言中进行数据可视化是数据分析和呈现的重要环节&#xff0c;R提供了多种强大的绘图系统和工具。以下是常见的数据可视化方法和示…...

NLP学习路线图(一): 线性代数(矩阵运算、特征值分解等)

引言&#xff1a;语言与矩阵的奇妙邂逅 在自然语言处理&#xff08;NLP&#xff09;的魔法世界里&#xff0c;每个词语都像被施了变形术的精灵&#xff0c;在数学的殿堂中翩翩起舞。当我们用"king - man woman queen"这样的向量魔法破解语义密码时&#xff0c;线性…...

【滑动窗口】LeetCode 1004题解 | 最大连续1的个数 Ⅲ

最大连续1的个数 Ⅲ 一、题目链接二、题目三、题目解析四、算法原理解法一&#xff1a;暴力枚举 zero计数器解法二&#xff1a;滑动窗口 五、编写代码六、时空复杂度 一、题目链接 最大连续1的个数 Ⅲ 二、题目 三、题目解析 注意题目中说的是最多k次&#xff0c;在一个数组…...

Linux 内核等待机制详解:prepare_to_wait_exclusive 与 TASK_INTERRUPTIBLE

1. prepare_to_wait_exclusive 函数解析 1.1 核心作用 prepare_to_wait_exclusive 是 Linux 内核中用于将进程以独占方式加入等待队列的关键函数,其主要功能包括: 标记独占等待:通过设置 WQ_FLAG_EXCLUSIVE 标志,表明此等待条目是独占的。 安全入队:在自旋锁保护下,将条…...

分布式数据库TiDB:深度解析原理、优化与架构设计

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【星海网址导航】 一、TiDB架构设计与核心原理 1.1 分布式架构演进 传统分库分表 vs TiDB架构 #mermaid-svg-8I88Hg2AVkzYTb3O {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fi…...

【深度学习基础】损失函数与优化算法详解:从理论到实践

【深度学习基础】损失函数与优化算法详解&#xff1a;从理论到实践 一、引言 1. 损失函数与优化算法在深度学习中的核心作用 在深度学习中&#xff0c;模型训练的本质是通过不断调整参数&#xff0c;使模型输出尽可能接近真实值。这一过程的核心驱动力是损失函数&#xff08;…...

睿抗足球机器人

目录 大框架 战术 Lua脚本语言编辑环境 大框架 策略脚本&#xff08;LUA-官方脚本&#xff09;、决策算法&#xff08;C-自定义&#xff09;、ROS系统 战术 我们研究了场地的长度、宽度、禁区范围、机器人运动速度等等&#xff0c;发现即使 Kicker 点球往极端角度踢&#xf…...

助力DBA技能无缝平迁 | YashanDB携最新成果亮相XCOPS智能运维管理人年会

5 月 16 日&#xff0c;由上海市软件行业协会、上海市计算机行业协会指导&#xff0c; dbaplus社群主办的XCOPS智能运维管理人年会在广州盛大召开&#xff0c;活动汇聚500余名金融、政府、能源、教育、电信、交通等领域的行业专家。深算院崖山数据库受邀参会&#xff0c;系统性…...

服务端安全测试:OWASP ZAP使用

ZAP下载地址:https://www.zaproxy.org/download/ ZAP有两种扫描方式: 1、使用 OpenAPI / Swagger 地址进行扫描 2、ZAP Proxy + Postman 因为业务云没有添加swagger插件所以本次介绍第2种方式。 【第一步】设置 ZAP 的代理端口(默认是 127.0.0.1:8080) 成功安装并打…...

Amazon Q 从入门到精通 – 测试与重构

Amazon Q Developer 是亚马逊推出的一个专为专业开发人员设计的人工智能助手&#xff0c;旨在提升代码开发和管理效率。其主要功能包括代码生成、调试、故障排除和安全漏洞扫描&#xff0c;提供一站式代码服务。 众所周知&#xff0c;在软件开发领域&#xff0c;测试代码是软件…...

[CSS3]属性增强2

空间转换 使用transform属性实现元素在空间内的位移、旋转、缩放等效果 空间: 是从坐标轴角度定义的。x、y 和z三条坐标轴构成了一个立体空间&#xff0c;z轴位置与视线方向相同。空间转换也叫3D转换 空间位移 使用translate实现元素空间位移效果 transform: translate3d(x…...

Go 语言 vs C+Lua(Skynet)游戏服务器方案对比分析

为啥挑这两个呢&#xff1f;因为两种技术分别对应CSP模型和Actor模型&#xff0c;都是经过时间检验的成熟且可靠的并发模型&#xff0c;问了很多地方&#xff0c;经过gpt整理得出如下报告。 从开发效率、运行性能、热更新扩展、云部署与水平扩展能力、多类型游戏支持等五个维度…...

ArcGIS Pro 3.4 二次开发 - 内容

环境&#xff1a;ArcGIS Pro SDK 3.4 .NET 8 文章目录 内容1 工程1.1 创建一个空工程1.2 使用指定名称创建新工程1.3 使用Pro的默认设置创建新工程1.4 使用自定义模板文件创建新工程1.5 使用 ArcGIS Pro 提供的模板创建工程1.6 打开现有工程1.7 获取当前工程1.8 获取当前工程的…...

java每日精进 5.19【Excel 导入导出】

基于 EasyExcel 实现 Excel 的读写操作&#xff0c;可用于实现最常见的 Excel 导入导出等功能。 Excel 导入导出功能涉及前后端协作&#xff0c;后端处理数据查询、文件生成和解析&#xff0c;前端提供用户交互和文件下载/上传界面。以下是全流程解析&#xff0c;分为导出流程…...

基于Elasticsearch的搜索引擎简介

## 一、Elasticsearch简介 Elasticsearch&#xff08;简称ES&#xff09;是一个开源的、分布式、RESTful风格的搜索和数据分析引擎&#xff0c;基于Apache Lucene开发。它能够实现对海量结构化和非结构化数据的实时存储、搜索和分析&#xff0c;广泛应用于全文检索、日志分析、…...

不同类型桥梁的无人机检测内容及技术难度

不同类型桥梁的无人机检测内容及技术难度 无人机桥梁检测的难度因桥梁类型、结构特点和所处环境的不同而存在显著差异。以下是针对梁桥、拱桥、斜拉桥、悬索桥等主要桥梁类型的无人机检测难度分析&#xff1a; 1. 梁桥&#xff08;简支梁、连续梁&#xff09; 检测难度&#x…...

数据结构实验10.1:内部排序的基本运算

文章目录 一&#xff0c;实验目的二&#xff0c;实验内容1. 数据生成与初始化2. 排序算法实现&#xff08;1&#xff09;直接插入排序&#xff08;2&#xff09;二分插入排序&#xff08;3&#xff09;希尔排序&#xff08;4&#xff09;冒泡排序&#xff08;5&#xff09;快速…...

java20

1.List集合 2.数据结构之栈&#xff0c;队列&#xff0c;数组&#xff0c;链表 3.ArrayList集合 4.LinkedList 5.泛型 注意&#xff1a;E...e是指若干个变量...

LLM笔记(九)KV缓存(2)

文章目录 1. 背景与动机2. 不使用 KV Cache 的情形2.1 矩阵形式展开2.2 计算复杂度 3. 使用 KV Cache 的优化3.1 核心思想3.2 矩阵形式展开3.3 计算复杂度对比 4. 总结5. GPT-2 中 KV 缓存的实现分析5.1 缓存的数据结构与类型5.2 在注意力机制 (GPT2Attention) 中使用缓存5.3 缓…...

将 Element UI 表格拖动功能提取为公共方法

为了在多个页面复用表格拖动功能&#xff0c;我们可以将其封装成以下两种形式的公共方法&#xff1a; 方案一&#xff1a;封装为 Vue 指令&#xff08;推荐&#xff09; 1. 创建指令文件 src/directives/tableDrag.js import interact from interactjs;export default {inse…...

项目中把webpack 打包改为vite 打包

项目痛点: 老vu e-cli1创建的项目,项目是ERP系统集成了很多很多管理,本地运行调试的时候,每次修改代码都需要等待3分钟左右的编译时间,严重影响开发效率. 解决方案: 采用vite构建项目工程 方案执行 第一步 使用vite脚手架构件一个项目,然后把build文件自定义的编译逻辑般到…...

Vue3 Element Plus 中el-table-column索引使用问题

在 Element Plus 的 el-table 组件中&#xff0c;使用 scope.index 是不准确的。正确的索引属性应该是 scope.$index。你的代码需要调整为&#xff1a; vue 复制 下载 <el-button type"primary" size"default" text click"onModifyClick(scope…...

盲盒一番赏小程序系统发展:创新玩法激发市场活力

盲盒一番赏小程序系统凭借其创新的玩法&#xff0c;在潮玩市场中脱颖而出&#xff0c;激发了市场的无限活力。它不仅保留了传统一番赏百分百中奖的特点&#xff0c;还结合线上平台的优势&#xff0c;开发出了更多新颖的玩法。 例如&#xff0c;小程序系统设置了赏品回收功能。…...

MySQL故障排查

目录 MySQL 单示例故障排查 故障现象一​ 故障现象二 故障现象三 故障现象四 故障现象五 故障现象六 故障现象七 故障现象八 MySQL主从复制排查 故障现象一 故障现象二 故障现象三 MySQL 优化 硬件方面 关于CPU 关于内存 关于磁盘 MySQL配置文件 核…...

微服务项目->在线oj系统(Java版 - 4)

相信自己,终会成功 目录 B端用户管理 C端用户代码 发送验证码: 验证验证码 退出登录 登录用户信息功能 用户详情与用户编辑 用户竞赛接口 用户报名竞赛 用户竞赛报名接口查询 用户信息列表 ThreadLocalUtil Hutool工具库 常用功能介绍 B端用户管理 进行列表显示与…...

DDoS与CC攻击:谁才是服务器的终极威胁?

在网络安全领域&#xff0c;DDoS&#xff08;分布式拒绝服务&#xff09;与CC&#xff08;Challenge Collapsar&#xff09;攻击是两种最常见的拒绝服务攻击方式。它们的目标都是通过消耗服务器资源&#xff0c;导致服务不可用&#xff0c;但攻击方式、威胁程度和防御策略存在显…...

旧物回收小程序,一键解决旧物处理难题

在快节奏的现代生活中&#xff0c;我们常常会面临旧物处理的困扰。扔掉觉得可惜&#xff0c;留着又占空间&#xff0c;而且处理起来还十分麻烦。别担心&#xff0c;我们的旧物回收小程序来啦&#xff0c;只需一键&#xff0c;就能轻松解决你的旧物处理难题&#xff01; 这款小…...

uniapp小程序获取手机设备安全距离

utils.js let systemInfo null;export const getSystemInfo () > {if (!systemInfo) {systemInfo uni.getSystemInfoSync();// 补充安全区域默认值systemInfo.safeAreaInsets systemInfo.safeAreaInsets || {top: 0,bottom: 0,left: 0,right: 0};// 确保statusBarHei…...

小程序弹出层/抽屉封装 (抖音小程序)

最近忙于开发抖音小程序&#xff0c;最想吐槽的就是&#xff0c;既没有适配的UI框架&#xff0c;百度上还找不到关于抖音小程序的案列&#xff0c;我真的很裂开啊&#xff0c;于是我通过大模型封装了一套代码 效果如下 介绍 可以看到 这个弹出层是支持关闭和标题显示的&#xf…...

map与set封装

封装map和set一般分为6步&#xff1a; 1.封装map与set 2.普通迭代器 3.const 迭代器 4.insert返回值处理 5.map operator【】 6.key不能修改的问题 一.红黑树的改造 map与set的底层是通过红黑树来封装的&#xff0c;但是map与set的结点储存的值不一样&#xff0c;set只需要存…...

【C语言基础语法入门】通过简单实例快速掌握C语言核心概念

文章目录 1. Hello World&#xff1a;第一个C程序2. 变量与数据类型3. 运算符4. 控制结构4.1 if-else 条件判断4.2 for 循环4.3 while 循环 5. 函数6. 数组7. 指针8. 结构体总结 &#x1f4e3;按照国际惯例&#xff0c;首先声明&#xff1a;本文只是我自己学习的理解&#xff0…...

Manus AI 突破多语言手写识别技术壁垒:创新架构、算法与应用解析

在人工智能领域&#xff0c;手写识别技术作为连接人类自然书写与数字世界的桥梁&#xff0c;一直备受关注。然而&#xff0c;多语言手写识别面临诸多技术挑战&#xff0c;如语言多样性、书写风格差异、数据稀缺性等。Manus AI 作为该领域的领军者&#xff0c;通过一系列创新技术…...

数字图像处理——图像压缩

背景 图像压缩是一种减少图像文件大小的技术&#xff0c;旨在在保持视觉质量的同时降低存储和传输成本。随着数字图像的广泛应用&#xff0c;图像压缩在多个领域如互联网、移动通信、医学影像和卫星图像处理中变得至关重要。 技术总览 当下图像压缩JPEG几乎一统天下&#xff…...

SGLang和vllm比有什么优势?

环境&#xff1a; SGLang vllm 问题描述&#xff1a; SGLang和vllm比有什么优势&#xff1f; 解决方案&#xff1a; SGLang和vLLM都是在大语言模型&#xff08;LLM&#xff09;推理和部署领域的开源项目或框架&#xff0c;它们各自有不同的设计目标和优势。下面我综合目前…...

BeanFactory和FactoryBean的区别

目录 1、Spring-core 2、控制反转&#xff08;IoC&#xff09; 2.1、定义 2.2、实现方式 1、BeanFactory 2、ApplicationContext 3、FactoryBean BeanFactory是容器&#xff0c;管理所有Bean(包括FactoryBean)&#xff0c;FactoryBean是被管理的Bean&#xff0c;只是它有…...

仓颉开发语言入门教程:搭建开发环境

仓颉开发语言作为华为为鸿蒙系统自研的开发语言&#xff0c;虽然才发布不久&#xff0c;但是它承担着极其重要的历史使命。作为鸿蒙开发者&#xff0c;掌握仓颉开发语言将成为不可或缺的技能&#xff0c;今天我们从零开始&#xff0c;为大家分享仓颉语言的开发教程&#xff0c;…...

火花生态【算力通】公测,助力全球闲置算力训练AI模型

近日,在数字化浪潮迅猛推进的大背景下,人工智能模型训练对算力的需求呈井喷式增长,而全球范围内大量算力资源却处于闲置状态,如何高效整合这些闲置算力,成为推动行业发展的关键命题。在此关键时刻,火花生态旗下的核心产品【算力通】(ComputePower)于 2025 年 5 月 10 日正式开启…...

OpenMV IDE 的图像接收缓冲区原理

OpenMV IDE 的图像接收缓冲区原理与 嵌入式图像处理系统 的数据流控制密切相关。以下是其核心工作原理的分步解析&#xff1a; 一、图像缓冲区架构 OpenMV 的整个图像处理流程基于 双缓冲&#xff08;Double Buffering&#xff09;机制&#xff0c;主要分为以下层级&#xff1…...

如何在LVGL之外的线程更新UI内容

前言 作为一个刚开始学习LVGL和嵌入式开发的新手&#xff0c;学会绘制一个界面之后&#xff0c;遇到了一个问题&#xff1a;在LVGL线程之外的线程&#xff0c;更新UI内容时&#xff0c;会导致程序崩溃。 1、问题分析 首先&#xff0c;需要了解LVGL的基本工作原理。LVGL&#…...

实景VR展厅制作流程与众趣科技实景VR展厅应用

实景VR展厅制作是一种利用虚拟现实技术将现实世界中的展览空间数字化并在线上重现的技术。 这种技术通过三维重建和扫描等手段&#xff0c;将线下展馆的场景、展品和信息以三维形式搬到云端数字空间&#xff0c;从而实现更加直观、立体的展示效果。在制作过程中&#xff0c;首…...

Regmap子系统之六轴传感器驱动-编写icm20607.c驱动

&#xff08;一&#xff09;在驱动中要操作很多芯片相关的寄存器&#xff0c;所以需要先新建一个icm20607.h的头文件&#xff0c;用来定义相关寄存器值。 #ifndef ICM20607_H #define ICM20607_H /*************************************************************** 文件名 : i…...