版本管理git及其命令介绍-附带详细操作

前言

在版本管理时代之前,人们写软件的方式如下图1所示
在这里插入图片描述
图1 无版本管理的代码

其坏处就是软件版本随着时间越来越多,每个版本修改了什么内容,修改了哪些文件,如果没有详细记录也不知道。这样久会导致如果我们想回退到某个版本内容的时候就无法做到。git的出现就时为了解决这些问题的。在git出现之前,其实还有比较出名的SVN,当然SVN现在也有很多公司在用。

SVN与git的区别:SVN是集中式的管理方式,即就服务器一个仓库,git是分布式的管理方式,除了服务器仓库,本地也有一个仓库。而且这个本地仓库也可以与其他用户交互。当然本地仓库也可以与中央服务器交互。

版本管理的好处主要有以下几个方面

  • 版本管理有一个中央服务器,可以保存所有代码、文档
  • 每一次的修改都可以提交到版本库,修改有记录,可追踪
  • 不害怕某个同事离职了,代码没有入库
  • 本地的代码流失后,可以从版本库检出
  • 多人协作,每个同事完成的工作提交到版本库,方便进行集成
  • 当我们要开发需求或修复PR时,可以从版本库上拉出分支管理
  • 如果构建失败了,可以自动revert掉某次提交
  • 在大的企业,每次提交都可能触发一次构建,实时检查代码的质量

git原理

git区域

git主要有4个区域,如下图2所示
在这里插入图片描述
图2 git区域

  • 工作区,就是你平时存放项目代码的地方
  • Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
  • Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
  • Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
    引入Index/Stage的目的时因为我们可能经常的操作有些误操作,会将一些文件的记录就保存到了Repository,不过其实没有Index/Stage也是可以的,因为提交给Repository也可以回滚,如果有SVN的使用经验,Index/Stage就类似于SVN的选择要提交文件的页面。

工作流程

工作流程如下图在这里插入图片描述
图3 git工作流程

1、在工作目录中添加、修改文件;
2、将需要进行版本管理的文件add到暂存区域;
3、将暂存区域的文件commit到git仓库;
4、本地的修改push到远程仓库,如果失败则执行第55、git pull将远程仓库的修改拉取到本地,如果有冲突需要修改冲突。回到第三步
因此,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)

文件四种状态

在这里插入图片描述
图4 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 操作

我们以windows 版本来演示git的操作,linux下命令一致。

配置git

当安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址。 这样做很重要,因为每一个 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改,使用这些信息是为了别人可以看到这次提交是由什么人提交,这样就可以直接找到相应的人。使用如下命令配置用户名和邮箱

 git config --global user.name “liqiang” 
 配置用户名
 
 git config --global user.email 552191868@qq.com
 配置邮箱
 
 git config -l  
 查看配置信息

在这里插入图片描述
图5 git 配置

常用命令

git init

安装git之后,我们在D盘的git目录下创建3个目录,远程仓库remote,和2个本地仓库(local-a,local-b).,我们先进入remote目录,然后右键Git Bash Here,创建一个远程的仓库。使用命令git init 创建 或者 git init --bare创建。使用git init 创建的仓库可以存储具体的代码,使用git init --bare创建的仓库不存储具体的代码,一般在远程服务器创建为裸仓库即可。创建远程仓库之后如下图6所示
在这里插入图片描述
图 6 创建远程服务器裸仓库

git clone

git clone 命令用于从远程服务器仓库拷贝到本地,并且后续可以通过在本地添加文件之后,并上传到服务器。进入到local-a目录,然后使用git clone命令从remote目录中拷贝文件如图7所示,同理,进入到local-b目录,使用git clone 将远程目录拷贝到本地。
在这里插入图片描述
图7 使用git clone将远程仓库拷贝到本地

git status

git status可以查看当前仓库文件的各自状态,在下面命令中进行说明。

git log

