zl程序教程

您现在的位置是:首页 >  工具

当前栏目

git:总结

Git 总结
2023-09-14 09:13:13 时间

gerrit 权限配置的建议

https://osm.etsi.org/gerrit/Documentation/access-control.html#category_forge_author

git 在 detach的状态时

一定要注意,在这种状态下只能做测试,不能做submit操作。原因是可能导致以下错误:
Change 111: Depends on change that was not submitted. Commit 333 depends on commit 333, which is outdated patch set 3 of change 444. The latest patch set is 4.
这个脱离状态,不能拿到444的最新的patch set4,而 333 的父commit,只到444的patch set3,所以提示上面这个错误。
而且在脱离状态,有不能从远端拿到patch set4,做不了 333的 amend,最终导致死循环。
解决方法:https://blog.csdn.net/u011240877/article/details/76273335
简单粗暴的方法:将git 切换到想要的branch,然后将刚才的333 merge 过来。

git detach 出现的一个情况
当使用git branch -r的时候,可能会出现;
origin/18.8
origin/19.0
origin/19.5
origin/20.0
当我们使用 git checkout origin/20.0的时候,就可能出现detach的状态,因为 实际的branch的名称是20.0.

git-bisect

https://ruanyifeng.com/blog/2018/12/git-bisect.html
二分法查找问题引入点。
实例:
https://bugzilla.kernel.org/show_bug.cgi?id=10002

git gc

