Git使用

首先介绍下使用的工具及插件,Git, TortoiseGit, VSCode插件(Git History,Git Graph)

下载安装Git:Git - Downloads

下载安装TortoiseGit及语言包:Download -- TortoiseGit -- Windows Shell Interface to Git

Think in Git

四个区域

当 `clone` 仓库代码到本地后四个区相同

当编辑代码后,`工作区` 与其余三个区不同

当使用 `add` 将修改的代码暂存后,`索引区`与 `工作区` 相同

当使用 `commit` 将修改的代码提交后,`仓库区` 与 `索引区` 和 `工作区` 相同

当使用 `push` 将修改的代码推送后,四个区的信息又再次相同

工作区 Workspace

从远程区获取代码使用 `pull(fetch + checkout)`

从仓库区获取代码使用 `checkout`

向索引区添加代码使用 `add`

索引区 Index / Stage

向仓库区提交代码使用 `commit`

移除代码到工作区 `reset`

仓库区 Repository

从远程区获取代码使用 `fetch/clone`

向远程区推送代码使用 `push`

从索引区得到代码使用 `commit`

向工作区检出代码使用 `checkout`

远程区 Remote

从仓库区获取代码使用 `push`

特殊文件

FETCH_HEAD

每个分支对应一行,记录最后一次 `fetch/pull` 下来对应分支的最新 `commitID`

HEAD

记录当前分支,`ref: refs/heads/<br>`

ORIG_HEAD

当执行 `reset/merge/rebase` 操作时记录原本 `HEAD` 值

COMMIT_EDITMSG

记录最后一次 `commit` 时填写的日志信息

配置

首要配置

bash 复制代码
git config --global user.name "YourName"
git config --global user.email "YourEmail"
bash 复制代码
# 基础命令
git config --system/global/local
  --get
  --add
  --unset
  -l, --list

# 配置默认提交信息模板
git config --global commit.template '~/commit-template'

# 配置默认提交信息编辑器
git config --global core.editor "vim"

# 证书校验
git config --global http.sslverify false

# 禁止文件中文名转义
git config --global core.quotepath off
# 在git为2.36.1的版本中, core.quotepath 默认设置为 true,
# 在git输出路径指令时, 控制字符、用反斜杠转译的字符或者字节树大于0x80被认为是"不寻常"的字符
# 如果该变量设置为false, 则这些字符不会被认为是异常字符, 会正确按照UTF-8编码展示

# 代理
git config --local/global/system http.proxy <addr>
git config --local/global/system https.proxy <addr>

秘钥创建

bash 复制代码
# 使用rsa算法为<邮箱地址>这个内容生成大小在2048B以下的秘钥文件test
# 同时还会有公钥文件test.pub生成
# 若不指定-f参数则会在~/.ssh/下生成秘钥文件id_rsa和公钥文件id_rsa.pub
ssh-keygen -t rsa -C "邮箱地址" -b 2048 -f test

# 将公钥信息添加到github等托管平台
# 测试是否添加成功
ssh -T git@github.com

常见问题

  1. 使用ssh -T git@github.com测试时报错Permission denied,修改如下文件权限即可:
  • id_rsa文件的权限是 -rw-------
  • id_rsa.pub文件的权限是 -rw-rw-r--

多账户

  1. 使用-f参数创建多个秘钥并添加到对应平台
  2. 修改~/.ssh/config,格式如下
  3. 测试 ssh -T <主机名>
  4. 新格式仓库地址:<主机名>:<仓库所有者>/<仓库名>.git
bash 复制代码
# ~/.ssh/config
# 主机名随意,但须保证文件内唯一
Host <主机名>
  # 托管平台,有很多,常用的有github, gitee, gitlab
  HostName github.com
  # 用户名固定是git
  User git
  # 对应平台的秘钥文件
  IdentityFile <秘钥文件>

# 此时<主机名>等效于git@github.com
# 原本使用的仓库地址git@github.com:<仓库所有者>/<仓库名>.git
# 等效的新格式仓库地址<主机名>:<仓库所有者>/<仓库名>.git

托管平台

gitlab

设置中文显示:Settings -> Preferences -> Localization -> Language

gitee

邮箱管理,禁止命令行推送暴露个人邮箱:开启后账号绑定的邮箱将无法推送

命令别名

bash 复制代码
# vim ~/.bashrc
# 增加如下内容
alias gr='git remote show origin'
alias gb='git branch'
alias gbv='git branch -vv'
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias gco='git checkout'
alias gp='git pull'
alias gps='git push'
alias grh='git reset --hard HEAD~1'
alias grs='git reset --soft HEAD~1'
alias grm='git reset --mixed HEAD~1'
alias gd='git diff'
alias gl='git log'

