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

Git:基本使用

我们在写项目代码的时候,代码提交后,由于功能需求的修改或其他原因,可能会涉及到多次的修改,但修改之后,可能会把原来的代码·给改坏了,或还是觉得之前的代码更合适。

但是,尴尬的是,此时的代码已经被改的面目全非了,相仅通过记忆去复原代码,是非常帮困难的,即使改回来了,但若存在多次这样的操作,谁又能受得了呢,于是,Git就能帮我们解决这个问题。

Git的其中一个功能是用来记录之前代码版本,想要查找或恢复之前的代码,可以通过Git查找到。

目录

一. 安装Git

二、Git基本操作

配置GIt

认识工作区,暂存区,版本库:

添加一个文件,并提交到本地仓库:

对 .git文件的介绍:

修改文件:

版本回退:

撤销修改:

情况1:工作区的代码还未add到暂存区:

情况2:工作区的代码已经add了,但还未commit

情况3:已经进行了add,和commit命令:

删除文件:

三、分支管理

创建分支:

合并分支:

合并冲突:

删除分支:

分支管理策略:

bug分支:


一. 安装Git

Git 是开放源代码的代码托管⼯具,最早是在Linux下开发的。开始也只能应⽤于Linux平台,后⾯慢慢的被移植到windows下,现在,Git可以在Linux、Unix、Mac和Windows这⼏⼤平台上正常运⾏了.

下面以Linux-ubuntu平台为例子安装Git:

可以先输入git命令,查看系统有没有安装git.

git
Command 'git' not found, but can be installed with:
sudo apt install git

出现上面的结果,说明git还未安装。就需要安装一下,安装命令也是非常简单的,上面也已经给出来了:

安装git:

sudo apt-get install git -y

(若在root目录下,则可以不用加sudo,非root目录要加sudo)

查看git安装版本:

git --version

Windows安装过程链接:

https://www.bilibili.com/video/BV1hf4y1W7yT/?p=3&vd_source=b57c3f3e8a7507d4af7322c28f05fdbc

二、Git基本操作

我们提交后的代码都是放到远程仓库中的,自己在本地修改好代码后,要提交到远程仓库中。

要先创建一个本地仓库,用来存放自己的代码。

创建本地仓库:

git init

注意,创建本地仓库命令要在文件下执行。

创建成功后,就会发现在当前文件下,多了一个 .git 文件。.git是用来跟踪管理仓库的,不要手动修改这个目录里的文件,否则可能会把Git仓库破坏掉。

配置GIt

安装好Git后,要先配置用户名和e-mail地址。

配置命令:

git config [--global] user.name "your username"
git config [--global] user.email 'email@example.com"

填入你的用户名和邮箱就可以了。

其中的 --global选项是选填项,如果使用了这个选项,表示这台机器上的所有Git都会使用这个配置。要是想在不同仓库设置不同的用户名和邮箱,不加这个配置即可。

查看配置命令:

git config -l

删除配置命令:

git config [--global] --unset user.name
git config [--global] --unset user.email

认识工作区,暂存区,版本库:

工作区:就是你要写的代码的目录。在 .git文件的同目录下。

当前目录就是工作区,在这里可以创建文件等,可以进行提交.

暂存区:(index)是将你写的代码暂存的地方。一般在 .git目录下的index文件夹中。暂存区也叫做索引。

add后的数据都会先保存在这里.

版本库:也叫做仓库,(repository).⼯作区有⼀个隐藏⽬录 .git ,它不算⼯作区,⽽是 Git 的版本库。这个版本库⾥⾯的所有⽂件都可以被 Git 管理起来,每个⽂件的修改、删除,Git 都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

在创建Git版本库的时候,Git会自动帮我们创建一个master分支,和一个指向master的一个指针HEAD。

通过git branch查看当前分支和已经存在的分支.(后面再将git命令),当前仅存在master分支,且前面的*表示HEAD指向它。

HEAD里面存储的就是指向当前分支的位置。

工作区修改完成后,执行 git add 命令,就会将内存存放到暂存区,暂存区的文件就会被修改

git add 要提交的文件名
//git add .提交当前目录下的所有文件

执行git commit 命令,master分支会做出相应的修改,就是将暂存区的内容写入到了版本库中

git commit -m"描述内容"
//-m 后面引号中填写一些关于提交的内容的描述,这个描述是不能少的,并且要好好写,是给我们自己看的

