【基础篇】Git 基础命令与核心概念

✅作者简介:大家好,我是小杨
📃个人主页:「小杨」的csdn博客

🐳希望大家多多支持🥰一起进步呀!


一,Git 初识

1.1,问题引入

不知道你工作或学习时,有没有遇到这样的情况:我们在编写各种文档时,为了防止出现文档丢失或者更改失误的情况,失误后也能恢复到原来的版本,不得不复制出一个副本,比如:

“文档报告-v1”

“文档报告-v2”

“文档报告-v3”

每个版本都有各自的内容,但最终只会有一份文档报告被我们使用。

但在此之前的工作都需要这些不同版本的文档报告,于是每次都要经过复制粘贴操作得到副本,产出的文件就会越来越多,虽然文件多不是什么大问题,但问题是:随着版本数量的不断增多,你是否还记得这些版本各自都是修改了什么吗?

这个文档报告是如此,我们写的项目代码也是如此,就是也存在上述这个问题的。那如何解决上述问题呢?


1.2,问题解决

那如何解决上述问题呢?这就便有了版本控制器。

何为版本控制器?所谓的版本控制器,就是能让你了解到一个文件的历史,以及它的发展过程的系统。

通俗的讲就是一个可以记录工程的每一次改动和版本迭代的一个管理系统,同时也方便多人协同作业。

目前最主流的版本控制器就是Git 。Git可以控制电脑上所有格式的文件,例如doc、 excel、dwg、dgn、rvt等等。对于我们开发人员来说,Git最重要的就是可以帮助我们管理软件开发项目中的源代码文件!

注意事项:

1,Git只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等。版本控制系统可以告诉你每次的改动,比如在第5行添加了一个单词”Linux",或者在第8行删了一个单词"Windows"。

2,而对于图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来。也就是只能知道图片从10OKB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。


1.3,Git 的功能

Git 是目前最主流的版本控制器,其主要实现以下的功能:

  1. 版本控制和分支管理
  2. 本地与远程仓库操作:提交,拉取,合并,推送
  3. 团队协同开发:团队中的成员可通过克隆仓库到本地后进行独立开发

1.4,Git 的工作机制

在谈到Git的工作机制之前,首先了解几个基本概念:

  1. 工作区:在电脑上所能看到或者写代码文件的目录。
  2. 暂存区:临时存储工作区的代码,一般存放在.git目录下的index文件中,也被称为索引。
  3. 版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。其里面的所有文件都可被Git 管理和控制。
  4. objects:Git 的对象库,位于 .git/objects 目录下,修改的工作区内容会写入对象库的一个新的object对象中。

下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

在这里插入图片描述

Git 的工作机制如下:

1,工作区的代码文件通过使用git add命令将其放到暂存区
2,暂存区的代码文件通过使用git commit命令将其提交到版本库
3,版本库的代码文件通过使用git push命令将其推送到远程仓库中


二,Git 使用

2.1,Centos 安装 Git

1. Git 查看命令:

git

2. Git 下载命令:

sudo yum -y install git

3. Git 版本查看命令:

git --version

4. Git 卸载命令:

sudo yum -y remove git 

2.2,Ubuntu 安装 Git

1. Git查看命令:

git

2. Git 下载命令:

sudo apt-get -y install git

3. Git 版本查看命令:

git --version

4. Git 删除命令:

sudo apt-get -y remove git

2.3,本地仓库创建

1. 创建一个文件夹并进入

mkdir gitcode

2. Git 本地仓库创建命令:

git init

3. Git本地仓库具体目录查看命令:

tree .git

4. 代码实操:

image-20240417212036088

在这里使用tree .git命令进行查看Git本地仓库具体目录时,会出现上述报错信息。出现其报错原因是在centos中,tree命令不存在,需要通过sudo yum -y install tree 命令下载tree,操作如下:

image-20240417212631162

下载完成后通过使用tree .git命令就可以查看Git本地仓库具体目录了。

image-20240417212840976

5. 本地仓库创建注意

仓库是进行版本控制的一个文件目录,所以要想对文件进行版本控制,就必须先创建一个仓库出来,然后在创建的文件目录下使用git init指令执行创建一个Git本地仓库的操作。


