Git 的使用

前言

用了好几年的工具了,主要被我用来记录更新时候的点滴,有时回过头看看,一路上不太容易。对于以后日益复杂的项目, 会一点简单的 Git 指令显然是不能满足要求的,所以打算记录一些笔记,留给自己日后查阅使用。

基本操作

初始化仓库

mkdir file
cd file
git init

如果初始化成功,执行了git init命令的目录下就会生成 .git 目录。这个 .git 目录里存储着管理当前目录内容所需的仓库数据。 在 Git 中,将这个目录的内容称为“附属于该仓库的工作树”。 文件的编辑等操作在工作树中进行,然后记录到仓库中,以此管理文件的历史快照。如果想将文件恢复到原先的状态,可以从仓库中调取之前的快照,在工作树中打开。

查看仓库的状态

git status 命令用于显示 Git 仓库的状态。

向暂存区中添加文件

git add

如果只是用 Git 仓库的工作树创建了文件,那么该文件并不会被记
入 Git 仓库的版本管理对象当中。因此我们用 git status命令查看 README.md 文件时,它会显示在 Untracked files 里。要想让文件成为 Git 仓库的管理对象,就需要用git add命令将其 加入暂存区(Stage 或者 Index)中。暂存区是提交之前的一个临时区域。如果提交有错误,想强制提交的话,可用如下指令

git add --ignore-errors --force .

保存仓库的历史记录

git commit

git commit 命令可以将当前暂存区中的文件实际保存到仓库的历 史记录中。通过这些记录,就可以在工作树中复原文件。

记述一行提交信息

git commit -m "First commit"

-m 参数后的 "First commit"称作提交信息,是对这个提交的 记述详细提交信息概述。

记述详细提交信息

如果想要记述得更加详细,请不加 -m,直接执行git commit命令。执行后编辑器就会启动,并显示如下结果。下面的代码前面都有#号,因为在我这编译的时候会有问题,所以就没加上去。

Please enter the commit message for your changes. Lines starting
with '#' will be ignored, and an empty message aborts the commit.

On branch master

Initial commit

Changes to be committed:
new file: readme.md

在编辑器中记述提交信息的格式如下。

第一行:用一行文字简述提交的更改内容

第二行:空行

第三行以后:记述更改的原因和详细内容

只要按照上面的格式输入,今后便可以通过确认日志的命令或工具看到这些记录。在以 # 标为注释的 Changes to be committed(要提交的更改)栏中,可以查看本次提交中包含的文件。将提交信息按格式 记述完毕后,请保存并关闭编辑器,以 #(井号)标为注释的行不必删除。随后,刚才记述的提交信息就会被提交。

中止提交

如果在编辑器启动后想中止提交,请将提交信息留空并直接关闭编辑器,随后提交就会被中止。

查看提交日志

git log

git log命令可以查看以往仓库中提交的日志。包括可以查看什么人在什么时候进行了提交或合并,以及操作前后有怎样的差别。

只显示提交信息的第一行

如果只想让程序显示第一行简述信息,可以在 git log命令后加上 --pretty=short。这样一来开发人员就能够更轻松地把握多个提交。

只显示指定目录、文件的日志

只要在git log命令后加上目录名,便会只显示该目录下的日志。 如果加的是文件名,就会只显示与该文件相关的日志。

git log README.md

显示文件的改动

如果想查看提交所带来的改动,可以加上-p参数,文件的前后差 别就会显示在提交信息之后。

git log -p

分支的操作

在进行多个并行作业时,我们会用到分支。在这类并行开发的过程中,往往同时存在多个最新代码状态。从 master 分支创 建 A 分支和 B 分支后,每个分支中都拥有自己的最新代码。 master 分支是 Git 默认创建的分支,因此基本上所有开发都是以这个分支为中心进行的

不同分支中,可以同时进行完全不同的作业。等该分支的作业完成之后再与 master 分支合并。如下所示

分支查看与切换

查看所有分支

git branch -a

查看当前使用分支

git branch

切换分支

git checkout 分支名

切换回上一个分支

git checkout -

新建分支并切换

想要新建一个分支并同时切换到那个分支上,可使用如下命令(如创建dev并切换):

git checkout -b dev

合并分支