执行了这两个命令后,就完成了将修改提交到了本地的代码仓库中。

添加一个文件,并提交到本地仓库:

先创建文件

touch file1 //创建一个文件
git add [file1] [file2] [file3]... //将创建的一个或多个文件添加到暂存区
git commit -m"touch file1.txt" //提交到本地代码仓库

git commit命令执行后,会告诉我们哪些文件做了改动,改动的内容是什么。

add命令可以进行一次或多次,而commit命令只执行一次即可。

可以通过git log命令,查看提交历史:

git log [--pretty=oneline] [abbrev-commit]
//选填项:
//--prettyp=oneline: 以简洁的形式显示,一行显示一次提交结果
//abbrev-commit: commitId仅显示前10个数字 

我们会看到每次的提交带有一大串数字,因为每次提交,都会生成commit Id(版本号),Git的commit id不是1,2,3……递增的数字,⽽是⼀个 SHA1 计算出来的⼀个⾮常⼤的数字,⽤⼗六进制表⽰.可以通过增加abberv-commit仅显示前10个数字。

对 .git文件的介绍:

1. index 就是我们的暂存区,add 后的内容都是添加到这⾥的。

2. HEAD 就是我们的默认指向 master 分⽀的指针。

3. objects 为 Git 的对象库,⾥⾯包含了创建的各种版本库对象及内容。当执⾏ git add 命令时,暂存区的⽬录树被更新,同时⼯作区修改(或新增)的⽂件内容被写⼊到对象库中的⼀个新对象中,就位于 ".git/objects" ⽬录下。

修改文件:

对创建的文件的任何修改,都算修改。Git跟踪并管理的是修改,而非文件。

现在对file1文件进行一次修改:添加一行:I an studing.

可以通过git status命令查看当前仓库的状态:

git status //该命令用于查看上次提交后,文件是否有新的修改

可以看到 提示文件有被修改,但还未被添加和提交。

通过git status命令,我们只知道文件有被修改,但并不知道修改了什么,若是刚刚修改的,可以记得修改了什么内容,但若是很长时间之前的修改,谁又记得呢?Git知道这个情况,可以通过

git diff [file]命令查看:

git diff [file] //该命令用于显示工作区和暂存区的文件差异。
git diff HEAD --[file] //该命令用于查看工作区和版本库之间的差异。
// file要查看的文件名

 

-表示修改之前:有0行

+:表示修改之后,有一行代码添加

版本回退:

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

执行git reset命令用于版本回退:可以指定返回某一次提交的版本。

这里的回退指的是版本库中代码的回退,工作区和暂存区的代码是否回退,取决于命令的参数

git reset [--soft|--mixed|--hard] [HEAD]//选项说明://HEAD: 指要回退的版本,可直接写commit Id即可。
//  HEAD: 表示回退到当前版本,
//  HEAD^: 上一个版本
//  HEAD^^: 上上个版本
//....以此类推。
//也可以使用 ~ 加 数字 表示:
//HEAD~0 : 表示当前版本
//HEAD~1 :表示上一个版本
//HEAD~2:表示上上个版本
//以此类推。//--soft : 仅回退版本库中的代码,工作区和暂存区的代码不回退。//--mixed: 为默认选项,使用时可以不带该参数。将暂存区内容回退为指定提交版本内容,工作区的内容保持不变。//--haed: 将工作区和暂存区的内容都回退到指定版本。切记,这个选项一定要慎用,因为一旦使用之前工作区未提交的代码将都找不到了。

当我们进行版本回退后,若发现还是原来的版本更好,Git也给我们提供了吃后悔药的机会。

还是使用git reset命令,但是必须要知道要返回的版本号,即commit ID。

当使用git log命令查找不到想要回退的版本号时,还可以通过git reflog命令查找:

git reflog //该命令用来记录本地的每一次命令

此处查到的是commit ID的部分。

git版本回退的速度时候非常快的,因为 Git 在内部有个指向当前分⽀(此处是master)的 HEAD 指针, refs/heads/master ⽂件⾥保存当前 master 分⽀的最新 commit id 。当我们在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储⼀个特定的version,通过修改HEAD的指向,即可实现版本回退到指定版本。

但是由于git更新版本的速度是非常快的,有可能查不到需要返回的版本的commit ID,就真的无法返回了,因此每一次的·git命令都应该慎重操作。

撤销修改:

