Git 使用总结

本文针对版本管理工具 Git 的使用进行归纳总结,以供查阅,仅用于个人学习。

Git 分支图

全文所用 Git 版本为:git version 2.37.3.windows.1

Git 基本原理

Git 是一个开源的分布式版本控制系统,也是计算机专业找工作的必备技能之一,其最初由 Linux Torvalds (Linux 之父) 创造,于 2005 年发布。其大致工作流程如下图:

Git 工作流程

创建版本库(又名仓库,repository):

mkdir myRepository
cd myRepository
git init # 初始化

拉取已存在的远程版本库:

git clone <remote_url>
# eg. git clone git@github.com:LiuPiPiPi/LPxz.git

查看本地 Git:

git config # 本地配置
git help # 帮助

仓库管理

git areas

Git 使用三种不同版本的文件添加和检索提交的工作流程,工作区用于编写更改,暂存区用于暂存更改,本地仓库指向开发者在 Git 存储库中对分支的最后一次提交。

暂存区

文件保存成二进制对象以后,还需要通知 Git 哪些文件发生了变动。所有变动的文件,Git 都记录在一个区域,叫做”暂存区”(index 或 stage)。等到变动告一段落,再统一把暂存区里面的文件写入正式的版本历史。

git add <file/dir> # 将文件或文件目录加入暂存区
git add <file1/dir1> <file2/dir2> # 将多个文件或文件目录加入暂存区
git add *.html # 使用通配符方式批量添加文件

git add . # 添加所有已改动文件
git add all
# 所在目录不同导致的差异:
# 1) git add all 无论在哪个目录执行都会提交相应文件
# 2) git add . 只能够提交当前目录或者它后代目录下相应文件

忽略文件:

git rm [-f] <file1> <file2> # 删除暂存区和工作区中的文件,可强制删除
git rm --cached <file> # 删除暂存区中的文件,但仍保留在工作区中
git rm –r * # 递归删除整个目录中的所有子目录和文件

stash 常用来保存和恢复工作进度,该命令只对被 git 跟踪的文件有效。这是一个非常有用的命令

# 保存当前工作进度,将工作区和暂存区恢复到修改之前。默认 message 为当前分支最后一次 commit 的 message
git stash
# 作用同上,message 为此次进度保存的说明
git stash save message
# 显示此次工作进度做了哪些文件行数的变化,此命令的 stash@{num} 是可选项,不带此项则默认显示最近一次的工作进度相当于 git stash show stash@{0}
git stash show stash@{num}
# 显示此次工作进度做了哪些具体的代码改动,此命令的 stash@{num} 是可选项,不带此项则默认显示最近一次的工作进度相当于 git stash show stash@{0} -p
git stash show stash@{num} -p
# 显示保存的工作进度列表,编号越小代表保存进度的时间越近
git stash list
# 恢复工作进度到工作区,此命令的 stash@{num} 是可选项,在多个工作进度中可以选择恢复,不带此项则默认恢复最近的一次进度相当于 git stash pop stash@{0}
git stash pop stash@{num}
# 恢复工作进度到工作区且该工作进度可重复恢复,此命令的 stash@{num} 是可选项,在多个工作进度中可以选择恢复,不带此项则默认恢复最近的一次进度相当于 git stash apply stash@{0}
git stash apply stash@{num}
# 删除一条保存的工作进度,此命令的 stash@{num} 是可选项,在多个工作进度中可以选择删除,不带此项则默认删除最近的一次进度相当于 git stash drop stash@{0}
git stash drop stash@{num}
# 删除所有保存的工作进度
git stash clear

本地仓库

暂存区保留本次变动的文件信息,等到修改了差不多了,就要把这些信息写入本地仓库,这就相当于生成了当前项目的一个快照(snapshot)。

git status # 查看当前版本库的状态

# 改动不需要执行 git add 命令,直接提交
git commit -a
# 提交改动,附带提交记录,-am 不需要执行 git add 命令
git commit -m | -am "message"
# 在不增加一个新 commit 的情况下将新修改的代码追加到前一次的 commit 中,会弹出一个界面重写 message
# --no-edit 表示不需要再修改 message 信息
git commit --amend [--no-edit]

# 提交一次没有任何改动的空提交,常用于触发远程 CI
git commit --allow-empty -m "message"
# 修改 commit 时间
git commit -m "message" --date="Wed May 27 00:35:36 2020 +0800"

远程仓库

fetch 用于从远程获取对象和引用到本地:

# 取回指定远程仓库的所有分支
git fetch <remote>
# 取回指定远程仓库的指定分支
git fetch <remote> <branch>
# 取回所有远程仓库的所有分支
git fetch --all

pull 用于从远程获取代码并合并本地的版本,其实就是 git fetchgit merge FETCH_HEAD 的简写:

# 拉取项目,相当于 fetch + merge
git pull <remote> <branch>:<local_branch>
# 相当于 fetch + rebase
git pull --rebase <remote> <branch>:<local_branch>

push 用于将本地版本库的分支推送到远程服务器上对应的分支:

# 推送提交,可强制执行
git push [--force] <remote> <local_branch>:<branch>
# 本地分支名与远程分支名相同
# -u 表示绑定指定分支
git push [-u] <remote> <branch>

管理远程仓库:

# 修改远程仓库地址
git remote set-url <remote> <remote-url>
# 仓库路径查询查询
git remote -v
# 添加远程仓库
git remote add <remote> <url>
# 删除指定的远程仓库
git remote rm <remote>

分支操作

查看分支

# 查看本地分支和当前分支
git branch
# 查看本地分支对应的远程分支
git branch -vv
# 查看远程分支
git branch -r
# 查看本地分支和远程分支
git branch -a

编辑分支

# 新建分支(还在当前分支中),可强制覆盖
git branch [-f] <branch>
# 修改本地分支名称
git branch -m <branch> <new_branch>
# 将本地分支与远程分支建立追踪关系
git branch --set-upstream <local_branch> <remote>/<branch>

# 基于当前所在分支新建一个赤裸分支,该分支没有任何的提交历史但包含当前分支的所有内容
# 相当于 git checkout -b <new_branch> 和 git reset --soft <first_commit_id> 两条命令 
git checkout --orphan <new_branch>

# 删除本地分支,-D 为强制删除
git branch -d | -D <branch>
# 删除远程分支
git push <remote> :<branch>

切换分支

# 切换到指定分支
git checkout <branch>
# 在当前位置新建分支并切换
git checkout -b <branch>
# 在指定 commit 上新建分支并切换
git checkout -b <branch> <commit_id>

版本操作

合并操作

git merge 用于将两个或两个以上的开发历史合并在一起的操作:

# 合并某个分支
git merge <branch>
# 退出 merge 过程,常在处理冲突出错时使用
git merge --abort
# 继续 merge 过程,常在处理完冲突时使用
git merge --continue

git rebase 相比 merge,合并分支历史的另一种管理方式:

# 变基某个分支
git rebase <branch>
# 退出 rebase 过程,常在处理冲突出错时使用
git rebase --abort
# 继续 rebase 过程,常在处理完冲突时使用
git rebase --continue

# 合并 n 个 commit
git rebase -i HEAD~n
# 将 (from_commit, to_commit] 上的所有 commit 合并到指定分支上,类似于 cherry-pick 多个提交
git rebase --onto <branch> <from_commit> <to_commit>

git cherry-pick 用于将指定的 commit 应用于其他分支:

# 将指定的提交应用于当前分支
git cherry-pick <commit_id>
# 将指定分支的最近一次提交应用于当前分支
git cherry-pick <branch>

# 将指定的两个提交先后应用于当前分支
git cherry-pick <commit_id1> <commit_id2>
# 将指定范围内的多个提交(不包含 commit_id1,包含 commit_id2)先后应用于当前分支
git cherry-pick <commit_id1>..<commit_id2>
# 将指定范围内的多个提交(包含 commit_id1,包含 commit_id2)先后应用于当前分支
git cherry-pick <commit_id1>^..<commit_id2>

# 退出 cherry-pick 过程,常在处理冲突出错时使用
git cherry-pick --abort
# 继续 cherry-pick 过程,常在处理完冲突时使用
git cherry-pick --continue

回滚操作

本地撤销暂存区的相关命令:

# 将暂存区的所有改动撤销到工作区
git reset (--mixed) HEAD
# HEAD 表示当前版本,上一个版本是 HEAD@{1},向上 100 个版本是 HEAD@{100}
git reset --hard HEAD@{num}

# 放弃工作区所有文件的变更(不包含未跟踪的)
git checkout .
# 放弃工作区中某个文件的修改(先使用 git status 列出文件)
git checkout -- <file>
# 强制放弃暂存区和工作区的改动
git checkout -f

本地撤销 commit 的相关命令:

git reset --soft | --mixed | --hard
# --soft 回退 HEAD,保留工作区、暂存区,使用 git commit 再次提交
# --mixed 回退 HEAD、暂存区,保留工作区,再次提交时需要 git add
# --hard 回退 HEAD、暂存区、工作区(危险操作),源码和 commit 都会回滚

# 常用于合并多个 commit,类似于 squash
git reset --soft <commit_id>/<branch>
# 常用于移出暂存区的文件以作为 add 命令的反动作
git reset (--mixed) <commit_id>/<branch>
# 常用于无条件放弃本地所有变更以向远程分支同步
git reset --hard <commit_id>/<branch>

Tips: git reset 实际执行的是 HEAD 的指向的回退,指定回到某个 commit,那么 HEAD 指针就会回退到对应的 commit。这些操作都是本地执行的,如果想要推送到远程仓库(这是危险操作,因为会修改提交历史),那么需要强制执行 push 操作:

git push --force <remote> <branch>

远程回滚 commit 的相关命令:

# 切换到指定 commit
git checkout <commit_id>
# 回滚指定的提交
git revert <commit_id>
# 回滚不包括 commit1,但包括 commit2 的一串提交
# revert 命令会对每个回滚的 commit 进行一次提交,--no-commit 可以最后一起手动提交
git revert [--no-commit] <commit1>...<commit2>