git log可以查看提交的版本信息,本地仓库的版本,远程仓库的版本等信息,在后续的命令中进行讲解。

git add

git add 是将工作区的代码提交给暂存区

git add . :将当前文件夹下的所有添加或者更新文件都一并提交

我们在本地目录local-a中添加一个main.c源文件,并添加一行内容。随后保存,然后使用git add . 将工作区的main.c提交给暂存区,并使用git status 查看文件状态 如图8所示
在这里插入图片描述
图8 git add将文件添加到暂存区,并使用git status查看状态

git commit

git commit 将暂存区提交给本地仓库

git commit main.c -m “first commit” 
将main.c文件提交给本地仓库,提交的日志信息为first commit

我们使用上述命令将暂存区的main.c提交到本地仓库,并使用git log查看当前的提交信息。如图9 所示.
在这里插入图片描述
图9 使用git commit提交和git log查看状态
我们对git log命令中的一些信息进行说明如下:
HEAD:本地仓库当前最新的提交指针
master:当前提交的分支(后续会说明分支的作用)
Author:里面包含用户名和邮箱信息(在git config中已经进行了描述)
Date:本次的提交时间
提交的信息:如first commit就是本次提交的日志信息
Hash字符串(40位):每次提交都使用hash算法生成的唯一 字符串,用来唯一描述某次提交。可以使用前面几位来描述某次提交。

git push

使用git add和git commit之后,代码已存储到本地仓库,但是其他用户却不能查看到最新的代码信息,使用git push命令,可以将代码推送到远程服务器。使用如下命令

git push origin master: 其中origin代表远程仓库的简写,master代表要提交本地仓库的master分支到远程仓库。

在这里插入图片描述
图10 推送代码到远程服务器
对于图10来说,使用git log 可以看到这次的日志信息比上次多了 origin/master,其实这是在本地查看到远程服务器的状态信息,这里HEAD->master,origin/master在同一行里,说明远程服务器和本地仓库的版本状态是一样的。通常如果进行了多次git commit,而没有git push到远程仓库,那么就会发现HEAD->master一般是提前于origin/master的,origin/master表示远程仓库也是使用的master分支。

git pull

可以使用git pull从远程服务器拉取代码,在我们的例子中,repo-a的代码已经更新到远程仓库中,如果repo-b想从远程服务器中获取到最新代码,使用git pull即可。
在这里插入图片描述
图11 从远程服务器拉取代码

git reflog

不像git log那样,git reflog不会显示那么完整的信息,但是使用git reflog会将自己每次提交的日志记录都记录下来了,即使使用git命令将提交信息进行了合并(后续会讲到),图12显示了git reflog的使用。
在这里插入图片描述
图12 git reflog的使用

有时候我们需要我们提交日志的内容,比如想把前几次的内容进行合并位一次提交,或者将值卡提交的版本删除,主要就是为了更容易阅读每次提交版本所做的工作。主要有git commit --amend 和git rebase命令

git commit --amend

可以修改提交记录,让提交版本的log更好看,比如我们之前提交的日志不足以说明提交的信息情况,如果想修改,则可以使用这条命令,提前可以使用git log查看日志状态,修改过后(vim修改,会vim操作就可以),然后再次使用git log就可以查看日志已经修改。
git commit --amend还可以将这次源文件修改之后和上次进行合并,既是说这次修改代码之后,不需要提交版本。我们将local-a的代码在提交1次,最终的状态如下所图13所示。
在这里插入图片描述
图13 提交2次记录到本地服务器

我们使用 git commit --amend命令之后,如图14所示
在这里插入图片描述
图14 git commit --amend
使用vim将second commit 2 修改为second commit ,然后保存,再次使用git log,就可以看到上次提交的日志信息已经被修改为second commit,但是使用git reflog命令却显示了3次修改。如图15所示
在这里插入图片描述
图15 显示git commit --amend修改后的日志情况

git rebase

