Git 速查

日常开发中,我们会用到一些 Git 的指令,有的比较常用,已经烂熟于心了,但是还有一些比较重要但是没有那么常用的,每次要用时记忆总有偏差,需要重新 Google 具体的用法,现在统一记录一下,方便以后查阅

1. 关于 Tag

删除本地 Tag 的指令比较简单,如下

1
git tag -d your-tag

如果要推送某个标签到远程,使用命令

1
git push origin your-tag

或者,一次性推送全部尚未推送到远程的本地标签

1
git push origin --tags

但是,如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

1
git tag -d your-tag

然后,从远程删除,比较怪异和难记的就是这个,删除命令也是 push,但是格式如下:

1
git push origin :refs/tags/your-tag

参考文章1

参考文章2

2. 设置 AS 内 git 环境为 git-bash

git-bash 的命令窗口操作,界面比 cmd 或 AS Terminal 美观,功能也强大,如果想要在 AS 内使用,可以设置一下

设置路径为 Settings… -> Tools -> Terminal,将其中的 Shell path 设置为你电脑中 git 目录下的 X:\Program Files\Git\bin\bash.exe,注意这个是让 Terminal 直接变成 git-bash 模式的,如果直接选择 git 目录下即 X:\Program Files\Git\git-bash.exe 的话,会变成弹窗模式

参考文章

3. git-bash 中文乱码解决方法

打开 git-bash,输入平时常用的命令如 ipconfig、systeminfo 等,输出的结果中英文是正常的,但是中文是乱码,可以做如下操作

  1. 打开 GitBash(git-bash.exe)后,对窗口右键 -> Options -> Text -> Locale 改为 zh_CN,Character set 改为 GBK
  2. 键入 exit 退出关闭再打开即可

参考文章

4. 撤销 merge、amend

撤销上一次 merge 的命令

1
git reset --hard HEAD~

撤销上一次 amend

1
git reset HEAD@{1}

5. 生成 SSH Key

这个也算重要和常见,但是有时一旦弄好环境,很久都不需要再次使用,所以又会记不太住,基本步骤如下:

  1. 生成 ssh key
    1
    ssh-keygen -o
  2. 进入相关目录查看文件
    1
    2
    cd ~/.ssh
    ls
  3. 输出 key 的内容
    1
    cat ~/.ssh/id_rsa.pub

具体效果演示如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
DDP@DESKTOP-EP4ME0S MINGW64 ~
$ ssh-keygen -o
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/DDP/.ssh/id_rsa):
Created directory '/c/Users/DDP/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/DDP/.ssh/id_rsa
Your public key has been saved in /c/Users/DDP/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:kQEwgBu5dCyJVCdXtqou2dpqeUfs8hgZvL8/q9UOuqk DDP@DESKTOP-EP4ME0S
The key's randomart image is:
+---[RSA 3072]----+
|o+=+o+o+. |
|=+ o+.. .o |
|.+o .o |
|o . . . |
| o.. S |
| =o . |
| +=o o . |
| =o++o+.o |
|.o=E=O=oo. |
+----[SHA256]-----+

DDP@DESKTOP-EP4ME0S MINGW64 ~
$ cd ~/.ssh

DDP@DESKTOP-EP4ME0S MINGW64 ~/.ssh
$ ls
id_rsa id_rsa.pub

DDP@DESKTOP-EP4ME0S MINGW64 ~/.ssh
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDDPLcVlpXBAQ0/Gld6PXI3DxvduQu0nFc06dOionC2IfEp54EJvNWizS487wQnJj1Esg8vMVr7i2sM8imc2FyP2QXb8YCIZLhtjeXDk+Ihaq62f5/CfrgZNPVOj7xk73W0AlAxmfaV5GjJGejrC0+RtHkhLxeayGMwaNZrPaRbkv0PzA7mEglN8yNenzNaheHXe2bYvrVulTXg1YZUDZlDkzo4vwbOHCevVNxol3Q3UHq903KZsW/AM17CFk2fhNxvhbtHQWtfEoBQ3xvDQJqQLXnZCMw6rFsgpXxH4oB1HmuQOlwS3M8skDj9ogVrzZx1+TM3R215bzwzaco9iQVJRB4JD7TbV6XRKYUd7pHwn5GZe5xcb9LZYkrv2QGtjsf8Rimjd6//NJ2blZ5cnQRc8eMsGSTJoigS0N3VNPfa9ERGGj1ek9yZ9ZGcQN8gOPZl0oFFTlEy0MjWCq9Vddfp4vKhmvJ8OTSQ2OvPuhHcLDKSeVvLMFYXAIcFA05kCTU= DDP@DESKTOP-EP4ME0S