当我们在工作区写了很长时间的代码,发现代码越写越乱,想回到修改之前,即上次提交的状态,Git也满足了我们。

情况1:工作区的代码还未add到暂存区:

当你还记得自己在哪些地方进行了修改,可以直接在原代码上修改即可;

要是已经改的很乱了,或者过了很长时间,忘记了修改了哪些地方,就是无法通过手动的方式进行恢复,Git提供了git checkout -- [file]命令让工作区文件回到最近一次add或commit状态。

git checkout --[file] //file:要恢复的文件名

情况2:工作区的代码已经add了,但还未commit

add后,就将代码保存到了暂存区,此时要恢复代码比较麻烦了。

法一:

在版本回退的时候的--mixed参数,使用这个参数吗,让暂存区的代码回退到当前版本库中代码的版本,暂存区中的代码就恢复到了上次提交代码的状态了;

然后再通过git checkout --[file]命令,将工作区的代码恢复即可。

git reset --mixed HEAD [file] 
git checkout --[file]

法二:

此时仅进行了add,版本库中的代码还未被更新,可以直接使用版本回退命令,将回退参数设为 --hard ,直接将工作区和暂存区的代码都回退到当前版本库中的代码版本。

git reset --haed HEAD [file]

情况3:已经进行了add,和commit命令:

还是通过版本回退命令,回退到版本库中的上一个版本:

git reset --hard HEAD^

删除文件:

删除文件也是一个操作,要想将执行提交到本地仓库中,也需要执行add和commit命令。若不小心误删了文件,这也属于操作,按照撤销修改的命令执行,进行文件恢复即可。

三、分支管理

我们知道,在创建git的时候,他会为我们默认创建一个master分支,并让HEAD指定master分支,每次提交,Git都把它们串成⼀条时间线,这条时间线就可以理解为是⼀个分⽀。截⽌到⽬前,只有⼀条时间线,在Git⾥,这个分⽀叫主分⽀,即 master 分⽀。

HEAD指向的不是提交,而是分支,此时指向的是master分支,master才是指向提交的,HEAD指向的是当前执行的分支。

每次提交,master分⽀都会向前移动⼀步,这样,随着你不断提交,master分⽀的线也越来越⻓,⽽HEAD只要⼀直指向master分⽀即可指向当前分⽀。

创建分支:

Git支持我们创建并查看分支,现在创建一个dev分支:

git branch //查看当前HEAD指向的分支和当前存在的分支git branch dev //创建一个dev分支git checkout dev //切换到dev分支,就是让HEAD指向dev分支,此后的操作都是在dev分支上执行的了//创建分支并切换到新创建的分支上,两条命令,可以合成一条执行:
git checkout -b dev //创建dev分支,并切换到dev分支上

查看当前分支,创建dev分支,并切换到dev分支上:

创建分支并切换到新创建的分支上,可以用git checkout -b dev命令一步实现。

合并分支:

不同的分支之间存在隔离性,在一个分支上进行的提交,在另一个分支上是不显示的,即一个分支的修改,对另一个分支不造成影响。
想要让两个分支上的结果合并到一个分支上,可以通过git merge来实现:

git merge dev //合并dev分支到master主分支上,这个操作必须要先切换到master分支上操作

该命令用于合并指定分支到当前分支上,因此在合并前,需要先切换到当前分支才行。

ast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度⾮常快。当然,也不是每次合并都能 Fast-forward,还有其他的合并方式。

合并冲突:

在合并分支的时候,并不一定能合并成功,有时候会遇到代码冲突的问题。

例如:master分支对file1文件进行了修改,并提交到了代码仓库,切换到dev分支,dev分支也对file1文件进行了修改,并提交到代码仓库,此时,dev分支想合并master分支,就会出现代码冲突的现象。这是因为两个分支都进行了新的提交,合并的时候不是在同一条主干上的,git不知道要以那个为准,就会发生合并冲突。

出现冲突后,需要自己手动处理冲突,然后再进行add,commit提交到代码仓库。

修改后保存,进行再次提交,推送。

用带参数的git log查看分支的合并情况:

git log --graph --pretty=oneline --abbrev-commit

删除分支:

分支合并后,就没有用了,就可以删除了:通过git branch -d 命令,将其删除:

git branch -d dev //删除dev分支

删除分支的时候,不能处在当前分支下,要切换到别的分支上执行该命令才行