使用git commit --amend只能对最近一次的日志进行修改,如果相对多次提交记录进行修改,需要使用git rebase 命令,get rebase操作是在操作本地仓库,用于将多次日志进行合并,git rebase -i 开始hash值,结束hash值也可以使用git rebase -i,如果不带hash值, 那么就是默认从最新版本到没有提交到远程服务器之前的办吧 。在修改之前,提交版本如图16所示
在这里插入图片描述
图16 提交了4次版本的本地仓库
如图16所示,我们使用git log可以看到有4次提交版本到本地仓库,但是只有第一次提交到远程服务器,如果我们使用git rebase -i 命令,会出现如图17所示。
在这里插入图片描述
图17 git rebase -i整理界面
git rebase 有很多命令可供操作(如注释说明),以下做个简单的说明
pick ( p ): 使用该条提交,不进行任何修改,比如我们这里退出vim,不进行任何修改,那么相当做不对任何操作。
r: 使用r命令修改第三次提交和第4次提交的日志,但是不修改提交的内容,这个命令的作用就是用于让别人更容易看懂每次提交代码的作用,有时候我们提交过后,才发现日志对本次代码的用途说明的不是很清楚,我们就可以使用这个命令。如图18所示
在这里插入图片描述
图 18 使用r命令修改第3次和第4次提交日志
然后保存vim会自动提出修改第3次和第4次的日志信息,保存为我们想修改的日志信息即可。然后使用git log查看,如图19所示。
在这里插入图片描述
图19 所用 git rebase的r命令修改提交的日志
e: e命令不仅会修改提交的日志,还会记录提交时的代码状态,比如我们使用e修改第4次提交的内容,如图20所示
在这里插入图片描述
图20 使用e命令修改日志和代码
然后在图20使用wq保存vim之后,出现如图21所示
在这里插入图片描述
图21 e命令修改之前的提示
图21说明了e命令可以对代码进行修改,并且git会记录这次提交之前的源文件的状态,修改代码之后,在使用git commit --amend 修改本次要提交的日志,然后使用git rebase --continue完成本次提交的修改,但是如果需要一次性修改多条提交,需要重复多次,以便完成所有的修改操作。
对于git rebase的其他命令,如果有兴趣,请自行查阅相关资料,这里就不过多说明了。

有时候,我们需要进行git的逆向操作,即将暂存区的内容回退到工作区,或者将本地服务器的版本回退到上一个版本等等。

git restore

使用git restore -S . 命令将暂存区的内容回滚到工作区,如图22所示
在这里插入图片描述
图22 暂存区回滚到工作区

git reset

我们使用local-b仓库来讲解,我们将local-a仓库的所有更新到服务器(git push origin master),然后在local-b使用git pull像远程服务器拷贝最新的内容,初始状态如图23所示。
在这里插入图片描述
图23 ,local-b的初始状态

我们将main.c的内容删除3行,保留hello world和return 0 2行内容。然后使用git add 和git commit 将内容提交到本地服务器,使用git reflog命令,然后查看main.c和状态如图24所示
在这里插入图片描述
图24 ,使用 git reset之前的状态
git reset --hard head~1该命令直接硬件回滚到HEAD~1(79983ed), 把上次提交(head~0)的内容直接给抹掉,就好像从来没有提交过一样。即没有在服务器上有过记录。
我们查看main.c和使用git log查看状态,就好像前面所做的操作没有一样,如图25所示
在这里插入图片描述
图25 硬件回滚到前一个版本

git reset --soft head~1:回退到index暂存区,将内容回到HEAD 1版本,使用git status可以看到main.c的内容还没有提交到本地服务器,如图26所示
在这里插入图片描述
图26 ,回退到暂存区
git reset head~1的全写是:git reset --mixed head~1 ,这里是直接退到workspace了。内容没有提交到服务器,但是本地workspace还是存在最近一次提交的内容。

解决冲突

