Git 01 入门与常用操作

Git 01 入门与常用操作

参考文献:稀土掘金 | ProGit2

与SVN的区别

SVN是集中式版本控制系统,其所有的版本管理都是集中在某个中央服务器,因此,在干活的时候,首先都需要从中央服务器中获取最新的版本,修改后将版本推送到中央服务器,因此大多数场景下需要进行联网使用。可能会更依托于相应的图形化客户端来进行同步和版本管理,便于管理美术资源等等。

GIT是分布式版本管理系统,每个人的电脑就是一个完整的版本库,可以进行独立的版本管理,多人协作可能依托于github之类的中继节点,将修改同步给对方,解决冲突。

初始化

包含ssh的详细指令在ssh的文档中,这边只介绍设置完这一系列操作之后的git初始化,主要是初始化ssh,并将私钥放到github或者gitee的账户中。
建议用Pc的名字来做标识

1
2
3
4
5
git config --global user.name "YourName"
git config --global user.email "YourEmailAdress"

# 查看相关的配置信息
git config --list

Github 设置

官方文档介绍的一些权限错误的地址:https://docs.github.com/en/github/authenticating-to-github/error-permission-denied-publickey

将本机的ssh公钥(public)放到GITHUB账户下的ssh管理地址,执行测试

1
ssh -T git@github.com

没有问题的话就可以直接进行clone,之类的git操作了

1
2
# 小trick,不拉取历史的commit
git clone --depth=1 REPO_ADRESS

Gitignore 文件编写

Git忽略提交规则 】【 gitignore 各语言模版

  1. 对文档创建相应的忽略文件,然后在里面编写要忽略的文件,文件夹就可以了
  2. 通过 VsCode 的插件或者直接使用上述语言模版的文件来创建初始化 ignore 文件。
1
touch .gitignore

Git 代理的设置与取消

设置全局代理使用如下的方式:

1
2
git config --global http.proxy 127.0.0.1:1080
git config --global https.proxy 127.0.0.1:1080

同理取消全局代理如下

1
2
git config --global --unset http.proxy  
git config --global --unset https.proxy

常用指令与工作流

Git 整体的工作流如下图所示,一般而言开发者在工作区进行当前修改,将需要同步或者发布的修改内容通过暂存区存储到本地 & 远程仓库中,结合远程仓库的协作特性和分支功能,可以实现同个项目的多人同步分离开发,同时开发多种功能等。

因此 Git 或者 Svn 等 CLI 的使用技能,在公司中或者在项目参与中是相当重要的,建议每个人程序开发者都能对其有一定的了解。

下面是一些基本的命令使用,其中许多命令都有一些额外的参数可供使用,如果经常使用 Git 建议可以简单阅读一下 ProGit。

这里会简单记录一些命令,其中那些在 git 使用中会有所提示的命令就不再赘述,例如 pull 别的分支的时候取消 merge 到当前分支的 git merge —abort 之类就会有所提示。

普通 command 分支 command
创建本地repo git init 创建/显示分支 git branch name
工作区状态 git status 切换分支 git checkout [branch]
添加到暂存区 git add /. 切换 git checkout -b name
暂存区到本地 git commit -m ‘mesg’ 合并分支 git merge branch
日志 git log (–oneline) 删除分支 git branch -d
拉取远程库 git pull / git fetch 推送本地分支 git push origin branch
克隆远程库 git clone
撤销 标签
撤销工作区修改 git checkout – file-name 创建标签 git tag tag-name
撤销暂存区修改 git reset HEAD file-name 显示所有标签 git tag
撤销本地库修改 git reset –hard commitID 删除标签 git tag -d tag
远程 储藏 ·
同步本地库和 git remote add origin xx@y repo 保存现场 git stash
远程库 git push -u origin master 恢复现场 git stash pop

Commit 规范和相关命令

commit 命令实现将”将暂存区的文件以特定的注释提交到仓库中”,提交的 Message 建议建立统一的规范,这样可以方便后续使用 log 查阅的时候定位到特定修改的 commit。

Message Standard 标准提交内容

本人推荐的 Commit Message 格式如下,该格式并非是一成不变的,可以根据仓库中存放的项目类型来灵活变更 Tag 的数量和内容。

1
git commit -m "[tag1(modify scope)] [tag2(modify type)]: excatly modify info"
  • Tag1 (modify scope): 说明修改的内容,泛一些例如修改代码 code,资源 res,细一些则例如修改的文件夹 tool、util
  • Tag2(modify type):说明修改的类型,主要有:FeatFixRefactorStyleTestDocsMerge,如果修改的是资源等文件可以忽略。
  • Modify info:修改的详细信息,说明修改的目的和修改的内容即可