git gc, 清理不必要的文件,优化本地的仓库。garbage collector
在当前目录执行一些清理任务,如:压缩文件版本信息(以减小磁盘使用空间,增加性能),删除不能访问到的对象,(这些对象可能由之前的操作产生,如:git add, packing refs, 清理reflog,等等。May also update ancillary indexes such as the commit-graph.

When common porcelain operations that create objects are run, they will check whether the repository has grown substantially since the last maintenance, and if so run git gc automatically. See gc.auto below for how to disable this behavior.

git prune

prune,这个单词是:修剪,删除。怎么搞都是要去除出去一部分事物。是git gc要执行的一部分任务。
解决办法,直接运行 git prune,删除不必要,访问不到的文件。
See “git help gc” for manual housekeeping.
error: The last gc run reported the following. Please correct the root cause and remove .git/gc.log.
Automatic cleanup will not be performed until the file is removed.

warning: There are too many unreachable loose objects; run ‘git prune’ to remove them.

First, rewinding head to replay your work on top of it…
Applying: ABC-ABC-commit
Auto packing the repository in background for optimum performance.
See “git help gc” for manual housekeeping.
error: The last gc run reported the following. Please correct the root cause
and remove .git/gc.log.
Automatic cleanup will not be performed until the file is removed.

warning: There are too many unreachable loose objects; run ‘git prune’ to remove them.

代码重构,对git blame的冲击

在看kernel的源码时发现,代码重构对代码查阅有一定阻碍,因为有些数据结构/函数不在原来的位置,需要借助git更详细的功能,才能查阅到。

获取repo的url

git remote -v
$ git remote -v
origin https://github.com/bminor/glibc.git (fetch)
origin https://github.com/bminor/glibc.git (push)

从当前commit 删除一个文件的修改

git reset --soft HEAD^
退回到之前的commit
git reset HEAD path/to/unwanted_file (sp/mt.c)
把要删除修改的文件,reset到之前的版本
然后重新做commit;
之前那个commit就可以abandoned掉了

不需要的文件的修改还会保留一份出来。
Changes not staged for commit:
(use “git add …” to update what will be committed)
(use “git checkout – …” to discard changes in working directory)

    modified:   sp/mt.c

生成一个git server repo

https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server

设置proxy

git config --global --add http.proxy http://

mzhan017@MINGW64 /c/open_source
$ git config --get http.proxy
http://11.1.1.1:8080

mzhan017@MINGW64 /c/open_source
$ git config --global --unset http.proxy
warning: http.proxy has multiple values , 如果出现这个警告,就用下面 unset-all
$ git config --global --unset-all http.proxy

windows 版的git 工具

WSL

https://wiki.ubuntu.com/WSL; 这个没有尝试过。看着都麻烦。

git

这个需要注意的问题是,需要设置目录的大小写敏感项设置,不然如果源代码里有大小写敏感的文件。导致文件名重复。例如 在库里有两个文件, A.c 和a.c 这两个文件,没有问题,clone到windows后,就变成了一个文件。会有后续git操作错误。
另一种解决方法,不要在库里创建这种需要大小写区分的文件。一劳永逸。

cygwin

最好不要用这个,之前用过,不是太好用。好几年之前的事情了,不知道现在怎么用。

grep

git grep -n code-code, 这个命令可以很好的用来做代码搜索
git grep -w __preempt_count, 按照单词过滤,整个词匹配。
git grep ‘time_t’ – ‘*.[ch]’
Looks for time_t in all tracked .c and .h files in the working directory and its subdirectories.
git grep -e ‘#define’ --and ( -e MAX_PATH -e PATH_MAX )
Looks for a line that has #define and either MAX_PATH or PATH_MAX.
git grep --all-match -e NODE -e Unexpected
Looks for a line that has NODE or Unexpected in files that have lines that match both.
git grep solution – :^Documentation
Looks for solution, excluding files in Documentation.

生成key

[root@localhost ~]# ssh-keygen -t ed25519 -C “mzhan017@qq.com” generate public key.
-t 算法类型, 默认是 rsa
-C comments, 默认是当前机器的hostname
Generating public/private ed25519 key pair.
Enter file in which to save the key (/root/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_ed25519.
Your public key has been saved in /root/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:5FrnNjHO5C1vsCn5mmQ mzhan017@qq.com
The key’s randomart image is:
±-[ED25519 256]–+
| . |
| o . |
|. = + o |
| + + O = o |
| o o… |
±—[SHA256]-----+
[root@localhost ~]# cd
[root@localhost ~]# cd .ssh
[root@localhost .ssh]# ls
id_ed25519 id_ed25519.pub known_hosts
[root@localhost .ssh]# more id_ed25519
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1fmqaM58H8rHf7D3hB
iy9mkFc0PXFkqHbGwuY29tAQID
-----END OPENSSH PRIVATE KEY-----
[root@localhost .ssh]# more id_ed25519.pub copy the content to gerrit website.
ssh-ed25519 AAAFkqHhPcecm mzhan017@qq.com
这里可以看到最后的公共key里还有 命令里指定的 算法和comment。

git bisect

利用二分法,寻找带有bug的 commit
实例:https://dirtypipe.cm4all.com/
https://git-scm.com/docs/git-bisect

git blame

如何实现github 这个 “view blame prior to this change”
在这里插入图片描述https://stackoverflow.com/questions/5098256/git-blame-prior-commits

git blame -L 10,+1 fe25b6d^ – src/options.cpp 这里fe25b6d是一个commit,这里的意思是要看这个commit之前的blame信息。默认是从Head 开始blame。

错误

$ git blame -L 330,+20 607ca46e97a1b^ - include/uapi/linux/rtnetlink.h
fatal: no such path include/uapi/linux/rtnetlink.h in 607ca46e97a1b^
这个错误的原因是在607ca46e97a1b 这个commit里新建了这个文件,如果要找这个commit之前的文件修改记录肯定是空。

git check out

git checkout 还原文件

下面这个命令可以:创建一个branch 名字是tmp,最后一个commit 是f316f6abb388d0326c8969a98e3a7de04072d827 这个之前的一个commit、同时切换到这个tmp branch。
git checkout -b tmp f316f6abb388d2d827^

checkout 基于tag

git checkout tags/ -b
写上tag,然后带着branch的名称。

git cherry-pick

如果直接在gerrit上cherry-pick 别人的commit,会说没有权限,需要在git repo里将别人的commit cherry-pick 过来。
git cherry-pick [–edit] [-n] [-m parent-number] [-s] [-x] [–ff] [-S[]] …​
git cherry-pick (–continue | --skip | --abort | --quit)

–edit、-e ,带着这个选项,在commit之前,允许修改commit信息。
给定一个或多个commit,然后根据每个commit的修改,单独创建新的多个commit。需要确保当前的工作目录是干净的(从HEAD commit开始,没有修改记录)。

如果cherry-pick出现错误:当前版本的HEAD指针指向最新的一次成功commit。CHERRY_PICK_HEAD指向了难于应用的commit。
Paths in which the change applied cleanly are updated both in the index file and in your working tree.
For conflicting paths, the index file records up to three versions, as described in the “TRUE MERGE” section of git-merge(1). The working tree files will include a description of the conflict bracketed by the usual conflict markers <<<<<<< and >>>>>>>.
No other modifications are made.
See git-merge(1) for some hints on resolving such conflicts.

子命令

–continue
Continue the operation in progress using the information in .git/sequencer. Can be used to continue after resolving conflicts in a failed cherry-pick or revert.
–skip
Skip the current commit and continue with the rest of the sequence.
–quit
Forget about the current operation in progress. Can be used to clear the sequencer state after a failed cherry-pick or revert.
–abort
Cancel the operation and return to the pre-sequence state.

git pull --rebase --autostash

https://tomkadwill.com/git-reset-or-git-pull
git pull 包含两个步骤:
git fetch

git merge origin/
做第二步的目的是为了方便,当前如果有commit没有submit,可以自动做merge。
所以如果没有这个目的情况下,可以仅使用git fetch 命令获取远端的数据。

有时候会出现这种错误:

$ git pull -f
error: cannot pull with rebase: You have unstaged changes.
error: please commit or stash them.

可以用这个autostash的参数来跳过错误,直接pull。

git config

core.compression

       An integer -1..9, indicating a default compression level. -1 is the zlib default. 0 means no compression, and
       1..9 are various speed/size tradeoffs, 9 being slowest. If set, this provides a default to other compression
       variables, such as core.looseCompression and pack.compression.

http.sslVerify “false”

git config --global http.sslVerify “false”
clone有时候会出现错误:OpenSSL SSL_read: Connection was reset, errno 10054

advice.detachedHead

在detach的情况下,会出现一个建议,这个建议无害,可用留着。
$ git checkout origin/88.8
Updating files: 100% (3462/3462), done.
Note: switching to ‘origin/88.8’.

You are in ‘detached HEAD’ state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

git switch -c

Or undo this operation with:

git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at f86185a0f ********

git fetch

–unshallow //非浅层, 还有浅层属性,这种概念。
If the source repository is complete, convert a shallow repository to a complete one, removing all the limitations imposed by shallow repositories. 如果库源是完整的话,就将浅层的库完整化。去除浅层属性的一切限制。
If the source repository is shallow, fetch as much as possible so that the current repository has the same history as the source repository.

获取不到其他branch信息

https://stackoverflow.com/questions/11623862/fetch-in-git-doesnt-get-all-branches
$ git config --get remote.origin.fetch
+refs/heads/master:refs/remotes/origin/master
这里这个参数的值的含义是指fetch master;

git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"  
指定多个branch,通过通配符。

git clone

–depth
Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch unless --no-single-branch is given to fetch the histories near the tips of all branches. If you want to clone submodules shallowly, also pass --shallow-submodules. 只创建一个浅层的库,到特定的commit号。暗含 --single-branch的含义。

git log

git log --full-diff -p Entry.cpp / 关键是-p,patch 修改的diff文件也会在里面
显示Entry.cpp的所有改动。

git log --pretty=oneline -S’bprm->recursion_depth > 5’
这个可以查看,S后面的code 是哪一个commit 删除的。
https://stackoverflow.com/questions/1528513/find-where-code-was-deleted-in-a-git-repository

git log -SFoo --since=2009.1.1 --until=2010.1.1 – path_containing_change
从哪一天开始的commit。

git merge

git merge < commit id > /// 根据commit 来做merge
git merge origin/master /// 根据branch 做merge
git merge tag-name /// 根据tag id、name 来做merge

git reglog

可以查看到最近的commit修改,然后根据commit id reset。
$ git reflog
b99d3d6d3 (HEAD -> scrum_) HEAD@{0}: reset: moving to b99d3d6d3
d3673ff81 HEAD@{1}: commit (amend): temp
b99d3d6d3 (HEAD -> scrum_) HEAD@{2}: commit: temp
2e2d7eb3b HEAD@{3}: commit (amend): fixed
7f2e84d57 HEAD@{4}: commit (amend): fixed
d50792b14 HEAD@{5}: commit (amend): fixed

git push

怎么撤回已经push的commit。
https://christoph.ruegg.name/blog/git-howto-revert-a-commit-already-pushed-to-a-remote-reposit.html

git reset

git reset [mode] commit

–soft

知识reset HEAD到指定的commit,不会动索引文件和工作目录。可以将当前所有改动的文件变成将要commit的文件。

–hard

这个比较彻底,会重置索引文件和工作目录。从指定commit之后的所有改动都会丢失。

git restore

(use “git restore …” to discard changes in working directory)
可以恢复当前目录的所有改动。删除改动。

错误

错误:fetch-pack: unexpected disconnect while reading sideband packet

https://stackoverflow.com/questions/66366582/github-unexpected-disconnect-while-reading-sideband-packet
这个错误的原因是说,库里的文件太多,而且网络不稳定导致传输有问题,可以尝试分段获取的方式:
git config --global core.compression 0
git clone --depth 1 <repo_URI>
#cd to your newly created directory
git fetch --unshallow
git pull --all

错误 error: invalid path 和下一个错误一样的原因

mzhan017@N-20S1PF2ST1ZD MINGW64 /c/open_source
$ git clone https://github.com/systemd/systemd.git
Cloning into ‘systemd’…
remote: Enumerating objects: 387109, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 387109 (delta 0), reused 3 (delta 0), pack-reused 387104
Receiving objects: 100% (387109/387109), 207.91 MiB | 10.07 MiB/s, done.
Resolving deltas: 100% (303259/303259), done.
error: invalid path ‘test/fuzz/fuzz-unit-file/dev-mapper-fedora_krowka\x2dswap.swap’
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with ‘git status’
and retry with ‘git restore --source=HEAD 😕’

错误 drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c

原因是 windows 系统不允许有 aux 名命的文件。还有这种规定,为什么?
https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN
解决方法
git config core.protectNTFS false
git config --global core.protectNTFS false
$ git clone git@github.com:torvalds/linux.git
Cloning into ‘linux’…
remote: Enumerating objects: 8359911, done.
remote: Counting objects: 100% (113/113), done.
remote: Compressing objects: 100% (71/71), done.
remote: Total 8359911 (delta 52), reused 55 (delta 42), pack-reused 8359798
Receiving objects: 100% (8359911/8359911), 3.28 GiB | 5.95 MiB/s, done.
Resolving deltas: 100% (6945819/6945819), done.
error: invalid path ‘drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c’
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with ‘git status’
and retry with ‘git restore --source=HEAD 😕’

错误, 不支持unicode,但是参数设置时使用了中文字符

$ git clone https://github.com/git/git.git
Cloning into ‘git’…
fatal: bad boolean config value ‘“false”’ for ‘http.sslverify’

Warning: Your console font probably doesn’t support Unicode. If you experience strange characters in the output, consider switching to a TrueType font such as Consolas!

git status

只显示 ontrack的文件状态
git status -uno