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工具创建的秘钥
相关推荐
Stara05111 小时前
Git推送+拉去+uwsgi+Nginx服务器部署项目
git·python·mysql·nginx·gitee·github·uwsgi
lsswear1 小时前
GIT 操作
git
勋勋勋勋小勋勋1 小时前
git分支合并某一次提交
git
PandaCave2 小时前
git常用命令以及注意事项总结
git
Lojarro13 小时前
【后端】版本控制
git·subversion
MengYiKeNan18 小时前
Git配置与使用
git
shall_zhao19 小时前
修改仓库中子模块并推送到远程仓库的指定分支
git
鱼钓猫的小鱼干21 小时前
Git 安装
git
子洋21 小时前
迁移 Gitlab 到 Forgejo
前端·git·后端