clone

bash 复制代码
git clone URL -b BRANCH path
  --depth 1       # 日志中只有最近1次提交
  --bare          # 以镜像的形式拉取代码
  --mirror        # 以镜像的形式拉取代码,与--bare相比,--mirror不仅将源的本地分支映射到目标的本地分支,还映射所有引用

commit

bash 复制代码
# 将添加到索引区的文件提交到仓库区
git commit
  -s, --signoff   # 提交日志中自动在最后追加Signed-off-by信息行
  --amend         # 追加到上一次commit中, --no-edit表示不对提交信息进行修改
  -e, --edit      # 弹窗编辑框编辑提交说明
  -n, --no-verify # 不启用pre-commit和commit-msg

# 允许不提交任何文件,目的是触发CI可能是
git commit --allow-empty -m "chore: re-trigger build"

# 允许不填写提交日志
git commit --allow-empty-message

push

bash 复制代码
# 推送到远端
git push <alias> <br>:<rbr> # 远端没有rbr分支则创建,但不会自动建立跟踪
git push <alias> :<rbr>     # 删除远端分支

fetch

bash 复制代码
# 拉取所有远端仓库中所有分支
git fetch # FETCH_HEAD 记录所有远端仓库中所有分支最新 commitID

# 拉取某个远端仓库中所有分支
git fetch <alias> # FETCH_HEAD 记录某个远端仓库中所有分支最新 commitID

# 拉取某个远端仓库中某个分支
git fetch <alias> <br> # FETCH_HEAD 记录某个远端仓库中某个分支最新 commitID

pull

bash 复制代码
# 更新代码到本地分支
git pull
git pull <alias>
git pull <alias> rbr    # 导致FETCH_HEAD有只有一条
git pull <alias> rbr:br # 导致FETCH_HEAD有只有一条
git pull --rebase       # 使用rebase合并代码

merge

bash 复制代码
# 整理差异产生新提交
git merge <br>       # 将br分支合并到当前分支
git merge --continue # 解决完冲突后继续合并
git merge --abort    # 取消本地合并,回到操作前,没有代码残留
git merge --quit     # 终止,有提交和代码残留
# 当<br>完全包含当前分支提交时,当前分支直接指向<br>即可,快读合并

# 其他参数
-ff     # 默认使能,对于那些不可能执行快速合并的情况下加不加没有分别
--no-ff # 取消,即使完全包括也会产生一次提交留痕

cherry-pick

bash 复制代码
# 指定某次提交
git cherry-pick <commitID>
# 后面跟两个提交表示范围(], 左开右闭合;若想实现[]则需要使用commitID^

# 分支的最新提交
git cherry-pick <br>

rebase

bash 复制代码
# 在目标分支上 cherry-pick 本分支提交
# rebase, "移动"目标提交到本分支,遍历本分支提交产生新的提交追加目标提交后
# 目标未修改, 不做处理
#  --no-ff   # 不难理解,不使用快速合并。由于目标未修改,所以没有"移动"动作,直接遍历本分支提交产生新的提交追加目标提交后
# 本分支未修改, 本分支直接指向目标分支
#  --no-ff   # 不难理解,不使用快速合并。"移动"目标提交到本分支,由于本分支没有提交,则不会产生新的提交,就像是直接指向目标分支一样

git rebase -i HEAD~2
  p, pick <commitID>   # 保持不变
  r, reword <commitID> # 保持该提交,但会编辑提交信息
  e, edit <commitID>   # 保持该提交,后续使用git commit --amend修改提交内容及信息,然后使用git rebase --continue继续
  s, squash <commitID> # 将本提交合并到上一次提交中,然后编辑提交信息

format-patch和am

bash 复制代码
git format-patch -n  # 当前分支最近n次提交
git am <>            # 应用补丁

reset

bash 复制代码
# 操作HEAD的指向,修改当前分支仓库区提交树
git reset option commitID
  --soft   # 不碰索引区和工作区,只修改HEAD指向
  --mixed  # 不碰工作区,重置索引区,修改HEAD指向
  --hard   # 重置工作区和索引区,修改HEAD指向
  --merge
  --keep

revert

bash 复制代码
git revert option commitID
  -n, --no-commit  # 不直接提交,恢复的文件保存在本地索引区
  --no-edit        # 不弹出编辑日志界面,直接提交
