状态类指令
git branch: 查看当前本地所处的 branch、本地中拉的所有的branchgit branch -r: 查看远程所有的分支git statusorgit st: 当前所处 branch、是否有需要 commit 的git log: 查看当前 branch 的所有提交记录git log --oneline: 查看当前 branch 的所有提交记录,每行只显示 commit id 和 commit message- 先 cd
到某一个子目录下查看该目录的提交记录,如
cd kernel/drivers/再执行git log --oneline - 也可以 cd
到某个目录下查看某个具体文件的提交记录,如
cd kernel/drivers/再执行git log -p -- ./pci/pci-acpi.c
- 先 cd
到某一个子目录下查看该目录的提交记录,如
git show -1: 查看当前 branch 的最新一次提交记录git show <commit id>git log --pretty=format:"%cd %h %s" --date=short: 显示当前 branch 的所有提交记录,每行只显示 commit id、commit message、提交时间
git mm 特有的指令:
git mm sync -j64: 64线程同步远程代码
查看本地 git 分支的状态树:
git log --graph --oneline --decorate --all: 显示当前分支的提交记录树状图--oneline: 显示每行只显示 commit id、commit message--decorate: 显示分支、tag、commit id--all: 显示所有分支
代码提交、合并、push到远程仓库
1)代码提交:暂时不推到远程仓中
1 | git add . # 添加所有文件 |
2)拉取代码
切换分支
切换前最好先暂存一下当前的代码修改内容:
1 | 暂存当前修改,需要切到修改的子仓库下 |
然后再切换到分支中:
1 | git checkout old_branch # 切换到旧分支old_branch中 |
有两种方法可以切换到某次提交中:git checkout <commit-hash>
或者 git reset --hard <commit-hash>
(其中要注意,切换到后面的提交后git log就看不到最新的commit
id了,所以最好是创建一个分支,或者先把最新的commit
id记下,可以通过git tag给commit打标签)
1 | git checkout <commit id> # 此时会切到 HEAD detached 状态,不属于任何分支,所以需要切回某个分支 |
后面有需要的话还要恢复到暂存状态(恢复暂存代码):
1 | 恢复特定的 stash (例如:stash@{2}) |
修改完代码也可以取消修改:
1 | git restore ./* # 取消当前目录下所有修改 |
查看分支领先/落后提交数
git branch -v --abbrev=0
删除分支
删除分支前需查看分支是否已经合并:
git branch --merged
删除分支前先切换到其他分支中:
git checkout master
删除某个已经被合并的分支:
git branch -d <branch_name>
删除未合并的分支(强制删除):
git branch -D <branch_name>
diff 查看修改内容
git diff <filrname.c>git statusgit diff <old_commit_id> <new_commit_id>:顺序很重要,git diff A B 表示从 A 提交到 B 的修改,B 一般是比较新的提交,A 一般是比比较旧的提交git diff --numstat <commit id>: 显示每个文件修改的行数(添加、删除、修改)git show --stat <commit id>: 统计修改的行数(添加、删除、修改)git stash show -p stash@{0}:显示当前stash某个暂存内容的diff情况
制作.patch文件存储当前工作夹的修改
针对某个文件
导出未commit提交的patch:
git diff > xxx.patch,可以指定文件名xxx.patch导出最近 n 次提交:
git format-patch -n,生成 n 个独立的 patch 文件
记事本打开这个文件就能看到你的修改内容
通过.patch文件恢复代码
git apply xxx.patch
撤销修改
git stash -m "message": 会暂存修改并恢复到未修改状态git restore .: 取消当前目录下所有修改,且不会暂存
在一个已有内容的文件夹下将该内容同步到新的仓库中
1 | git init # 初始化一个git仓库 |
如果原先没有关联过其他仓库,那么还得进行一些分支的操作,如果之前已经有分支,那么可以直接push到新仓库中
1 | git branch --set-upstream-to=origin/master master # 设置当前分支的远程分支 |
然后就可以观察远程仓库上是不是已经被 push 上去了
git am 拉取邮件补丁
下载并添加补丁(能丝滑成功的话)
从所订阅的 Linux 模块中拼凑下面的链接,并找到相应的补丁进行下载:
从Linux KVM - Patchwork中找到对应的patch,逐个点击保存所有的子patch
- 下载后得到的文件为:
v1-1-5-arm64-sysreg-add-HDBSS-related-register-information.patch
- 下载后得到的文件为:
在 Linux 源码仓库根目录下应用(推荐):
1
2
3cd ~/linux # 这里是你 clone 下来的主线源码目录
git checkout -b feat-hdbss # 建议新建一个分支,避免污染主线代码
git am /path/to/*.patch这样就会把整个 patch 系列应用到当前分支。
当然 patch 有可能是很久以前写的,跟当前最新 master
分支的代码不兼容,导致 git am
命令失败。此时需要更换为git am --3way命令,并手动解决冲突rebase。
patch合入失败时rebase
方法:从主线上一个一个patch进行rebase
如果git am直接报error的话,是不给我们 merge
的机会的,此时先git am --abort然后git am --3way,用这种方式来添加patch,然后手动
rebase
git am --3way xxx.patch:添加patch
git am --3way --keep-no-patch:添加patch,并保留没有冲突的文件
此时git status后就能看到需要我们手动 rebase 的文件:
git status查看Umerged的文件,然后手动修改Unmerged的文件
修改完后执行以下语句:
1 | git add <修改的文件名> |
然后重复上面所有步骤,直到所有patch全部被添加进来
对于 git am --3way 依然解决不了的问题,通过 .rej 手动解决
1 | [shell]git am --3way v1-4-5-arm64-kvm-support-to-handle-the-HDBSSF-event.patch |
用git bash强制应用补丁,再手动处理问题文件。具体步骤如下:
1)
执行git am --3way --ignore-space-change --keep-cr --reject xxx.patch。其中--reject指示工具将patch不可应用的部分保存为*.rej文件。
- 如果补丁缺少 index
信息用
git apply --reject --ignore-space-change,但是这种方式需要自己重新commit,不推荐
2)打开*.rej会有没添加的patch相关代码内容,手动修改相应未生效patch的文件。然后删除.rej文件。
3)执行git add。将所有需要提交的文件添加到缓存区。因为应用失败,所以应用patch过程停在了修改文件的流程,需要我们手动修改和提交,完成工具无法自动完成的流程。
4)执行git am --continue。继续完成补丁的应用,成功即表示应用patch生效。
步骤 1) 执行后的结果:
1 | [zhengtian@localhost linux]$ git am --3way --ignore-space-change --keep-cr --reject v1-4-5-arm64-kvm-support-to-handle-the-HDBSSF-event.patch |
添加进来patch后,可以删除.rej文件,然后将当前的修改合入到仓库中:
1 | git log --oneline |
在 v1 作者 patch 的基础上作为新的 v2 作者制作 patch:rebase 方法
如果在处理后面几个patch时,发现前面的patch又需要修改,此时可以用rebase指令暂时停在之前的patch中,修改完再返回:
1 | git rebase -i 438883838b9e^ |
^:该提交的父提交(即它的前一个提交),加上^后的 edit 选择才能包含 438883838b9e
然后在交互式界面中,初始显示全是
pick,把你要修改的那一条标记为 edit,保存后
Git 会停在那个 commit:
1 | edit 438883838b9e arm64/sysreg: add HDBSS related register information |
注意:上面的显示内容是从 旧提交->最新提交
的顺序进行显示的。
然后会暂时回到 438883838b9e 处,给一个修改之前的commit的机会,修改完可以先编译运行一下:
1 | # 修改代码 |
如果 patch 做了大修改,已经跟原来的 commit info 不一样了,就必须修改 commit info,否则保持原来的信息即可。
在 git commit --amend 后在 commit 信息中添加自己的邮箱:
1 | git commit --amend 后在commit 信息中添加自己的邮箱 |
然后就可以保存一下当前的新patch
1 | git format-patch -1 |
最后继续 rebase:
1 | git rebase --continue |
如果重复上面的修改步骤,把所有patch都修改完了的话,可以制作该serial的所有patch,在最后一个patch commit中,执行以下指令:
1 | git format-patch -v2 HEAD~5 |
- HEAD~5:表示从当前分支的最近 5 个提交中,生成一个 v2 版本的 patch 系列,每个提交对应一个 .patch 文件。
- -v2:表示这是 patch 的第 2 个版本,Git 会在每个 patch 的标题中自动加上 [v2,1/5]、[v2,2/5] 等前缀
如果是多个 patch,在发送邮件前,可以用下面的指令生成一些列带 序号、封面的patches:
1 | git format-patch --numbered -n --cover-letter --subject-prefix='PATCH' -v2 |
其中的 n 是提交个数
生成patches后打开 0/5 这个 patch 修改里面的信息。
用 linux 工具检查 patch 是否符合内核编码风格(如缩进、注释、空行、函数命名等)
scripts/checkpatch.pl --strict --file xxx.patch
查出问题可以手动修复,也可以尝试用 linux 自带的工具进行修复:
scripts/checkpatch.pl --fix-inplace xxx.patch
经常会出现末尾带一个空格的问题,所以可以通过下面的指令删除:
sed -i 's/[[:space:]]*$//' xxx.patch
回合同步主线
将分支切到master中,然后拉取最新代码:
1 | git checkout master |
然后回到我们当前coding的分支,merge master 的最新代码:
1 | git checkout <branch-name> |
此时可能会有一些冲突,需要手动解决就行。
1 | <<<<<<< HEAD |
然后git add标记为已解决
1 | git add . |
1 | git commit # 完成合并 |
git 中对 commit 的坏点二分法查找
- 找到一个好点 commit id:
- 找到一个坏点 commit id:
在<commit_id_good> ~ <commit_id_bad>区间内,肯定能找到因为引入了某个
1 | git bisect start |
重复完上面的二分步骤后,最终会找到一个首次引入该问题的