因为创建、合并和删除分⽀⾮常快,所以Git⿎励你使⽤分⽀完成某个任务,合并后再删掉分⽀,这和直接在master分⽀上⼯作效果是⼀样的,但过程更安全。

当当要删除的分支上还有未被提交的内容时,Git会禁止删除分支,若想要强制删除,可以使用

git branch -D 分支名 命令进行删除。

git branch -D dev //强制删除dev分支

分支管理策略:

之前提到的fast forward模式,在合并分支的时候,若合并成功,就是采用的fast forward模式,这种模式下,当合并之后,删除分支后,查看历史分支时,就不知道这次的操作是最新的提交还是分支合并的,只能看到有一次提交。

当合并冲突的时候,就不是fast forward模式了,会进行一次新的提交,这样即使删除了合并的分支,也能知道上次的提交是合并的,还是一次提交。

Git支持我们强制禁止使用fast forward模式,禁止后,当merge时,就会生成一个新的commit,这样就能从历史分支上知道分支信息了。

在执行合并分支命令的时候,要想禁用fast forward模式,加上--no-ff 配置 :

git merge --no-ff -m"合并描述" dev //将dev分支采用非fast forward的方式合并到master分支上

禁用fast forward模式后,会创建一个新的commit Id,因此在合并的时候,要将描述写进去。

bug分支:

当在dev上开发项目,进行到一半,发现master分支上有一个bug,需要解决,在Git中,每个bug都可以创建一个临时bug分支,进行修复,修复后,合并bug分支到master分支上,合并后将bug分支删除。

但此时dev还未开发完,无法提交,可以通过Git提供的git stash命令,将当前工作区的信息存储起来,被存储的信息在将来某个时间可以恢复出来。

git stash //将当前还未完成的版本暂存起来

这个命令执行后,当前的状态就是上次提交代码的状态。

master分支上的代码修复后,要取dev分支上继续代码开发,此时可以通过git stash list命令。查看之前stash的代码保存在了哪里。要恢复代码时,通过git stash pop命令,恢复原来的代码,并将stash也给删除了。

git stash list //查看之前stash的工作现场存储在哪里了
git stash pop //将之前stash的工作现场恢复,并删除stash

总结:每当要实现一个新的功能时,需要在原来的代码上进行开发,就可以创建一个新的分支,创建完成后,再和主分支进行合并,你创建了⼀个属于你⾃⼰的分⽀,别⼈看不到,还继续在原来的分⽀上正常⼯作,⽽你在⾃⼰的分⽀上⼲活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分⽀上,这样,既安全,⼜不影响别⼈⼯作。

并且 Git ⽆论创建、切换和删除分⽀,Git在1秒钟之内就能完成。

http://www.xdnf.cn/news/18961.html

相关文章:

  • 校园勤工俭学微信小程序的设计与实现:基于数字化服务生态的赋能体系构建
  • 10分钟快速搭建 SkyWalking 服务
  • 机器学习笔记
  • 【C语言】小游戏:关机程序
  • 【Linux 进程】进程程序替换
  • RAG中使用到的相关函数注释——LangChain核心函数
  • AI出题人给出的Java后端面经(二十仨)(不定更)
  • 【AI论文】FutureX:面向未来预测任务中大语言模型智能体的前沿动态基准测试
  • 【科研绘图系列】R语言在海洋生态学中的应用:浮游植物糖类组成与溶解性有机碳的关系
  • 永磁同步电机无速度算法--传统脉振方波注入法(1)
  • LangGraph
  • 【更新至2024年】2000-2024年各地级市绿色专利数据
  • 【lucene】spancontainingquery
  • 主流的 AI Agent 开发框架
  • 矩阵的秩几何含义
  • WPS 智能文档,5分钟上手!
  • 云蝠智能 Voice Agent:多语言交互时代的AI智能语音呼叫
  • 支持向量机(第二十九节课内容总结)
  • JMM 浅析
  • StandardScaler()进行0,1标准化时fit_transform与transform的区别
  • HTML的form表单
  • 子串:和为K的子数组
  • 记一个Mudbus TCP 帮助类
  • from中烟科技翼支付 面试题1
  • 财报出炉,李宁也被“靠边站”了
  • 摄像头模块的技术原理
  • WeakAuras Lua Script (My Version)
  • 【Lua】题目小练11
  • 红黑树下探玄机:C++ setmultiset 的幕后之旅
  • 无线网络中的Duration字段计算:原理、机制与实现