6. 切换 ssh 和 http 协议

  1. 查看当前 remote
    1
    git remote -v
  2. 切换到 http:
    1
    git remote set-url https://github.com/username/repository.git
  3. 切换到ssh:
    1
    git remote set-url git@github.com:username/repository.git

也可以直接改当前 git 目录里面有个配置文件,路径是 .git/config,大致如下,修改 url 即可,有时候 fetch 和 push 的 url 会不一样,如果没额外写出来的话,应该就是默认一致的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
[remote "origin"]
url = git@github.com:EndeRHoshI/hoshi-blog.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[gui]
wmstate = normal
geometry = 841x483+156+156 189 218

据评论说不正确,暂时还未做验证,如果有问题,还可参考下面的

  1. 先增加新的协议
    1
    git remote set-url --add origin https://gitee.com/zjZSTU/zjzstu.gitee.io.git
  2. 再删除原先的协议
    1
    git remote set-url --delete origin git@gitee.com:zjZSTU/zjzstu.gitee.io.git

参考文章

7. 解决 The authenticity of host ‘gitee.com (180.97.125.228)’ can’t be established. 问题

具体情形如下:

1
2
3
4
5
6
7
HoShI@DESKTOP-050RN3C MINGW64 /f/RiskOfRainPhoto (master)
$ ssh -T git@gitee.com
The authenticity of host 'gitee.com (180.97.125.228)' can't be established.
ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQp+KkGYoFgbVr17bmjey0Wc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'gitee.com,180.97.125.228' (ECDSA) to the list of known hosts.
Hi Hoshi! You've successfully authenticated, but GITEE.COM does not provide shell access.

其原因为:在新生成密钥之后,在 .ssh 文件夹中少了一个 known_hosts 文件,本来密钥文件应该是三个,现在是两个,便报了这样的错误,此时选择 yes 回车之后,便可,会生成缺少了的 known_hosts 文件

参考文章

8. github action 签名问题:如何保证自己的 keystore 文件安全?

  • 如果整个项目都是私有的,你不会开放它,那么你可以直接上传你的 keystore
  • 如果你的项目是公开的,有以下两个方法
    1. 上传一个加密过的 keystore 文件,将你的密钥写到 github secret 里面,要使用的时候再解密
    2. 上传 keystore 到一个私有库中,要使用的时候,再从私有库拉取,把私有库的凭证例如账号密码之类的写到 github secret 里面

9. 修改 Git 用户名或邮箱

查看用户名和邮箱:

1
2
3
4
5
6
7
# 当前项目
git config user.name
git config user.email

# 全局
git config --global user.name
git config --global user.email

如果要修改,则直接在后面加上目标字符串,如下:

1
2
3
4
5
6
7
# 当前项目
git config user.name targetName
git config user.email targetName

# 全局
git config --global user.name targetName
git config --global user.email targetName

参考文章

10. 修改远端提交记录

修改提交信息

修改最近一次 commit 信息,可以直接用 amend,使用后,你会进入文本编辑器,修改 commit 信息保存后就可以更新 commit 信息

1
git commit --amend

修改多条 commit 信息,例如想要修改最近三次提交信息,或者那组提交中的任意一个提交信息,将想要修改的最近一次提交的父提交作为参数传递给 git rebase -i 命令,即 HEAD~2HEAD~3

1
git rebase -i HEAD~3

使用上述命令后,会出现类似的界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file

# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

如果你想更改第一条 commit 信息,把第一条 commit 信息对应的 pick 更改为 edit 然后 ESC + :wq 保存退出,运行

1
git rebase --amend

运行上述命令后在弹出文本编辑界面重新提交 commit 信息,完成后保存退出。运行

1
git rebase --continue

所有的 commit 信息都修改完之后运行一下命令将更改推送到远程

1
git push origin master --force

参考文章

修改提交记录用户名

1
2
3
4
5
6
7
8
9
10
11
12
13
# 第一步,(n)代表提交次数
git rebase -i HEAD~n

# 第二步然后按`i`编辑,把`pick` 改成 `edit`,按'Esc'退出编辑,按`:wq`保存退出

# 第三步
git commit --amend --author="作者 <邮箱@xxxx.com>" --no-edit

# 第四步
git rebase --continue

