常用GIT命令速览,现学也能登堂入室

举报
战斧 发表于 2023/09/18 18:23:12 2023/09/18
【摘要】 GIT的命令总体分为上层命令与底层命令。底层命令直接操控GIT的底层存储机制,操作风险性大还不友好,一般不使用。所以开发者对于开发者而言,只需要专注于上层命令即可,这也是我们今天要学的内容

常用GIT命令速览,现学也能登堂入室

image.png
经过前两期的学习,相信大家对GIT本身,以及其基本原理与模型有了一定的了解。本期就让我们开始学习GIT的命令,GIT的命令总体分为上层命令与底层命令。底层命令直接操控GIT的底层存储机制,操作风险性大还不友好,一般不使用。所以开发者对于开发者而言,只需要专注于上层命令即可,这也是我们今天要学的内容


一、GIT HELP

1. 命令文档

一切都有个开始,我们现在学GIT命令,最首先要学的就是git help ,该命令用来显示任何命令的 Git 自带文档。
它有三种打开方式

git help <verb>
git <verb> --help
man git-<verb>

比如我想了解 add命令,当我输入 git add --help ,就会打开一个关于 add 命令的操作文档

 git add --help

image.png

2. 简要说明

当然,如果我们不需要打开文档,只想快速了解下这个命令,只要在命令后加 -h 即可,还是拿 add 举例:

git add -h

image.png

二、配置(config)

1. 配置列表

GIT的配置项非常的多,从功能到界面颜色都能设置,不过对于大多数同学,需要用的时候再做具体了解也不迟。一般情况下,我们可以用 git config --list 来进行配置的查看

# 查看配置列表
git config --list

image.png

2. 增删改查

当我们明确要修改某个配置的时候,我们往往会先查看该配置的当前值,其格式如 : git config <variable>

# 查看 user.name
git config user.name
zhanfu

如果我们想删除某个配置的设置,其格式如下:git config --unset <variable>

# 取消 user.name 的配置
git config --unset user.name

image.png

如果我们想修改,或是新增一个新的配置,我们可以这么使用:git config <key> <value>

# 新增一个叫user.aabb的配置
git config user.aabb ccdd

git config user.aabb
ccdd

3. 配置范围

GIT支持多种作用域范围的配置,即使同一个配置名,在不同的范围等级也是可以不一样的,目前其支持的主要作用域有

  • system:系统,配置存储于$(prefix)/etc/gitconfig
  • global:全局,配置存储于$XDG_CONFIG_HOME/git/config
  • local:本地(也是默认作用域),配置存储于$GIT_DIR/config
  • worktree:工作区,配置于$GIT_DIR/config.worktree

每个作用域都对应一个命令行选项:--system, --global, --local, --worktree

读取选项时,指定范围将仅从该范围内的文件中读取选项。编写选项时,指定范围将写入该范围内的文件,可以看这样的示例:

# 分别在全局和本地设置用户名
git config --global user.name zhanfu
git config --local user.name zhanfu1
# 查询用户名,显示的本地作用域配置
git config user.name
zhanfu1

4. 常用设置

尽管GIT的配置项非常的多,但大多数人不需要全部掌握,我们在这给出一些常用的配置

  1. 用户信息
git config --global user.name "Your Name"
git config --global user.email you@example.com

这里使用了 --global,代表这是一个全局设置,但是如果你想在对接不同仓库时(比如电脑上同时有公司仓库和个人项目仓库),使用不同的个人信息可能更合适,此时你需要在对接不同仓库时,使用如下配置

git config user.name "Your Name"
git config user.email you@example.com
  1. 编辑工具

如果在linux上使用GIT,没有视窗,我们可以设置其全局编辑工具

git config --global core.editor "vim"
  1. 禁用Git自动换行
git config --global core.autocrlf false

三、仓库创建

Git支持两种方式来创建仓库。 一种是从网络上或者其他地方拷贝一个现有的仓库,另一种就是在一个目录中创建一个新的仓库