假设 A 已经实现完毕,想要将它合并到主干分支 master 中。首先切换到 master 分支。

git checkout master

然后合并 feature-A 分支。为了在历史记录中明确记录下本次分支合并,需要创建合并提交。因此,在合并时加上 --no-ff参数。

git merge --no-ff A

图表形式查看分支

git log --graph

用 git log --graph 命令进行查看的话,能很清楚地看到分支A提交的内容已被合并。

更改提交的操作

回溯历史版本

git reset

修复未提交文件中的错误(重置)

git reset --hard HEAD

这条件命令会把你工作目录中所有未提交的内容清空。

修复已提交文件中的错误

1, 创建一个新的提交(commit),在新的提交里撤消老的提交所作的修改。

2, 也可以去修改你的老提交(old commit)。但是如果你已经把代码发布了,那么千万别这么做;Git 不会处理项目的历史会改变的情况,如果一个分支的历史被改变了那以后就不能正常的合并。

没有 add(没有添加到暂存区)

撤销全部文件修改:

git checkout -- .

这个是我在犯傻后用argdo %s /old/new/g,发现修改的东西太多了,发现的一个有用的功能;

创建新提交来修复错误

创建一个新的,撤消(revert)了前期修改的提交(commit)是很容易的;只要把出错的提交(commit)的名字(reference)做为参数传给命令:git revert就可以了;

git revert HEAD

撤消“上上次”(next-to-last)的提交:

git revert HEAD^

git revert其实不会直接创建一个提交(commit),把撤消后的文件内容放到索引(index)里,你需要再执行git commit命令,它们才会成为真正的提交(commit)。

修改提交来修复错误

git commit现在支持一个叫–amend的参数,它能让你修改刚才的这个提交(HEAD commit)。这项机制能让你在代码发布前,添加一些新的文件或是修改你的提交注释(commit message)。

如果你在老提交(older commit)里发现一个错误,但是现在还没有发布到代码服务器上。你可以使用git rebase命令的交互模式,git rebase -i会提示你在编辑中做相关的修改。这样其实就是让你在 rebase 的过程来修改提交。

乱码解决办法

在git bash查看日志的时候发现乱码,需要更改一下相关设置即可,在窗口点击右键,选择 Options -> Text, 找到 Locale,Charector set, 并进行如下设置。

然后在命令窗口中输入如下设置命令即可

git config --global i18n.commitencoding utf-8
git config --global i18n.logoutputencoding utf-8
export LESSCHARSET=utf-8

常用指令的具体介绍

git clean

要取消已经track过的文件的修改,可以使用git checkout xxx,但是如果要取消 untracked 文件的修改,除了手动删除,还可以用 git clean 命令实现

删除 untracked files

git clean -f

删除 untracked 文件和目录

git clean -df

连 gitignore 的 untracked 文件和目录也一起删掉

git clean -xdf

建议加上-n参数来看看会删掉哪些文件,防止重要文件被误删。

git clean -nf
git clean -ndf
git clean -nxdf

git diff

git diff 命令可以对比两个版本的差异,具体来说包括:

1, 本地工作区和暂存区的diff信息:git diff 或者 git diff file
2, 暂存区和版本库的diff信息(使用git add 将工作区修改保存到了暂存区后):git diff --cached
3, 版本库中不同commit、分支的diff信息(使用git commit 将暂存区修改提交到了版本库):git diff commit1 commit2 或 git diff branch1 branch2
4, 技巧:一般将要对比的分支/commitID名字放到第二个参数,这样对比起来比较直观。

1)基本操作

git diff branch1 branch2 --stat //--stat参数,显示两分支简单diff信息
git diff branch1 branch2 //显示两分支详细的diff信息
git diff branch1 branch2 path //显示两分支指定路径下文件的详细diff信息
git diff branch1 branch2 file_name(带路径) //显示两分支指定文件的详细diff信息

注:这里的分支可以是本地的,也可以是远程的(git diff branch1 origin/branch2)

git tag

Git 标签(Tag)是用于在代码库中标记某个特定提交(commit)的方式。标签通常用于标识发布版本或重要的里程碑,以便于追踪和管理代码库的发展历史。下面详细介绍了 Git 中标签的常用操作:

创建标签

创建一个轻量级标签:

git tag tag_name