2.4,本地仓库配置

当安装Git后首先要做的事情是设置你的用户名称e-mail地址,这是非常重要的。

  1. 特定配置添加命令:
git config [-global] user.name "Your Name"
git config [-global] user.email "email@example.com"

# 把 Your Name 改成你的昵称
# 把 email@example.com 改成邮箱的格式,只要格式正确即可。
  1. 所有配置查看命令:
git config -l
  1. 特定配置删除命令:
git config [--global] --unset user.name
git config [--global] --unset user.email
  1. 代码实操:

image-20240417214247412

5. 本地仓库配置注意

–global选项是一个可选项。如果使用了该选项,表示这台机器上所有的git仓库都会使用这个配置。如果你希望在不同仓库中使用不同的name或e-mail,可以不使用–global选项,但要注意的是,执行命令时必须要在仓库里,并且如果特定配置添加时使用了–global选项,删除特定配置时也需要使用该选项。


2.5,本地文件操作

1.本地文件准备:

touch file

2.本地文件添加命令:

git add [file1] [file2] ...  # 添加⼀个或多个⽂件到暂存区
git add [dir]                # 添加指定⽬录到暂存区,包括⼦⽬录
git add .                    # 添加当前⽬录下的所有⽂件改动到暂存区

3.本地文件提交命令:

 git commit -m "message"                       # 提交暂存区全部内容到仓库中
 git commit [file1] [file2] ... -m "message"   # 提交暂存区的指定⽂件到仓库区
 git commit [dir] ... -m "message"	           # 提交暂存区的指定目录到仓库区

4.本地文件提交记录查看命令:

git log [--pretty=oneline]

5.代码实操:

image-20240417222545411

6.本地仓库状态查看命令:

git status

7.文件差异查看命令:

git diff [file]              # 暂存区和工作区文件差异查看命令
git diff HEAD -- [file]      # 版本库和工作区文件差异查看命令

8.代码实操:

image-20240417225733879


2.6,本地仓库结构目录

通过使用tree .git 命令就可以查看本地仓库的结构目录,下图所示:

image-20240417231144776

在本地仓库的结构目录中,需要特别关注下面几个:

• index:暂存区,git add后会更新该内容。

• HEAD:默认指向 master 分支的一个指针。

• refs/heads/master:文件里保存当前 master 分支的最新commit id 。

• objects: 包含了创建的各种版本库对象及内容,可以简单理解为放了 git 维护的所有修改。

代码实操:

image-20240417234308038

注意1:查找object时要将commit id分成2部分,其前2位是文件夹名称,后38位是文件名称。找到这个文件之后,一般不能直接看到里面是什么,该类文件是经过sha(安全哈希算法)加密过的文件,我们可以使用 git cat-file 命令来查看版本库对象的内容。

注意2:通过使用git cat-file命令来查看版本库对象的内容,发现内容中有tree和parent。其中tree表示当前提交的文件状态快照,它包含了文件和子目录的信息,而parent表示当前提交对象的父提交,也就是它的前一个历史状态。


2.7,文件版本回退

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

git reset命令语法格式为:git reset [–soft | --mixed | --hard] [HEAD]

–soft:对于工作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。

–mixed:默认参数,将暂存区和版本库的内容回退到指定版本,工作区文件不变。

–hard:将版本库,暂存区,工作区都回退到指定版本,使用该参数需要慎重考虑。

HEAD:表示回退的版本,有三种写法,分别为:直接使用commit id,HEAD(当前版本),HEAD^(上一版本),HEAD0(当前版本),HEAD1(上一版本)。


2.8,文件撤销修改

文件撤销修改有3种情况以及对应的解决方法:

  1. 工作区内容未添加和提交:直接修改工作区内容【不推荐,容易操作失误】,使用git checkout -- [file]命令撤销修改【推荐】。
  2. 工作区内容添加但未提交:使用git reset --mixed HEAD [file]命令将暂存区内容回退到当前版本,接着进行上述第一种情况操作。
  3. 工作区内容添加并已提交:使用git reset --hard HEAD^ [file]命令将版本库,暂存区,工作区内容回退到上一版本。