例如以下的几个写法:

1
2
3
git commit -m "[res]: add presonal conf file"
git commit -m "[code-util][Feat]: add function to parser conf file"
git commit -m "[code & res][Feat & Fix]: add function for merge conf, fix bug on parser conf, add my conf resource"

该部分没有什么硬性要求,只需要自己能够清晰的看懂自己的 commit 且具备一致性即可。

Extra Operation 撤销、重写、合并

有时候针对已经提交的 Commit 不满意,或者有一些新的更改需要添加到上一次的 Commit 中,可以参考下面的操作。

撤销 Commit 或者重写 Commit Message

1
2
git reset --soft HEAD^  # 撤销当前commit
git commit --amend # 重写当前commit

合并多次 Commit:通过 rebase 命令来进行 merge,该命令通过整理多次的 Commit 来使得整个提交历史更为整洁有序,但是需要额外的精力去整理就是。具体的操作流程如下:

  1. 首先查看 commit 的 hash
1
git log
  1. 找到需要修改的 commit 的前一个 commit 的 ID
1
2
3
4
5
# 找到需要合并的最早commit的上一个的ID
git rebase -i <ID>

# 也可以使用以下命令合并header往前多少n次的commit
git rebase -i HEAD~n
  • square:将该次 commit 和上一次 commit 合并
  • pick:保留该次 commit

通过修改 commit 提交界面的 square 和 pick 即可实现多次 commit 的合并。

History 历史查看

查看当前分支的提交历史只需要通过 git log 即可看到基本的提交信息,这里简要介绍一些参数来帮助更清晰的定位 commit

  • git log -p -{n}: 参数 -p 以 diff 的形式在显示基本提交信息的基础上还显示该提交的具体修改内容,由于内容较多;可以通过 -{n} 仅显示最近 n 次提交的内容
  • git log --stat :参数 --stat 显示每次提交的统计信息,包含修改的文件以及对该文件修改的行数的统计信息
  • git log --graph: 参数 --graph 会使用简单的 ASCII 图像来可视化提交之间的分支关系,也就是 vscode 中 gitgraph 的命令行版本,可以帮助了解提交之间的合并和起始提交等信息

此外还有诸如 --pretty 等参数可以自定义 log 显示的具体格式,需要的话可以参阅 progit 或者官方文档进行了解。

Add 一些额外操作

Add 命令主要将修改的内容提交到暂存区,不仅可以作为我们一次次的中间存储节点,也是为后续的提交做缓冲,但是难免会遇到以下的情况:

  • 提交错文件或者修改了结构需要将一个或者多个文件从暂存区中撤退出来;
  • 清除工作区中不需要提交的临时文件

如果是撤销所有提交的文件:

1
git reset HEAD .

撤销特定文件的提交

1
git reset HEAD <file>

以上两个命令不需要记录,只需要使用 git status 查看当前状态的时候会有提示。

清除工作区中不需要提交的临时文件,可以使用以下的命令

1
2
git clean -nf # 查看会被清除的未追踪文件
git clean -f # 清除未追踪的文件

如果涉及到文件夹可以添加参数d

1
2
git clean -ndf # 查看会被清除的未追踪文件和文件夹
git clean -fd # 实际执行清除指令

其中-n 参数为查看而不实际执行的参数,避免文件的误删。具体可以通过 git help clean 查看。

远程协作

考虑多用户,多分支的在线场景,如何有效的Pull & Push.

在本地仓库切换默认提交用户

在多用户的终端场景,推送前记得切换相关的用户设置。

1
2
git config --local user.name "YourName"
git config --local user.emali "YourEmail"

推送、拉取远程分支

1
2
3
  # 冒号前本地,冒号后远程
git push origin local_branch:remote_branch
git pull origin remote_branch:local_branch

仅Clone指定分支

1
git clone -b {branch} {rep}

拉取代码解决冲突

git fetch 实际上 pull = fetch + merge,可以解决完冲突再进行代码提交,相对 pull 更安全,结合 Vscode 中的 Gitgraph 等,用于解决冲突和验证修改方面更为安全简单。

1
2
3
git fetch
git log -p FETCH_HEAD
git merge FETCH_HEAD

通过使用 Stash 的方式,同样可以避免再拉取远程代码的时候不覆盖本地的代码,灵活选用吧,一般情况下使用 fetch 已经足够。