创建一个带有注释的标签

个人最喜欢的方式创建标签:

git tag -a tag_name -m "Tag message"

查看标签

查看所有标签:

git tag

查看特定标签的详细信息

git show tag_name

推送标签到远程仓库

推送单个标签:

git push origin tag_name

推送所有标签:

git push origin --tags

删除标签

删除本地标签

删除一个本地标签:

git tag -d tag_name

删除远程标签

首先删除本地标签:

git tag -d tag_name

然后删除远程标签:

git push origin :refs/tags/tag_name

切换到标签对应的提交

创建一个新分支并切换到标签对应的提交:

git checkout -b new_branch_name tag_name

检出标签的特定文件版本

git checkout tag_name -- file_path

在标签上创建新分支

git checkout -b new_branch_name tag_name

列出与标签相关的提交:

git log tag_name^..tag_name

对以前提交的信息打标签

git log --pretty=oneline

上面这条命令显示了全部的commit id信息,简短点的commit 信息,看下面的命令:

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

代码冲突检测

在多人同时修改同一个文件或者同一个代码库时,就可能出现冲突。如果有人在本地已经修改了某个文件并提交了,但另一个人在远程也修改了这个文件并提交了,这时候就会出现冲突。

检查是否存在冲突

通过以下命令检查当前文件是否存在冲突:

git status

如果出现类似如下输出,则说明当前文件存在冲突:

On branch master
You have unmerged paths.
(fix conflicts run "git commit")

查看冲突文件

在检查出存在冲突后,我们需要查看具体哪些文件存在冲突,可以通过以下命令查看:

git diff --name-only --diff-filter=U

遇到的问题

无法推送

已明确账号密码输入无误,在 git bash 里面无法推送自己的代码,其报错如下:

Logon failed, use ctrl+c to cancel basic credential prompt.
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.

有一种可能,由于git 升级,执行 git update-git-for-windows, 更新后推送报了一个新的错误

SSL certificate problem: unable to get local issuer certificate

解决方式,输入如下指令

git config --global http.sslVerify false

提交中文字符乱码问题

这个问题主要是在Windows下使用git bash时候遇到的, 从以下几个步骤可以解决这个问题

1, 确认本地git配置

git config --global -l

看输出的结果里面有没有包含下面两条信息

core.quotepath=false
i18n.commitencoding=UTF-8

2, 若不存在,输入如下指令

git config --global core.quotepath false
git config --global i18n.commitencoding UTF-8

3, 将文件字符集设置为UTF-8,可以保证中文字符在git提交后不会乱码。

git config --global core.autocrlf true
git config --global core.safecrlf true
git config --global core.quotepath false
git config --global i18n.commitencoding UTF-8
git config --global i18n.logoutputencoding UTF-8

fatal: LF would be replace by CRLF

这个问题会导致往仓库推的时候推不上去,解决办法如下,在shell中输入如下指令

git config --local core.autocrlf false

可根据自己的需要,将local替换成global;

下载大文件

在 Git 里直接下载大文件通常会遇到限制(例如 GitHub 的单文件大小 100MB 上限,整个仓库 2GB 以上推送困难)

使用 Git LFS (Large File Storage)

# 安装 Git LFS
git lfs install

# 选择要用 LFS 管理的文件类型(例如 .zip 或 .mp4)
git lfs track "*.zip"

# 添加 .gitattributes 配置
git add .gitattributes
git commit -m "Track large files with Git LFS"

# 正常 add + commit + push
git add large_file.zip
git commit -m "Add large file"
git push origin main

下载时,Git 会只拉取指针文件,LFS 会在后台同步大文件。

安装 Git LFS 的方法

Linux (Ubuntu/Debian)

sudo apt update
sudo apt install git-lfs -y
git lfs install

macOS (Homebrew)

brew install git-lfs
git lfs install

Windows

去 Git LFS 官方下载页面:https://git-lfs.github.com/

下载 Git LFS installer for Windows,安装完成后重新打开终端。

设置 Git 的默认编辑器为 Vim

git config --global core.editor "vim"

参考

[1]《GitHub 入门》

[2] web3

[3] GIT使用log命令显示中文乱码

[4] Python 技术站

[5] git diff

[6] chatGPT 的回答

知识共享许可协议