# 第五步
git push --force

要注意,如果 master 分支是受保护的,无法直接强制推上去,那就需要分开其他分支如 develop 分支,方便此类操作以及后续的分支管理

参考文章

11. Git 远程仓库地址变更本地如何修改

由于各种原因,作为 Git 仓库的服务器 IP 地址变了,本地代码太多,重新检出会花很多时间,这时就可以修改一下配置让本地仓库和新的远程仓库建立关联

方法有很多,这里简单介绍几种,以下均以项目 git_test 为例:

1
2
3
老地址:http://192.168.1.12:9797/hoshi/git_test.git
新地址:http://192.168.100.235:9797/hoshi/git_test.git
远程仓库名称: origin

方法一 通过命令直接修改远程地址

  1. 进入 git_test 根目录
  2. git remote 查看所有远程仓库, git remote xxx 查看指定远程仓库地址
  3. git remote set-url origin http://192.168.100.235:9797/hoshi/git_test.git

方法二 通过命令先删除再添加远程仓库

  1. 进入 git_test 根目录
  2. git remote 查看所有远程仓库, git remote xxx 查看指定远程仓库地址
  3. git remote rm origin
  4. git remote add origin http://192.168.100.235:9797/hoshi/git_test.git

方法三 直接修改配置文件

  1. 进入 git_test/.git
  2. vim config
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [core]
    repositoryformatversion = 0
    filemode = true
    logallrefupdates = true
    precomposeunicode = true
    [remote "origin"]
    url = http://192.168.100.235:9797/shimanqiang/assistant.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    [branch "master"]
    remote = origin
    merge = refs/heads/master
  3. 修改 [remote “origin”] 下面的 url 即可

方法四 通过第三方git客户端修改。

以SourceTree为例,点击 仓库 -> 仓库配置 -> 远程仓库 即可管理此项目中配置的所有远程仓库, 而且这个界面最下方还可以点击编辑配置文件,同样可以完成方法三

摘自他人的文章,原文链接

12. git reflog 以及 git reset

有时候我们做了一些错误的操作,可以使用 git reflog 查看操作日志以及 git reset 来进行撤回

  1. 执行 git reflog,可以查看所有操作日志:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    git reflog

    8dd0780f2e (HEAD -> temp/extend_warranty_2) HEAD@{0}: rebase (continue) (finish): returning to refs/heads/temp/extend_warranty_2
    8dd0780f2e (HEAD -> temp/extend_warranty_2) HEAD@{1}: rebase (continue) (pick): 初步实现积分中心框架
    cb5b611664 HEAD@{2}: rebase (continue): 初步实现单设备、多设备界面框架
    5e60393df3 HEAD@{3}: rebase (pick): 增加激励广告
    cdc046373e HEAD@{4}: rebase (pick): 调整异步工具类;调整 Span 工具类
    d887d18e29 HEAD@{5}: rebase (pick): 移除本地冗余 MagicIndicator;初步实现 πStore 页面框架
    c894b70de3 (origin/temp/dev-7.1.5, temp/dev-7.1.5) HEAD@{6}: rebase (start): checkout origin/temp/dev-7.1.5
    b89a45651b HEAD@{7}: reset: moving to HEAD
    b89a45651b HEAD@{8}: checkout: moving from temp/dev-7.1.5 to temp/extend_warranty_2
    c894b70de3 (origin/temp/dev-7.1.5, temp/dev-7.1.5) HEAD@{9}: checkout: moving from ui7.0-kotlin-lvqx to temp/dev-7.1.5
    496ffa9056 (ui7.0-kotlin-lvqx) HEAD@{10}: commit (amend): 调整 Gradle 版本,初步引入 Kotlin,并编写 Kotlin 示例类
    3d81c02df2 HEAD@{11}: checkout: moving from temp/dev-admin-lvqx to ui7.0-kotlin-lvqx
    3732cde39b HEAD@{12}: checkout: moving from temp/extend_warranty_2 to temp/dev-admin-lvqx
    b89a45651b HEAD@{13}: commit: 初步实现积分中心框架
    d9b3616a1f HEAD@{14}: commit: 初步实现单设备、多设备界面框架
    47f0792ecf HEAD@{15}: commit: 增加激励广告
    仔细查看记录,比如我想撤回到从分支 dev-7.1.5 切换到 extend_warranty_2 的那个状态,即 HEAD@{8} 的内容
  2. 执行命令 git reset --hard 回到初始状态
    1
    2
    3
    git reset --hard HEAD@{26}
    或者
    git reset --hard bbc9da41b5