1. 初始化(init)

当我们想在某个目录创建GIT仓库,只需在此目录下执行 git init 命令即可,其会自动在当前目录中创建一个新的 Git 仓库,以此开始对版本控制的跟踪。

git init

该命令可以跟带一些参数,常用的有:

# 从给定模板目录创建新的 Git 仓库,默认模版为(/usr/share/git-core/templates)
git init --template=<template-directory>

# 创建仓库时,为自动建立的分支命名。若不设置,默认分支名通常为“master”
git init --template=<template-directory>

需要注意的是,git init 命令只在仓库初始化时使用一次,创建仓库后就不需要重复执行。

2. 克隆(clone)

如果你想从远程服务器克隆下来一个仓库,那你需要使用到git clone命令,比如如果我想克隆Gitee上的一个开源框架Sa-Token的仓库 其url为 https://gitee.com/dromara/sa-token.git。那么我们可以这样使用

git clone https://gitee.com/dromara/sa-token.git

执行完上述步骤后,Git 会克隆远程仓库到本地,并在当前目录下创建一个与远程仓库同名的文件夹

从原理上来说,git clone实际上是一个封装了其他几个命令的命令。 它创建了一个新目录,切换到新的目录,然后 git init 来初始化一个空的 Git 仓库, 然后为你指定的 URL 添加一个(默认名称为 origin 的)远程仓库(git remote add),再针对远程仓库执行 git fetch,最后通过 git checkout 将远程仓库的最新提交检出到本地的工作目录

当然,他也有很多参数可选,一般来说常用的有以下几个

# -b 克隆后切换当前分支到 dev,如果不设置,默认当前分支为远程仓库的HEAD位置
git clone -b dev https://gitee.com/dromara/sa-token.git

# --single-branch 只克隆一个分支,此参数需要配合 -b,才能明确是要克隆哪个分支
git clone --single-branch -b dev https://gitee.com/dromara/sa-token.git

四、核心命令

如果说前面的命令用的频率较少,那么接下来我们就讲一些常用的核心命令

1. 添加至暂存区(add)

前面的文章,我们已经提到过暂存区的概念。本地仓库只接收暂存区里的东西,所以使用git add命令把文件添加进暂存区是必需的,比如我们想添加两个文件

git add ./file1.txt ./temp/file2.txt

当然,有时候我们不想一个个指定文件,那可以用下面的命令

# 不带参数,只有目录,代表把本目录所有修改过,和新建的文件加入暂存区。但被你删除的文件不会
git add .
# 更新暂存区已有的,即包括修改过的,和被你删除的,但不包括新建的文件
git add -u
# All 代表所有文件,包括你新增的、修改的、删除的
git add -A

另一个常见的参数是交互参数 -i,当你输入下面命令时,会出现交互

git add -i

image.png

在交互状态下,你可以输入小命令前面的数字来执行,这些小命令意思分别如下:

status        - 展示修改的文件位置
update        - 把工作区里修改的文件加入暂存区
revert        - 撤销暂存区里的修改
patch         - 选择性添加
diff          - 比较暂存区与本地仓库上一次内容之间的差异
add untracked - 把还没被git管理的文件添加到索引库中
quit          - 退出git add -i命令系统

2. 提交(commit)

如果你的暂存区已经有了内容,接下来你就可以将暂存区的内容提交至本地仓库,这个时候我们需要用到:

git commit

当然,一般情况下,我们每次提交都应当写一写提交信息,用于描述本次提交的作用

# 提交时添加提交信息
git commit -m "这是我的第一次提交"

3. 推送(push)

在完成提交后,我们的本地仓库就包含了我们的代码了,接下来,如果你对接了远程仓库,就可以把这部分内容从本地仓库推送至远程仓库了,这个时候我们要用到 git push 命令

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

如果本地分支名与远程分支名相同,则可以省略冒号,如我们要推送本地仓库的 dev 分支到远程仓库 dev 分支