2.9,文件删除

文件删除不仅需要将工作区文件删除,还需要将版本库中的文件删除。有2种方式:

  1. 首先需要使用git rm [file]命令删除工作区和暂存区的文件,然后通过git commit命令进行删除版本库中的文件。
  2. 首先需要使用rm [file]命令删除工作区文件,然后通过git addgit commit命令依次进行删除暂存区和版本库中的文件。

三,分支管理

3.1,分支管理理解

Git分支管理是一种组织和管理代码变更的方法,它允许团队在同一个代码库中同时进行多个独立的工作。通过使用分支,团队可以在不影响主要代码流的情况下开发新功能、修复bug、测试变更等。

  1. 主分支(Main/Branch):主分支是项目的主要分支,通常用于发布稳定版本。在过去,主分支通常被称为“master”,但随着对语言的更新,更倾向于使用“main”。
  2. 开发分支(Develop Branch):开发分支是用于整合和测试新功能的分支。团队成员通常从主分支创建开发分支,并在此处进行开发工作。当开发完成并且测试通过时,开发分支通常会被合并回主分支。
  3. 功能分支(Feature Branch):功能分支用于开发单个功能或修复单个问题。每个功能或问题通常对应一个独立的功能分支。功能分支通常从开发分支创建,并在完成后被合并回开发分支。
  4. 发布分支(Release Branch):发布分支用于准备发布新版本。在发布分支上进行最后的测试、修复bug和准备版本号等工作。完成后,发布分支会被合并回主分支,并且通常会被打上标签以标记发布版本。
  5. 修复分支(Hotfix Branch):修复分支用于紧急修复生产环境中的bug。它们通常是从主分支分支出来的,并且在修复后会合并回主分支和开发分支。

3.2,分支管理操作

1.分支查看

git branch            # 列出所有本地分支,当前分支会用星号标记。
git branch -a         # 列出所有本地和远程分支。

2.分支创建

git branch <branch-name> 

3.分支切换

git checkout <branch-name> 

4.分支合并

git merge <branch-name>           # 将指定分支合并到当前分支。
git merge --no-ff <branch_name>   # 以非快进模式合并分支,保留合并历史。

5.分支删除

git branch -d <branch-name>
git branch -d <branch_name>       # 删除指定的本地分支,如果分支未合并,则会报错。
git branch -D <branch_name>       # 强制删除指定的本地分支,即使分支未合并也会删除。

6.分支创建并切换

git branch -b <branch-name> 

7.分支重命名

git branch -m <old_branch_name> <new_branch_name

8.合并基点查看

git merge-base <branch1> <branch2>   # 查看两个分支的最近共同祖先,通常用于解决合并冲突。

9.分支历史查看

git log --oneline --graph --all      # 以图形化方式查看所有分支的提交历史。

10.远程分支跟踪

git branch -u <remote>/<branch>      # 将当前分支设置为追踪指定的远程分支。

11.分支推送

git push <remote> <branch_name>      # 将本地分支推送到远程仓库。
git push -u <remote> <branch_name>   # 第一次推送分支时,使用 -u 参数建立追踪关系。

12.远程分支拉取

git fetch <remote>                   # 从远程仓库拉取所有分支的更新。
git fetch <remote> <branch_name>     # 从远程仓库拉取指定分支的更新。

13.默认分支设置

git config --global init.defaultBranch <branch_name>   #设置新建仓库时的默认分支。

3.3,分支管理注意

1,分支合并策略有两种,分别为:fast forwardnon-fast forward

fast forward :在合并分支时,Git 可以简单地将目标分支指针向前移动到要合并的分支的最新提交,而不需要创建新的合并提交。这种方式的合并操作不会产生额外的合并提交,因此合并历史非常干净,分支图也非常线性清晰。

non-fast forward:在合并分支时,Git 需要创建一个新的合并提交,将两个分支的更改集成在一起。这种方式的合并操作会在提交历史中创建一个新的合并节点,显示两个分支的合并点。