在日常开发中,难免会遇到多个开发者同时修改同一个文件,而且修改文件的同一个地方,那么就不可避免的出现冲突,我们这里先说明冲突的git状态,然后在说明如何解决冲突。
有2个本地仓库,其中一个本地仓库修改源文件之后提交给服务器(git push),另一个本地仓库去下载(git pull),并修改了其中一个文件,并提交到本地(git commit),然后提交到服务器(git push).第一个本地仓库也去修改源文件,并提交到暂存区(index),然后去git commit到本地仓库。然后使用git pull拉取服务器上的文件操作,就会发生冲突(修改了同一个源文件导致)。
首先我们将local-a的main.c代码更新到远程服务器(git push),随后local-b去拉取代码(git pull),然后local-a和local-b同时去更新main.c,然后local-a提交到服务器(git push),local-b提交到本地服务器,然后使用git pull去拉取到本地,这时候就出现冲突了,如图27所示
在这里插入图片描述
图27,local-b出现冲突
使用vim打开main.c,如图28所示,然后并修改如图29之后,提交就能解决冲突。
在这里插入图片描述
图28,冲突版本的代码

图28 ,冲突信息,<<<<<<<<< HEAD 到=============是自己本地修改的信息,============到>>>>>>>>> 3e4d20…是远程服务器的版本信息,然后我们想让远程的自己的代码一起使用,我们保留这2份代码即可。
在这里插入图片描述
图29 修改后的代码
然后修改完成后,按照正常操作即可。

标准工作流程

git 分支

在企业开发中,不可能只在一个分支上进行开发,比如前面提到的master分支。在说明工程流程之前,先说下一般有哪些分支,分支如图30所示
在这里插入图片描述
图30 企业git分支情况

master:主分支,通常用于线上版本
hotfix:热更新版本,可以线上更新的版本
release:开发完成之后,并测试通过之后,积极发布的版本
develop:开发分支版本,一般由主程进行管理
feature:功能模块版本
bug:存在bug的版本分支

查看分支

git branch:用于查看当前处于什么分支,不过一般不需要,因为在命令中就已经显示了当前处于什么分支

创建和切换分支

一般刚建的仓库仅仅只有master分支,我们创建develop分支:git branch develop,并且切换到develop分支,如图31所示。
在这里插入图片描述
图31 创建和切换分支

切换到develop分支之后,在打开main.c,发现里面的内容和master分支一致。然后我们修改main.c的部分内容。并git add ,git commit ,并git push 到服务器,然后我们切换到master分支,会发现develop修改的内容并没有更新到master分支,这就是说,master分支一般作为稳定的线上版本,develop修改的内容不会影响到master分支。
git checkout -b bug/timer: 首选切换到bug/timer,-b参数表示如果没有bug/timer分支,则先创建该分支。

合并分支

前面提到,develop用于开发版本,修改的内容不会及时更新到master分支,但是我们确实想将develop分支的内容更新到master分支该怎么办呢,那么使用git merge develop将develop分支合并到master分支(要保证当前处于master分支)

正常流程

通常主程会生成一个develop分支,然后弄创建一些功能模块和BUG的分支,交由不同的人员去开发,开发完成之后,检查功能模块和BUG分支是否合格,如果合格,就将其合并到develop分支,有时候我们需要查看当前有哪些分支,可以使用 git branch --all ,还有很多关于分支的命令,如下所示
在这里插入图片描述

git帮助

git --help:会线上帮助命令,假如我们想知道git branch 支持的参数,可以使用git branch --然后按tab键就可以知道git branch的所有支持的参数。

.gitignore

有时候我们不想提交一些文件,那么可以将这些忽略的文件列表写入到这个文件中,比如我们想忽略所有的exe文件,我们可以在文件里面写 *.exe即可。

总结