git push origin dev

接下来我们列举一些参数供大家学习

# 设置远程仓库的 dev 分支为默认 push 目标,后续 push 可以省略参数
git push -u origin dev
# 强制推送,即将本地仓库的修改强制覆盖远程仓库的修改
git push -f origin dev
# 推送所有分支到远程仓库,包括新分支和删除的分支
git push --all origin
# 删除远程仓库的 dev 分支
git push origin --delete dev

4. 拉取(pull)

git pull命令用于从远程仓库中获取最新版本的代码并合并到本地仓库中,效果相当于git fetch + git merge,一般会这么使用

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

同push一样,如果本地分支名与远程分支名相同,则可以省略冒号,那么远程仓库 dev 分支拉取到本地 dev 就是如下:

git pull origin dev

需要注意的是,pull会同时更新本地工作区,但不会更新暂存区。同时,因为这里有着一个合并操作,所以其有着两种方式合并:rebase 或者 merge(默认)

# 将远程仓库的提交合并到本地仓库时使用 rebase (变基)方式,以使合并的提交历史更清晰和整洁
git pull --rebase origin dev

5. 分支(branch)

git branch 是git命令中的一个分支管理命令,用于列出、创建、重命名、删除等分支操作,它的主要用法,我进行了一个罗列:

git branch:列出所有本地分支。
git branch -r:列出所有远程分支。
git branch -a:列出所有本地和远程分支。
git branch <branchname>:创建一个新的分支。
git branch -d <branchname>:删除一个分支。
git branch -D <branchname>:强制删除一个分支。
git branch -m <newbranchname>:重命名一个分支。
git branch -vv:显示本地分支与远程分支的对应关系。
git branch -u <upstream>:将本地分支与远程分支建立跟踪关系。
git branch --merged:列出已经合并到当前分支的分支。
git branch --no-merged:列出未合并到当前分支的分支。
git branch --contains <commit>:列出包含指定提交的分支。
git branch --set-upstream-to=<upstream>:设置当前分支跟踪另一个远程分支。

例如,使用 git branch 命令可以列出所有本地分支:

$ git branch
  branch1
* master
  branch2

其中带 * 号的就是当前所在分支

6. 检出(checkout)

checkout的用法就是检出,但是它检出的内容多种多样,我们也进行一个列举:

  1. 切换分支
git checkout <branch_name>
  1. 创建新分支并切换到该分支,相当于执行以下两个命令:git branch <new_branch_name>git checkout <new_branch_name>
git checkout -b <branch_name>
  1. 恢复某个文件的修改,即撤销对某个文件的修改,还原到最近一次提交的状态。
git checkout <file_name>
  1. 恢复某个历史版本,切换到指定的历史版本。可以使用git log命令查看各个历史版本的commit id
git checkout <commit_id>
  1. 恢复某个文件在历史版本中的状态,将指定文件回滚到指定的历史版本中的状态。
git checkout <commit_id> <file_name>

7. 合并(merge)

一般我们的仓库都会有多个分支,比如当我们每做一个任务,就从开发分支(dev)新建一个分支(iss95)用来做任务,做完以后自然要合并。所以会用到git merge命令,注意,该命令是将其他分支的修改合并到当前分支,所以我们得先checkout 到 dev ,再进行合并

git checkout dev
git merge iss95

常用的git merge参数有不少,我们挑几个来说:

  1. squash

将所有合并提交压缩到一个新的提交中。这个选项通常用于将一个长期开发的功能分支合并到主分支中,比方说在iss95分支我们提交了很多次,如果我们直接git merge iss95,在后续我们进行历史查询时,就会把 iss95 的这么多次提交全查出来。这是因为合并后,F提交点相当于以后有两个父节点了
image.png

而如果我们使用的是命令 git merge iss95,就会把我们在c、d做的修改合并成一次,并且放在我们的暂存区中,等待我们的手动提交,如下