image-20240418182306193

2,分支合并冲突问题

场景1:master分支和dev分支各自都分别有新的提交,在这种情况下,Git试图把各自的修改合并起来,但这种合并就可能会有冲突。

当Git合并分支时,如果发现有冲突,它会在文件中标记出这些冲突,这种标记使用<<<<<<<=======,和>>>>>>>来区分不同分支的内容。

这时,你需要手动解决这个冲突,编辑文件,然后提交解决后的结果。这样做可以确保冲突得到正确解决,并且合并结果被正确保存。

image-20240418222849741

场景2:现有主分支master运行代码程序,修复分支fix修复bug,开发分支dev2开发功能,fix分支和dev2分支都有新的提交,在这种情况下,Git试图把各自的修改合并起来,会出现合并冲突。

当将修复分支(fix)合并到主分支(master)后,接着再把功能分支(dev2)合并至主分支,可能引入了一些与正在开发的功能(在dev2分支上)不兼容的更改,从而导致主分支的代码出现错误。

image-20240418230808530

解决这个问题的方法就是:在dev2分支上合并master,再让master去合并dev2,这样做的目的是有冲突可以在dev2分支上解决并进行测试,而不影响master主分支。

image-20240418230609198


四,远程操作

4.1,远程仓库克隆

1,使用HTTPS方式克隆

git clone https:....

2,使用SSH方式克隆

git clone ssh:....

注:在使用SSH方式克隆仓库时,需要添加公钥至远程仓库中,如果未进行添加,服务器会拒绝我们的clone操作。设置方式:

  1. 查看服务器主目录中有没有.ssh目录

  2. 再看.ssh目录中有没有id_rsa(私钥)id_rsa.pub(公钥)这两个文件

  3. 如果没有上述两个文件,则需要创建SSH KEY

    ssh-keygen -t rsa -C "邮箱"     # 邮箱要与Gitee上的保持一致
    
  4. 使用cat命令查看id_rsa.pub(公钥)这个文件,然后将出现的一串公钥复制

  5. 把复制的公钥粘贴至Gitee的添加公钥页面,确认即可


4.2,远程仓库推送

远程仓库克隆到本地仓库之后,需要配置本地仓库的user.name和user.email。操作命令如下:

git config [user.name/user.email] [值]

这里的用户名和邮箱也要和Gitee上的保持一致。

git push [远程仓库名] [本地分支]:[远程分支]

如果本地分支和远程分支相同,可以省略:[远程分支]


4.3,远程仓库拉取

在日常开发工作中,需要从远处仓库中拉取最新的代码,操作命令如下:

git pull [远程仓库名] [远程分支]:[本地分支]

五,标签管理

在Git中,标签(tag)是用于标记特定提交的版本号或者别名。标签可以帮助你在代码库中标记重要的里程碑、版本发布等信息。

5.1,创建标签

1,轻量级标签(Lightweight Tags):只是一个指向特定提交的引用

git tag <tag_name>

2,带注释的标签(Annotated Tags):包含更多关于该标签的信息,如标签作者,发布日期,发布说明等

git tag -a <tag_name> -m "tag message"

5.2,查看标签

1,查看所有标签:

git tag

2,查看特定标签的详细信息:

git show <tag_name>

5.3,删除标签

git tag -d <tag_name>

5.4,推送标签到远程仓库

1,推送单个标签:

git push origin <tag_name>

2,推送所有标签:

git push origin --tags

5.5,删除远程仓库上的标签

git push origin --delete <tag_name>

结语

这就是本期博客的全部内容啦!如果有什么其他的问题无法自己解决,可以在评论区留言哦!

最后,如果你觉得这篇文章写的还不错的话或者有所收获的话,麻烦小伙伴们动动你们的小手,给个三连呗(点
赞👍,评论✍,收藏📖),多多支持一下!各位的支持是我最大的动力,后期不断更新优质的内容来帮助大家,一起进步。那我们下期见!


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

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

相关文章

Centos8操作系统安装mysql5.7版本以及报错解决