# 恢复 commitIDA 到 commitIDB, 验证失败
git revert option commitIDA..commitIDB

# 恢复完冲突了
git revert --abort
git revert --quit

clean

bash 复制代码
# 默认值删除未被版本控制的文件,通过下列选修改删除的范围
git clean -n # 演习,告知哪些文件会被删除
git clean -d # 删除目录,默认情况下不会删除未被版本控制的文件夹及其子文件
git clean -x # 删除忽略文件,默认情况下不会删除忽略的文件
git clean -X # 只删除忽略文件
git clean -f # 强制

remote

复制代码
git remote, 显示所有远端库别名
  origin
git remote -v, 显示所有远端库别名 + url,每个别名都有与之对应的fetch(下载)和push(上传)地址
  origin  https://gitee.com/zhangguangxuan/Documents.git (fetch)
  origin  https://gitee.com/zhangguangxuan/Documents.git (push)
git remote show origin
  * remote origin
    Fetch URL: https://gitee.com/zhangguangxuan/Documents.git
    Push  URL: https://gitee.com/zhangguangxuan/Documents.git
    HEAD branch: master
    Remote branch: 远端分支
      master tracked(已跟踪)
      ...
    Local branch configured for 'git pull': 本地可直接git pull的分支
      master merges with remote master
      ...
    Local ref configured for 'git push': 本地可直接git push的分支
      master pushes to master (up to date)
      ...
git remote add alias url
git remote prune alias, 删除远端库中不存在的分支
git remote rename old_alias new_alias
git remote update
git remote get-url alias

stash

复制代码
git stash [save]
pop `<ID>` 弹出ID号暂存修改作用于当前分支,默认最新
apply `<ID>` 提取ID号暂存修改作用于当前分支,默认最新
create 创建暂存
store `<ID>` 将暂存存到栈中
branch `<ID>` 弹出ID号暂存创建分支,默认罪行
clear 删除所有暂存
drop `<ID>` 删除ID号暂存
list 显示所有暂存,ID号暂存,在某分支上,路径信息
 stash@{0}: On sanjuan/master: systemtest/configs/
show `<ID>` 显示ID号暂存修改,默认最新

diff

复制代码
git diff      按行显示修改
  --word-diff   按单词显示修改
git diff --name-only FETCH_HEAD..FETCH_HEAD^
git show commitId, 查看修改的详情

# 显示大量的文件mode被修改
git config --global core.filemode false

submodule

复制代码
# 添加子模块
git submodule add git@ssh:xxx.git pod-library

git submodule update --init --recursive

git submodule foreach git pull

branch管理

bash 复制代码
# 创建本地分支
git branch <br>                    # 创建后不会切换分支,不会建立跟踪
git checkout -b <br>               # 切换分支,若不存在则创建,存在则报错,不会建立跟踪
git checkout -b <br> origin /<rbr> # 切换分支,若不存在则创建,与远端建立跟踪

# 推送本地分支
git push origin <br>[:<rbr>] # 将分支推送到远端,但不会建立跟踪

# 删除本地分支
git branch -d <br> # 有代码未合并会提示错误
git branch -D <br>

# 删除远端分支
git push origin :<br>
git push origin --delete <br>

# 建立分支跟踪
git branch --set-upstream-to=origin/<rbr> [<br>]

# 其他参数
-a        # 所有分支
-r        # 远端分支
-m        # 移动(重命名)分支
-M        # 强制移动(重命名)分支

tag管理

bash 复制代码
# 创建本地标签
git tag <tag> [<commitID>]

# 推送本地标签
git push origin <tag>[:<tag>]
git push origin --tags # 推送所有tag

# 删除本地分支
git tag -d <tag>
git tag -D <tag>

# 删除远端分支
git push origin :regs/tags/<tag>
git push origin --delete <tag>

# 其他参数
-l 所有tag

查看日志

git log

复制代码
commit <commitID>
Author: <user><<email>>
Date:   <time>

    <info>

    Change-Id: <changeID>

git log -p

复制代码
# 在 git log 的基础上追加补丁信息
diff --git <file> <file>
index 54f466c..292b0df 100755
--- <file>
+++ <file>
@@ -252,7 +252,7 @@
         .............

git log --stat

复制代码
# 在 git log 的基础上追加各个文件修改行信息
<file> | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

# 不携带具体文件信息
--shortstat
1 file changed, 1 insertion(+), 1 deletion(-)

git log --name-only

复制代码
# 在 git log 的基础上追加修改的文件
<file>