git merge --squash dev
git commit -m "Merged dev_branch changes"

image.png

  1. no-ff

--no-ff的意思为禁用快进合并,这将创建一个新的合并提交,即使分支已经可以直接合并。这样可以保证在历史记录中保留正确的分支信息。快速合并是GIT的一个机制,如果我们合并的两个分支,一个是另一个的祖先,那么并不会真正的“合并”,而是取了个巧,具体情况如下
image.png

masteriss95 祖先分支,如果我们要把 iss95 合并进 master,GIT就只会把分支master移动到iss95的位置,这就是所谓的“快速合并”
image.png

如果使用了 --no-ff,就是禁用快速合并。此时,就要求它必须会新建一个提交点。这样,我们就能得到更准确的记录了
image.png

8. 记录(log)

git log经常在追溯问题时使用,可以查看提交的历史,它常配合使用的参数如下

# 显示每个提交的详细修改信息。
git log -p
# 查看指定作者的提交记录
git log --author="author name":查看指定作者的提交记录

五、易混命令对比

1. fetch 和 pull

  • fetch

·fetch·只是将远程代码库的代码更新到本地代码库,不会自动合并代码。它会将远程代码库的提交记录下载下来,并更新远程分支。如果要将远程代码库的提交记录合并到本地代码库,需要手动执行·git merge·命令。
fetch的命令是:

git fetch [remote]

remote是远程代码库的名称,例如origin。如果省略remote,则默认使用origin。

  • pull

pull会首先执行fetch命令,然后自动将远程代码库的代码合并到本地代码库。如果有冲突,需要手动解决冲突并提交更改。如果没有冲突,pull会自动提交合并的更改。
pull的命令是:

git pull [remote] [branch]

remote是远程代码库的名称,branch是要拉取的分支名称。如果省略branch,则默认拉取当前分支。

  • 对比

因此,pullfetch的主要差异是:pull会自动将远程代码合并到本地代码库,而fetch只是将远程代码库的代码更新到本地代码库

pull可能会导致冲突,需要手动解决冲突并提交更改,而fetch不会导致冲突。

一般来说,如果你不确定要合并代码是否会导致冲突,可以先使用fetch命令拉取远程代码库的代码,然后手动执行git merge命令进行合并。如果你确定合并代码不会导致冲突,可以直接使用pull命令拉取远程代码库的代码并自动合并到本地代码库。

2. merge 与 rebase

这两者都可以用于合并不同的分支,假设这是我们目前的分支情况
image.png

  • merge

当我们切换至 master 分支,然后将 experiment 使用 merge 合并进来时

git checkout master
git merge experiment 

最终会产生一次新的提交C5,这种提交叫“合并提交”,与一般的提交不同,它有两个父节点,也就是说以后我们在分支 master 上还能看到*experiment * 的痕迹
image.png

  • rebase

而如果使用rebase,其实就是将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。

它的原理是首先找到这两个分支(即当前分支 experiment、变基操作的目标基底分支 master) 的最近共同祖先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件, 然后将当前分支指向目标基底 C3, 最后以此将之前另存为临时文件的修改依序应用

image.png

  • 对比

这两种整合方法的最终结果没有任何区别,但是变基使得提交历史更加整洁,所以说,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。 变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起

  • 变基的风险

需要注意的是,在某些复杂场景下,rebase 反而会导致提交历史混乱,具体的例子可以参考官方给出的一个示例:变基,因此,在无法防范的情况下,使用 merge 是最省心的

总结

今天我们讲了几乎都是GIT常用的核心命令,希望大家能都掌握。虽然在日常工作中,开发者的很多操作都是由可视化工具来完成的,但是也不能完全忘记命令的使用,这样即使后续出了问题,也能根据现象推断出大概解决方向,而不是越弄越糟。在GIT专栏后面的内容中,我们还会讲解一些冲突场景的预防及解决、常用的GIT工具等等。希望大家能够喜欢

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。