目录 一、卸载MySql 1.首先查看已安装的mysql 2.逐个或者执行一下命令统一卸载掉 注意&#xff1a; 3. 卸载其他相关文件 二、安装MySql 1.安装mysql的rpm源 2.安装MySql 如果遇到以下错误&#xff1a; 问题一: 解决方法&#xff1a; 问题二、 解决方法&#xff1…

国产麒麟v10系统下打包electron+vue程序,报错unknown output format set

报错如下&#xff1a; 报错第一时间想到可能是代码配置原因报错&#xff0c;查看代码似乎感觉没啥问题 又查看具体报错原因可能是因为icon的原因报错&#xff0c;后面查阅发现ico在各系统平台会不兼容&#xff0c;也就是ico是给win下使用的&#xff0c;此处改下图标格式就ok&am…

1、Qt简介

文章目录 前言一、pySide2 / pySide6 ,PyQt5 / PyQt6二、安装包1 安装pyside22 安装pyqt5三、从一个简单的例子开始三、界面动作处理---信号(signal)与槽(slot)(Qt最核心的机制)--- 绑定事件封装到类中总结前言 参考文章:Qt简介 本文开始就开始进入到qt的开发笔记书写…

【论文解读】QUEST: Query Stream for Practical Cooperative Perception

QUEST 摘要引言QUERY COOPERATION PARADIGMQUEST FRAMEWORKA. Overall ArchitectureB. Cross-agent Query Interaction 实验结论 摘要 合作感知通过提供额外的视点和扩展感知领域&#xff0c;可以有效地提高个体感知性能。现有的合作模式要么是可解释的(结果合作)&#xff0c;…

计算机视觉——OpenCV 使用分水岭算法进行图像分割

分水岭算法 分水岭算法&#xff1a;模拟地理形态的图像分割 分水岭算法通过模拟自然地形来实现图像中物体的分类。在这一过程中&#xff0c;每个像素的灰度值被视作其高度&#xff0c;灰度值较高的像素形成山脊&#xff0c;即分水岭&#xff0c;而二值化阈值则相当于水平面&am…

LabVIEW高效目标跟踪系统

LabVIEW高效目标跟踪系统 随着机器视觉技术的飞速发展&#xff0c;设计和实现高效的目标跟踪系统成为了众多领域关注的焦点。基于LabVIEW平台&#xff0c;结合NI Vision机器视觉库&#xff0c;开发了一种既高效又灵活的目标跟踪系统。通过面向对象编程方法和队列消息处理器程序…

以更多架构核心专利,推进 SDS 产业创新创造

今天是第 24 个世界知识产权日&#xff0c;今年世界知识产权日活动的主题是&#xff1a;“知识产权和可持续发展目标&#xff1a;立足创新创造&#xff0c;构建共同未来。” 这也正是 XSKY 在软件定义存储领域的目标之一。以“数据常青”为使命的 XSKY&#xff0c;始终立足于软…

济宁市中考报名照片要求及手机拍照采集证件照方法

随着中考报名季的到来&#xff0c;并且进入了中考报名演练阶段&#xff0c;济宁市的广大考生和家长都开始忙碌起来。报名过程中&#xff0c;上传一张符合要求的证件照是必不可少的环节。本文将详细介绍济宁市中考报名照片的具体要求&#xff0c;并提供一些实用的手机拍照采集证…

LeetCode in Python 74/240. Search a 2D Matrix I/II (搜索二维矩阵I/II)

搜索二维矩阵I其实可以转换为搜索一维数组&#xff0c;原因在于&#xff0c;只要先确定搜索的整数应该在哪一行&#xff0c;即可对该行进行二分查找。 搜索二维矩阵II中矩阵元素排列方式与I不同&#xff0c;但思想大致相同。 目录 LeetCode in Python 74. LeetCode in Pyth…

html表格导出为word文档,导出的部分表格内无法填写文字

导出技术实现&#xff1a;fileSaver.jshtml-docx-js 1.npm安装 npm install --save html-docx-js npm install --save file-saver 2.页面引入 import htmlDocx from html-docx-js/dist/html-docx; import saveAs from file-saver;components: {htmlDocx,saverFile, }, 3.页…