本文说了git的一些常见用法,基本上这些命令能解决工作上的大多数问题,如果想更加深入的学习git,需要自行参考git语法。这里就不说了,希望本文能够帮助初学git的人有一个帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/367324.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLM(3) | 自注意力机制 (self-attention mechanisms)

LLM(3) | 自注意力机制 (self-attention mechanisms) self-attention 是 transformer 的基础&#xff0c; 而 LLMs 大语言模型也都是 transformer 模型&#xff0c; 理解 self-attention, 才能理解为什么 LLM 能够处理好上下文关联性。 本篇是对于 Must-Read Starter Guide t…

Java学习day26:和线程相关的Object类的方法、等待线程和唤醒线程(知识点详解)

声明&#xff1a;该专栏本人重新过一遍java知识点时候的笔记汇总&#xff0c;主要是每天的知识点题解&#xff0c;算是让自己巩固复习&#xff0c;也希望能给初学的朋友们一点帮助&#xff0c;大佬们不喜勿喷(抱拳了老铁&#xff01;) 往期回顾 Java学习day25&#xff1a;守护线…

(十二)常见Linux命令——磁盘分区、进程线程、系统定时任务

文章目录 1、磁盘分区类命令1.1、df (disk free 空余硬盘)查看磁盘空间使用情况1.2、fdisk 查看分区1.3、mount/umount 挂载/卸载 2、进程线程类命令2.1、ps (process status 进程状态)查看当前系统进程状态2.2、kill终止进程 3、系统定时任务命令3.1、crond服务管理3.2、cront…

使用ngrok内网穿透

没有服务器和公网IP&#xff0c;想要其他人访问自己做好的网站&#xff0c;使用这款简单免费的内网穿透小工具——ngrok&#xff0c;有了它轻松让别人访问你的项目~ 一、下载ngrok 官网地址&#xff1a;ngrok | Unified Application Delivery Platform for Developers&#x…

前端开发者应该知道的TypeScript可区分联合

作为一个前端开发者&#xff0c;你的工作不仅仅是移动像素&#xff0c;前端的大部分复杂性来自于处理你的应用程序可能处于的所有不同状态。 它可能是加载数据&#xff0c;等待表单被填写&#xff0c;或者发送一个遥测事件 - 或者同时进行这三项。 如果不能正确处理状态&…

【PostgreSQL内核学习(二十五) —— (DBMS存储空间管理)】

DBMS存储空间管理 概述块&#xff08;或页面&#xff09;PageHeaderData 结构体HeapTupleHeaderData 结构 表空间表空间的作用&#xff1a;表空间和数据库关系表空间执行案例 补充 —— 模式&#xff08;Schema&#xff09; 声明&#xff1a;本文的部分内容参考了他人的文章。在…

深度学习入门笔记(七)卷积神经网络CNN

我们先来总结一下人类识别物体的方法: 定位。这一步对于人眼来说是一个很自然的过程,因为当你去识别图标的时候,你就已经把你的目光放在了图标上。虽然这个行为不是很难,但是很重要。看线条。有没有文字,形状是方的圆的,还是长的短的等等。看细节。纹理、颜色、方向等。卷…

C++学习Day01之namespace命名空间

目录 一、程序及输出1.1 命名空间用途&#xff1a; 解决名称冲突1.2 命名空间内容1.3 命名空间必须要声明在全局作用域下1.4 命名空间可以嵌套命名空间1.5 命名空间开放&#xff0c;可以随时给命名空间添加新的成员1.6 命名空间可以是匿名的1.7 命名空间可以起别名 二、分析与总…

洛谷 P1980 [NOIP2013 普及组] 计数问题

题目背景 NOIP2013 普及组 T1 题目描述 试计算在区间 1 到 n 的所有整数中&#xff0c;数字 x&#xff08;0≤x≤9&#xff09;共出现了多少次&#xff1f;例如&#xff0c;在 1 到 11 中&#xff0c;即在 1,2,3,4,5,6,7,8,9,10,11 中&#xff0c;数字 1 出现了 4 次。 输入…

