git使用记录

本文记录git使用过程中用到的一些功能

git ssh设置代理

在没有设置代理的情况下,git拉取 更新偶尔无法成功,在~/.ssh/config加入如下的配置

1
2
3
4
5
Host github.com
HostName github.com
User git
# socks代理
ProxyCommand nc -v -x 127.0.0.1:1089 %h %p

测试ssh是否能连接github.com

1
2
3
jack@linux:~/Documents/source/vim (master) $ ssh -T git@github.com
Connection to github.com 22 port [tcp/ssh] succeeded!
Hi JackHuang021! You've successfully authenticated, but GitHub does not provide shell access.

创建worktree

在各个差异较大的分支中切换,工程需要做全局编译,导致开发效率下降,创建worktree可以在多个分支并行开发,从而实多个工程环境的缓存,达到提升开发效率的目的,特点:

  • 可为一个分支创建一个工作区
  • 每个工作区的工程环境独立运行
  • 每个工作区共享同一个版本仓库信息

相比通过git clone方式创建多个独立工程环境的工作区,git worktree的优点在于:

  • 更节省硬盘空间git clone方式下,每个工作区都有一个版本仓库,git worktree方式下,每个工作区共享同一个版本仓库,节省了n-1/n(n为工作区数量)的硬盘空间
  • 各个工作区之间的更新同步更快git clone方式下,A工作区和B工作区同步更新的步骤,A工作区commit -> A工作区push -> B工作区pull,git worktree方式下,A工作区只要本地提交更新后,其他工作区就能立即收到

git worktree使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 进入工程目录
cd path/to/project

# 查看worktree信息
git worktree list

# 创建worktree
git worktree add worktree test_branch

# 进入工作区worktree上进行开发
cd worktree

# 删除工作区
git worktree remove path/to/worktree

合并其他分支commit到当前分支

使用git cherry-pick将其他分支的commit合并到另一个分支

1
git cherry-pick <commit-id>

同时也支持批量合并,一次可以cherry-pick一个区间内的commit

1
git cherry-pick <start-commit-id>..<end-commit-id>

git生成patch

使用git format-patch生成patch

1
2
3
4
5
6
7
8
9
10
11
12
# 生成单个commit的patch
git format-patch -1 <commit id>

# 生成最近1次commit的patch
git format-patch HEAD^

# 生成最近2次commit的patch
git format-patch HEAD^^

# 生成两个commit间的修改的patch
# 生成的patch不包含commit id1
git format-patch <commit id1>..<commit id2>

合入patch

1
2
3
4
5
# 检查patch是否能正常合入
git apply --check <path/to/patch>

# 合入patch
git apply <path/to/patch>

git PR过程

  1. 在Git主页fork开源项目,然后将fork后的项目仓库clone到本地

    1
    git clone git@gitlab.phytium.com.cn:huangjie1663/linux-kernel.git
  2. 添加远程代码仓库地址

    1
    2
    3
    4
    5
    6
    jack@linux: git remote add upstream git@gitlab.phytium.com.cn:embedded/linux/linux-kernel.git
    jack@linux: git remote -v
    origin git@gitlab.phytium.com.cn:huangjie1663/linux-kernel.git (fetch)
    origin git@gitlab.phytium.com.cn:huangjie1663/linux-kernel.git (push)
    upstream git@gitlab.phytium.com.cn:embedded/linux/linux-kernel.git (fetch)
    upstream git@gitlab.phytium.com.cn:embedded/linux/linux-kernel.git (push)

    这时总共包含三个仓库信息:本地仓库、origin仓库、upstream仓库

  3. 更新git remote中所有远程仓库所包含分支的最新commit,并合并upstream

    1
    2
    git fetch upstream
    git merge upstream/branch

git代码回滚

git代码回滚常用的两种方式:git revertgit reset

git reset,将提交的commit从历史记录中删除,用途如下:

  • 新提交的commit有问题,想要撤销该笔提交,并保留修改的内容git reset --soft HEAD^
  • 撤销新提交的commit,不保留修改的内容git reset --hard HEAD^

git暂存文件转为unstage

1
2
3
4
5
# 当前所有暂存文件全部转为unstage状态
git restore --staged .

# 将某个暂存文件转为unstage状态
git restore --staged <filename>

git bisect定位问题

git bisect命令使用二分搜索算法来查找提交历史中的哪一次提交引入了错误,只需要告诉这个命令一个包含该bug的坏commit ID和一个引入该bug之前的好commit ID,这个命令会用二分法在这两个提交之间选择一个中间的commit ID,切换到那个commit ID的代码,然后询问你这是好的commit ID还是坏的commit ID,你告诉它是好还是坏,然后它会不断缩小范围,直到找到那次引入bug的commit ID