(MSFT.O)微软2024财年Q3营收619亿美元

在科技的浩渺宇宙中&#xff0c;一颗璀璨星辰再度闪耀其光芒——(MSFT.O)微软公司于2024财政年度第三季展现出惊人的财务表现&#xff0c;实现总营业收入达到令人咋舌的6190亿美元。这一辉煌成就不仅突显了微软作为全球技术领导者之一的地位&#xff0c;更引发了业界内外对这家…

Vue从0-1学会如何自定义封装v-指令

文章目录 介绍使用1. 理解指令2. 创建自定义指令3. 注册指令4. 使用自定义指令5. 自定义指令的钩子函数6. 传递参数和修饰符7. 总结 介绍 自定义封装 v-指令是 Vue.js 中非常强大的功能之一&#xff0c;它可以让我们扩展 Vue.js 的模板语法&#xff0c;为 HTML 元素添加自定义行…

在Elasticsearch 7.9.2中安装IK分词器并进行自定义词典配置

Elasticsearch是一个强大的开源搜索引擎&#xff0c;而IK分词器是针对中文文本分析的重要插件。本文将引导您完成在Elasticsearch 7.9.2版本中安装IK分词器、配置自定义词典以及验证分词效果的全过程。 步骤一&#xff1a;下载IK分词器 访问IK分词器的GitHub发布页面&#xf…

【网络编程】TCP流套接字编程 | Socket类 | ServerSocket类 | 文件资源泄露 | TCP回显服务器 | 网络编程

文章目录 TCP流套接字编程1.ServerSocket类2.Socket类3.文件资源泄露4.**TCP回显服务器** TCP流套接字编程 ​ ServerSocket类和Socket类这两个类都是用来表示socket文件&#xff08;抽象了网卡这样的硬件设备&#xff09;。 TCP是面向字节流的&#xff0c;传输的基本单位是b…

MySQL B+索引的工作原理及应用

引言 在数据库系统中&#xff0c;索引是优化查询、提高性能的关键技术之一。特别是在MySQL数据库中&#xff0c;B树索引作为最常用的索引类型&#xff0c;对数据库性能有着至关重要的影响。本文旨简单解析MySQL中B树索引的工作原理&#xff0c;帮助学生朋友们更好地理解和利用…

Kubernetes学习-核心概念篇(一) 初识Kubernetes

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Kubernetes渐进式学习-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1. 前言 2. 什么是Kubernetes 3. 为什么需要Kubernetes 3.1. 应…

ArcGIS批量寻找图层要素中的空洞

空洞指的是图层中被要素包围所形成的没有被要素覆盖的地方&#xff0c;当图层要素数量非常庞大时&#xff0c;寻找这些空洞就不能一个一个的通过目测去寻找了&#xff0c;需要通过使用工具来实现这一目标。 一、【要素转线】工具 利用【要素转线】工具可以将空洞同图层要素处于…

HTML网页自动播放背景音乐和全屏背景图代码

HTML网页自动播放背景音乐的代码 背景音乐代码及分析代码的应用背景图代码及分析下期更新预报 背景音乐代码及分析 能使网站上自动循环的背景音乐代码如下&#xff1a; <audio src"music.mid" autostart"true" loop"true" hidden"true…

python使用opencv对图像的基本操作(2)

13.对多个像素点进行操作&#xff0c;使用数组切片方式访问 img[i,:] img[j,:] #将第j行的数值赋值给第i行 img[-2,:]或img[-2] #倒数第二行 img[:,-1] #最后一列 img[50:100,50:100] #50-100行&#xff0c;50-100列&#xff08;不包括第100行和第100列&#xff09; img[:100…

怎么用PHP语言实现远程控制电器

怎么用PHP语言实现远程控制电器呢&#xff1f; 本文描述了使用PHP语言调用HTTP接口&#xff0c;实现控制电器&#xff0c;通过控制电器的电源线路来实现电器控制。 可选用产品&#xff1a;可根据实际场景需求&#xff0c;选择对应的规格 序号设备名称厂商1智能WiFi通断器AC3统…
最新文章