# 退出 revert 过程,常在处理冲突出错时使用
git revert --abort
# 继续 revert 过程,常在处理完冲突时使用
git revert --continue

标注 tag

为什么有必要使用 git tag?

每一个提交都有一个 commit ID,但是每次记录 commit ID 都很复杂,使用 git tag 可以在一些重要的版本和修改中加入一个标识,可以很快速的找到我们需要的版本。

tag 常用于发布版本的管理,是指向某个 commit 的指针:

# 查看所有 tag / 特定 tag
git tag [-l] [<tagName>]
# 基于本地当前分支最后一个 commit 创建 tag
git tag <tagName> 
# 基于指定 commit 创建 tag
git tag <tagName> <commit_id>
# 基于指定 commit 创建 tag 并指定 message
git tag -a <tagName> -m "message"

# 切换到指定 v1.2 的标签
git checkout tags/v1.2
# 删除本地指定 tag
git tag -d <tagName>

# 远程推送一个 tag
git push <remote> <tagName>
# 删除一个远程 tag
git push origin :<tagName>
# 向远程推送本地所有 tag
git push --tags <remote>

版本对比

diff 用来比较文件之间的不同:

# 查看工作区与暂存区所有文件的变更
git diff
# 查看暂存区与最后一次 commit 之间所有文件的变更
git diff --cached
# 查看工作区与最后一次 commit 之间所有文件的变更
git diff HEAD
# 查看两次 commit 之间的变动
git diff <commit_id>...<commit_id>
# 查看两个分支上最后一次 commit 的内容差别
git diff <branch>...<branch>

日志查询

git log 命令用于查看提交的 Git 历史记录信息,同时,git log 命令可以通过多种不同的参数,定制显示的样式。

日志按照修改时间从上往下为近到远(按 q 退出查询):

# 查看当前分支所有日志
git log
# 查看特定开发者的提交记录
git log --author=<username>
# 压缩后的每一条提交记录只占一行
git log --pretty=oneline

# 通过树形结构来展示所有的分支, 每个分支都标示了名字和标签
# --oneline 哈希值只显示部分
# --decorate 显示对应 commit 所属的 branch 和 tag 信息
# --graph 绘制一个 ASCII 图像来展示提交历史的分支结构,类似于一个树形结构
git log --graph --oneline --decorate --all

# 查看文件改动
git log --name-status
# 输出文件增删改的统计数据(-p 参数更为详细)
git log --stat | -p

# todo
git reflog

# 更多命令
git log --help

相关链接

Tips

1) 限制 clone 深度,加快下载速度

仅是 clone 此仓库学习(不是参与翻译工作)的话,请使用如下 Git 命令:

git clone --depth 1 https://github.com/labuladong/fucking-algorithm.git

这样会限制 clone 的深度,不会下载 Git 协作的历史记录,可以极大加快下载速度。

2) 初始化本地项目到 Git 仓库

# 初始化本地仓库
git init
# 将本地内容添加至git索引中
git add .
# 将索引添加至本地仓库中
git commit -m "first commit"
# 添加远程仓库路径
git remote add origin https://github.com/coderliguoqing/vans.git
# 将本地内容push至远程仓库中
git push -u origin master

3) Git 关闭换行符提示

git config --global core.autocrlf false

4) CentOS 7 安装最新版 Git

参考:https://www.cnblogs.com/wayne173/p/9483008.html

安装方法有两种:

一、yum 命令安装,此方法简单,自动安装依赖的包,傻瓜式安装,而且会从源里安装最新的版本,不过不一定是 Git 最新的。

sudo yum install git

二、源码安装,这个比较麻烦,不过过程还是比较清晰的,毕竟源码安装也比较普遍

1、安装前手动安装下依赖包,可以直接是用 yum 安装

yum install -y wget
yum install gcc
yum install gcc-c++
yum install -y zlib-devel
yum install -y perl-ExtUtils-MakeMaker package

2、官网下载最新版本的 Git 源码包

wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.18.0.tar.gz

3、接下来就是解压,配置安装

tar -zxvf git-2.18.0.tar.gz
cd git-2.18.0
./configure --prefix=/usr/local/git
make
make install

4、设置环境变量 PATH,可以随处使用 Git

echo "export PATH=$PATH:/usr/local/git/bin">>/etc/bashrc
source /etc/bashrc
git --version

5、查看版本

# 如果之前安装了别的版本
sudo yum remove git
source /etc/bashrc
git --version

5) SSH 密钥配置

命令行输入 ssh-keygen -t rsa -C "xxx@mail.com" 生成公钥文件,复制 /root/.ssh/id_rsa.pub 中的内容,访问 Github 个人设置页面,在“SSH and GPG keys”选项卡中粘贴刚才复制的公钥信息。


Git 使用总结
http://lpxz.work/posts/62460/
作者
LPxz
发布于
2022年11月10日
许可协议