CherryPick 挑选 Commit

仅简要介绍其作用,详细使用等后续有使用场景再来补充。

Git CherryPick 命令实现从别的分支挑选某个 Commit 的修改合并到当前分支中,该命令在一些提交数少的分支中,可以代替 merge,实现一个更为线性整洁的 Master 分支。

可以结合 Rebase 合并提交使用,由此得到一个更为干净的提交历史。

暂存区 & Stash

暂存区指的是 git add. 后存储到的区域,用来作为本地和仓库之间的缓存。

暂存区处理

清除暂存区某个文件的指令(通常是为了修改.gitignore)的时候执行

1
git rm -r --cache filename

看暂存区有什么文件

1
2
git ls-files
git status

stash 区域使用

是一个特殊的区域,本地的 git 存储区,一般来说使用场景较少,例如以下的场景。

本地改了代码,但是突然有个人过来问你另一个分支的问题,同时这个时候你在实现某个功能,实现一半,又不想提交到 Git 仓库中,那么你就可以考虑使用 git stash save "临时存一下",这个时候它就会帮你存到这个储存区,你去其他分支做完事情回来,再 git stash pop就好了。

主要使用的就是以下的几个命令:

  • git stash save "message" 将当前的修改暂存
  • git stash list 查看暂存了哪些修改
  • git pop 默认使用存储的堆栈中的第一个 stash
  • git stash apply stash@{n} 使用第 n+1个 stash,n 从0开始。

一般建议是不要使用太多的 stash,这样一个 save 和一个 pop 命令就可以 handle 。

一些工具

一些好用的 CLI(命令行工具)和 VsCode 插件推荐:

  • Lazygit(命令行工具,带一个比较酷炫的 GUI)
  • Gitlens(VsCode):在编辑界面显示每行代码的提交者,丰富 github 的 git 拓展选项
  • Gitgraph(VsCode):方便查看每次 commit 的修改内容,用对比窗口显示,便于发现冲突解决和修改内容
  • Beyond Compare(差异对比工具):类似 diff 命令,非常好用的对比和修改不同版本的文件,文件夹之间的差异。
  • Win Merge (差异对比工具): BC 的免费替代品,基本上是足够使用的。
  • 还有一些诸如 tortoise 和 github 客户端等图形界面也可供尝试

Troubleshooting

记录一些Git的问题,方便后续进行排查。

从Commit中删除大文件

避免.git目录占用过多存储,这一部分写的有点小瑕疵,到时候就看超链接

郑宇;主要是要将大文件排除追踪,在push之前都还是比较好解决的,但是如果已经提交上去了就稍微比较麻烦,尝试将其中的大文件删掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 1. 运行gc,生成pack文件`–prune = now` 表示对所有的文件都做修剪
git gc --prune=now

# 2. 找出最大的k个文件,以3为例
git verify -pack -v .git/objects/pack/*.idx |sort -k -3 -n |tail -3

# bug: cannot open ///bad ..
# 可能是由于地址出错了,修改地址,如下是查看地址的代码
find .git/objects/ -type -f

# 3. 查看那些大文件究竟是谁,按照上一步输出的hash value 进行搜索,(不用全长)
git rev-list --objects --all |grep <hashvalue>

# 4. 移除对该文件的追踪引用
git filter-branch --force --index-filter "git rm --cache --ignore-unmatch '<FILENAME HERER>'" --prune-empty --tag-name-filter cat -- --all

# 5. 进行repack
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now

# 6. 查看pack的空间使用情况
git count-objects -v

# 7. 强制推送重构大文件
git push origin local-b:remote-b --force

连接问题

  1. openssl error 10054
1
git config --global http.postBuffer 524288000
  1. time out port443

just wait for some time,应该是代理的问题,不行就使用国行版github把

  1. server certificate verification failed. CAfile

使用github.com.cnpmjs.org国内镜像站的时候,可能会出现权限的问题,这种情况下就要对git的证书验证命令做调整,有两种策略,执行其中一种:

1
git config --global http.sshverify false
1
2
# carry out in the 
export GIT_SSL_NO_VERIFY=1

之后我们就可以正常的使用镜像站对原有的repo进行更新和拉取了,比如说omz update.

ToBeContinue

Git 01 入门与常用操作

http://aikenh.cn/cn/Git_Manual1/

Author

AikenH

Posted on

2022-02-01

Updated on

2023-10-30

Licensed under


Comments