# 携带文件修改状态
--name-status
M       <file>

git log --pretty=<>

复制代码
oneline == git log --oneline, 只有 commit(短) msg
medium     默认
short      比默认少 Date 和 Change-Id, 即,只有 commit Author msg
full       比默认多 Commit Merge, 少 Date
fuller     比full多 AuthorDate CommitDate
email
  From <commitID> <time>
  From: <user> <<email>>
  Date: <time>
  Subject: [PATCH] <info>

  Change-Id: <changeID>
raw        比默认多 tree parent committer, 少 Date
format:
  %H  显示hash
  %h  提交对象的简短哈希字串
  %T  树对象(tree)的完整哈希字串
  %t  树对象的简短哈希字串
  %P  显示父节点hash
  %p  父对象的简短哈希字串
  %ad 显示作者时间 Mon May 15 09:40:07 2023 +0800
  %cd 显示提交时间 Mon May 15 09:40:07 2023 +0800
    --date=format:%Y-%m-%d %H:%M:%S 指定时间显示格式
  %ae 显示作者邮箱
  %ce 显示提交者邮箱
  %an 作者(author)的名字
  %cn 提交者(committer)的名字
  %ar 作者修订日期,按多久以前的方式显示
  %cr 提交日期,按多久以前的方式显示
  %s  显示主题
  %b  显示内容

git log --date=<>

复制代码
relative == git log --relative-date
local       本地时间
iso         ISO 8601 format
rfc         RFC 2822 format
short       YYYY-MM-DD format
raw         %s %z format
format
  %a:星期缩写, Tue
  %A:星期全称, Tuesday
  %b:月份缩写, Jul
  %B:月份全称, July
  %c:时间全称, Tue 04 Jul 2023 02:24:58 PM GMT
  %d:日期 (01 -- 31), 04
  %H:小时 (00 -- 23), 14
  %I:小时 (01 -- 12), 02
  %j:一年中第几天 (001 -- 366), 185
  %m:月份 (01 -- 12), 07
  %M:分钟 (00 -- 59), 27
  %p:上午下午, AM/PM
  %S:秒数 (00 -- 59), 58
  %U:一年中的第几周,周日为一周的开始 (00 -- 53), 27
  %w:星期编号 (0 -- 6; 周日 is 0), 2
  %W:一年中的第几周,周以为一周的开始 (00 -- 53), 27
  %x:本时区的日期, 07/04/2023
  %X:本时区的时间, 02:24:58 PM
  %y:2位年份 (00 -- 99), 23
  %Y:4位年份, 2023
  %z, %Z:时区编号和时区名称缩写, +0000 GMT
  %%:Percent sign

其他参数

复制代码
# 显示7位commit
--abbrev-commit

# 显示提交时间与当前时间差
--relative-date

# 显示 graph 信息
--graph

显示数量

复制代码
-n          显示前n条
--after     在之后
--until     结束时间
--before    在之前
--since     开始时间
--author    作者
--grep      内容
--          文件
<br>        分支
--branches  所有分支,只是本地的所有分支
--no-merges 忽略合并的提交,两个分支合并代码时可能出现两个父节点的节点,该节点就是合并的提交,同理还有--merges参数

TortoiseGit

秘钥工具

复制代码
设置 -> 网络 -> SSH客户端
C:\Program Files\Git\usr\bin\ssh.exe, 使用 ssh-keygen -t rsa -C '邮箱'创建的秘钥, 位置在~/.ssh/id_rsa.pub
C:\Program Files\TortoiseGit\bin\TortoiseGitPlink.exe, 使用PuTTY Key Generator工具创建的秘钥
相关推荐
MatrixOrigin7 小时前
MatrixOne Git4Data 技术详解(二):从零跑通所有 Git 原语
git
anew___7 小时前
常用的 Git 工作流
git
shimly1234567 小时前
git diff 生成一部分文件的补丁
git
m0_579146658 小时前
Git 重置模式详解:四种重置方式的原理与应用场景
git
恋喵大鲤鱼8 小时前
git grep
git·git grep
霸王龙的小胳膊9 小时前
Git基础知识
git
恋喵大鲤鱼9 小时前
git fetch
git·git fetch
Java知识技术分享10 小时前
安装sourcetree
java·git·源代码管理
恋喵大鲤鱼10 小时前
git revert
git·git revert
爱和冰阔落10 小时前
【Codex项目实战】从模糊需求到可验证交付:Plan、测试、Review与Worktree完整流程
人工智能·git·codex