如果错误地使用了 git commit –amend,也就是在 AS 中提交时,手滑点了右上角的 Amend commit,导致上一次的提交被覆盖了,丢失了提交记录,或者导致分支状况不一致无法上传到远端服务器,这时就要想办法撤销掉这个错误的 amend commit,回到之前的状态,解决方法如下:

首先使用 git reflog 命令查看操作记录:

1
2
3
$ git reflog
6889e84 (HEAD -> master) HEAD@{0}: commit (amend): modified 1/2/3.txt
b82585f HEAD@{1}: commit: modified 1/2.txt

然后可以看到你的 amend commit,之后再使用 git reset,其中 reset 后面的就是你在 reflog 命令中查到的 id,或者后面的 HEAD@{x}

1
$ git reset b82585f

不使用 git reset --hard 的目的就是为了保留本地修改,否则修改就会被丢弃,如果一个 commit 被 amend 了多次, 也可以用这种方法撤销到任意一次 amend 处:

1
2
3
4
5
6
7
$ git reflog
937fd53 HEAD@{0}: commit (amend): add blank line to index.html
7589755 HEAD@{1}: commit (amend): add blank line to index.html
f7ade82 HEAD@{2}: commit (amend): add blank line to index.html
c1c1b21 HEAD@{3}: commit (amend): add blank line to index.html
9ff821d HEAD@{4}: commit: add blank line to index.html
$ git reset --soft HEAD@{2}

由此看来,不只是 rebase 可以撤回,很多操作都可以通过这个方法撤回

参考文章

13. 端口 22 超时

端口 22 超时问题,报错如下,解决方法另外的参考文章终极解决问题文章修改 host

1
2
3
4
5
ssh: connect to host github.com port 22: Connection timed out
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

注意整完之后,好像用 https 协议不行了,报错 https 地址 + Failed to connect to github.com port 443 after 21077 ms: Timed out

14. git gc 相关问题

在对 Git 库执行一些操作命令时(比如 git amgit pullgit push 等操作)的时候,会出现类似如下提示(作者是在用 git am 打 patch 时出现的,其他情况也是一回事):

1
2
3
4
5
ronny@ronny:~/tmpgitrepol$ git am ~/03patch/kernel/0001-add-kernel-version.patch --keep-cr
Applying: add kernel version for compile
Auto packing the repository for optimum performance. You may also
run "git gc" manually. See "git help gc" for more information.
Counting objects: 84286, done.

而且 git am 后不退出,必须要 Ctrl + C 退出。(其实是 git 在将松散对象打包,这个需要时间,没有执行完打包,所以没退出)

里面主要关心如下两句:

1
2
Auto packing the repository for optimum performance. You may also
run "git gc" manually. See "git help gc" for more information.

当有这个提示的时候,直接运行 git gc,就可以了。

原因:Git 往磁盘保存对象时默认使用的格式叫松散对象 (loose object) 格式。Git 时不时地将这些对象打包至一个叫 packfile 的二进制文件以节省空间并提高效率。当仓库中有太多的松散对象则就会提示你运行 git gc

我们可以运行 find .git/objects -type f 命令,查看一下 objects 目录里有多少对象,然后运行 git gc 之后再看看剩下多少对象

git gc 后,接下来再执行 git 命令的时候就没有出现提示的情况了

摘自他人的文章,原文链接

15. 修改历史 commit

平时如果我们刚刚提交完,发现有问题,可以用 amend 的方法来修改上一次的提交,但是如果是前几个提交中有需要修改的地方,就要用到下面的方法

首先 git rebase -i HEAD~10 查看最近十条提交记录(也可以指定其他条数),会得到下面的结果:

rebase十条数据

然后我们按 i 进入编辑模式,把需要修改的那一条提交前面的 pick 改为 edit,再按 ESC 退出编辑模式,:wq 退出当前编辑器

这时我们回到终端界面,再用指令 git commit --amend 更新提交信息,然后 git rebase --continue 结束当前这条的修改,进行下一条,循环执行这两条指令,直到最后提示你 rebase successfully,就全部完成了,下面是前后对比,我把第二第三条提交的 :bugfix: 改成 :bug: 了

修改前

修改后


Git 速查
https://enderhoshi.github.io/2022/03/09/Git 速查/
作者
HoshIlIlI
发布于
2022年3月9日
许可协议