基于Java SSM框架实现校园快领服务系统项目【项目源码+论文说明】

基于java的SSM框架实现校园快领服务系统演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于校园快领服务系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了…

Electron+Vue3+Vite的产品级模板项目

1. electron-vue3-template 基于Vue3 Electron TypeScript的客户端程序模板&#xff0c;使用Vite和Electron Forge构建和打包。 真正做到开箱即用&#xff0c;面向跨平台客户端设计&#xff0c;产品级的项目模板。 项目地址&#xff1a; https://github.com/winsoft666/el…

Golang `crypto/hmac` 实战指南:代码示例与最佳实践

Golang crypto/hmac 实战指南&#xff1a;代码示例与最佳实践 引言HMAC 的基础知识1. HMAC 的工作原理2. HMAC 的应用场景 Golang crypto/hmac 库概览1. 导入和基本用法2. HMAC 的生成和验证3. crypto/hmac 的特性 实战代码示例示例 1: 基本的 HMAC 生成示例 2: 验证消息完整性…

C++通用编程(2)

函数模板高级用法 1.分文件编写的优点2.普通函数的分文件编写3.函数模板的分文件编写4.细节提示5.函数模板应用高级decltype推导类型函数后置返回类型 6.总结 函数模板讲完后&#xff0c;C全部的函数类型我们就接触的差不多了。今天给做一些关于函数份文件编写的知识点补充。 1…

C语言问题汇总

指针 #include <stdio.h>int main(void){int a[4] {1,2,3,4};int *p &a1;int *p1 a1;printf("%#x,%#x",p[-1],*p1);} 以上代码中存在错误。 int *p &a1; 错误1&#xff1a;取a数组的地址&#xff0c;然后1&#xff0c;即指针跳过int [4]大小的字节…

调试以及发布npm组件

开发原因&#xff1a; 由于公司自己的封装到npm的组件有点问题&#xff0c;负责人由在忙其他&#xff0c;就由我去负责改改&#xff0c;中途出了不少问题&#xff0c;记录一下。 一、下载源码 第一步肯定是去git上把组件的源码下载下来&#xff0c;这一步没什么好说&#xf…

日志记录——单片机可执行文件合并

一&#xff1a;需求场景 现在有一片单片机&#xff0c;执行程序包括自定义boot和应用程序app, 在将打包好的固件给到生产是有以下问题&#xff0c;由于要通过jlink烧录boot&#xff0c;然后上电启动boot&#xff0c;通过boot烧录初始化程序&#xff0c;过程过于复杂&#xff0…

Oracle和Mysql数据库

数据库 Oracle 体系结构与基本概念体系结构基本概念表空间(users)和数据文件段、区、块Oracle数据库的基本元素 Oracle数据库启动和关闭Oracle数据库启动Oracle数据库关闭 Sqlplussqlplus 登录数据库管理系统使用sqlplus登录Oracle数据库远程登录解锁用户修改用户密码查看当前语…

嵌入式软件中常见的 8 种数据结构

数据结构是一种特殊的组织和存储数据的方式&#xff0c;可以使我们可以更高效地对存储的数据执行操作。数据结构在计算机科学和软件工程领域具有广泛而多样的用途。 几乎所有已开发的程序或软件系统都使用数据结构。此外&#xff0c;数据结构属于计算机科学和软件工程的基础。当…

SpringBoot:@Profile注解和Spring EL

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、Prof…

业务流程自动化平台在制造业应用案例,助力业务自动化、智能化

捷昌驱动成立于2000年&#xff0c;并于2018年9月在上海证券交易所上市&#xff0c;是一家专注于线性驱动产品研发、生产及销售的科技集团。 公司整合全球资源&#xff0c;为智慧办公、医疗康护、智能家居、工业自动化等关联产业提供驱动及智能控制解决方案&#xff0c;以科技驱…