Cao Yi

第十五章 Git 配置

⇦上一章 - 首页🏠 - 下一章⇨



Git 安装后,往往需要一些设置以方便后来的使用。前面提到过,只要给 git 配置了邮箱和用户名,就可以修改和提交文件了。

$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"

--global 表示全局配置,没有这个参数就是只对当前仓库生效,如

$ git config user.email "you@another_example.com"

只对当前所在的仓库生效。仓库会优先使用它自己的配置,然后才是全局配置。

查看配置信息,可以用下面的指令

$ git config --list
$ git config --global --list

如果需要重新设置一个配置项覆盖之前的值即可。

删除配置的示例如下:

$ git config --global --unset {key}

配置信息实际上都记录在 ~/.gitconfig 中,但不建议手工更改这个文件。Git 有非常多有用的配置,下面会介绍一些。

1. 默认编辑器

编辑 commit message 时,需要一个文本编辑器,具体可以由用户指定:

$ git config --global core.editor vi

我一般习惯用 vi 或 vim. 如果不设置,git 可能默认使用 nano.

Ref: How do I make git use the editor of my choice for editing commit messages?

2. 设置比较差异的工具

如果没有设置 diff.tool,则执行 git difftool 时会出现下面的提示:

$ git difftool

This message is displayed because 'diff.tool' is not configured.
See 'git difftool --tool-help' or 'git help config' for more details.
'git difftool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld kompare gvimdiff diffuse diffmerge ecmerge p4merge araxis bc codecompare smerge emerge vimdiff nvimdiff

Viewing (1/1): 'git/14.md'
Launch 'vimdiff' [Y/n]?

可以先打 Y,让它选用默认的 vimdiff,也可以按照它的提示安装一个合适的工具,并设置好 diff.tool 的值。

3. 设置文本文件换行符

文本文件的换行符有几种

不同操作系统默认的换行符不一样

这可能给大家的协作带来不便,如果两个人使用的系统不一致。如果没有设置 core.eol, 在 Windows 上添加文本文件时,可能会得到警告性提示:

$ git add .
warning: in the working copy of 'hello.txt', LF will be replaced by CRLF the next time Git touches it

这是因为 Windows 上仓库用 Windows 默认的换行符 CRLF. 这时可以让大家约定都使用 LF 换行,git 库里可以这样设置:

$ git config --global core.eol lf
$ git config --global core.autocrlf input

设置之后,在 Windows 创建的文本文档入库时,会碰到这样的提示信息:

$ git add .
warning: in the working copy of 'hello', CRLF will be replaced by LF the next time Git touches it

内容正好和设置之前相反。Windows 上可用用 VS Code 修改换行符,也可以选择不理会,因为入库后自然会替换成 LF.

Linux 用户不用设置此选项。

参考:Be Careful!不同操作系统中文本换行的方式(知乎)

4. 处理大小写敏感问题

不同操作系统对文件名的大小写是否敏感是不一致的:

为了方便大家协作,可以设置为大家都对大小写不敏感:

$ git config --global core.ignoreCase true

但是,经过本人在 Linux 和 Windows 上的实验,发现这种设置实际效果不佳:

因此,可以团队可以建立 git 外的约定:

文件名和目录名永远不用大小写来区分

但如果已经有了大小写名称混乱的问题,我们应该怎么处理?Git 提供的 git mv {old file name} {new file name} 能很好处理这个问题,下面是一个示例

现在目录里有如下几个文件:

$ ls
hello  hello2.txt  hiworld.txt

git mv 将 hiworld.txt 改成 HiWorld.txt:

$ git mv hiworld.txt HiWorld.txt

查看状态,已经修改成功:

$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        renamed:    hiworld.txt -> HiWorld.txt

提交改动,屏幕显示的消息也表明修改成功:

$ git commit -m "adm-1234, test renmae"
[main a9f9c38] adm-1234, test renmae
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename hiworld.txt => HiWorld.txt (100%)

验证,一切OK:

$ ls
HiWorld.txt  hello  hello2.txt

然而,core.ignoreCase 还是 true:

$ git config --global core.ignoreCase
true

也就是说 git mv 在配置项 core.ignoreCasetrue 也就是配置忽略大小写的情况下,仍然把文件名的大小写改了。

Ref: core.ignoreCase 说明

5. 支持长路径

这个只影响 Windows 用户,受操作系统的限制,路径长度限制在260个字符以内,如果要支持更长的路径,可以作如下设置。

$ git config --global core.longpaths true

建议 Windows 用户都把这个设置上。

Ref:

6. 文件模式设置

Linux 的文件 mode 有:

Windows 上却没有这些区分。

6.1 实验一 fileMode true

在 Linux 上,一个文件如果它的 mode 发生变化,这个文件也会认为已经发生变化,默认情况下,这个变化是可以提交到 git 仓库的。以下是具体实验过程:

登录 Linux 并进入实验用仓库,首先确认 fileMode 的值是 true,不管现在的值是多少,先用下面的指令设置一遍

$ git config core.fileMode true

查看其中的文件 hello.sh,发现还没有可执行权限:

$ ls -l
-rw-rw-r-- 1 caoyi caoyi  6 Dec 23 20:22 hello.sh

给 hello.txt 添加可执行权限

$ chmod +x hello.sh
$ ls -l
-rwxrwxr-x 1 caoyi caoyi  6 Dec 23 20:22 hello.sh

使用 git status 检查库的状态,它提示 hello.sh 有修改

$ git status
On branch hello-branch
Your branch is ahead of 'origin/hello-branch' by 1 commit.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   hello.sh

no changes added to commit (use "git add" and/or "git commit -a")

将 hello.sh 添加到 Staging Area 再提交到 Repository:

$ git add hello.sh
$ git status
On branch hello-branch
Your branch is ahead of 'origin/hello-branch' by 1 commit.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   hello.sh

$ git commit -m "add executable permission to hello.sh"
[hello-branch 8ac69ff] add executable permission to hello.sh
 1 file changed, 0 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 hello.sh

上面的屏幕显示内容很清晰,就是 hello.sh 的权限变动入库了。再用 git show 查以下刚才的提交,也能看到同样的信息

$ git show
commit 8ac69ffa9182f1f388c12b7edfe220561139cf7c (HEAD -> hello-branch)
Author: Cao Yi <iridiumcao@gmail.com>
Date:   Sat Dec 23 20:23:55 2023 +0800

    add executable permission to hello.sh

diff --git a/hello.sh b/hello.sh
old mode 100644
new mode 100755

6.2 实验二 fileMode false

登录 Linux 并进入实验用仓库,首先确认 fileMode 的值是 false,不管现在的值是多少,先用下面的指令设置一遍

$ git config core.fileMode false

查看其中的文件 hello.sh,前面的实验已经给它赋予了可执行权限:

$ ls -l
-rwxrwxr-x 1 caoyi caoyi  6 Dec 23 20:22 hello.sh

这里我们将 hello.sh 的可执行权限去掉

$ chmod -x hello.sh
$ ls -l
-rw-rw-r-- 1 caoyi caoyi  6 Dec 23 20:22 hello.sh

使用 git status 检查库的状态,它并没有检测到工作区里 hello.sh 有任何改动:

$ git status
On branch hello-branch
Your branch is ahead of 'origin/hello-branch' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

(上面 git status 提到的本地分支比远程关联分支多两个 commit,和 hello.sh 的 mode 变化无关。)

6.3 设置建议

考虑到文件权限变化在 Linux 中是有实际意义的,并非可有可无,建议将 fileMode 设置为 true.

$ git config core.fileMode true

这个设置在 Linux 上是生效的,不过对于 Windows 无感。这个值不论是 true or false, Windows 都检测不到这种变化。这样设置后,如果需要修改文件的权限,直接到 Linux 主机上去修改即可。

7. 设置 pull

初学者不用理会本节的设置。

git config --global pull.rebase true

如果不设置,在 pull 时如果要使用 rebase 就得用:

git pull --rebase

官方文档解释如下:

pull.rebase

When true, rebase branches on top of the fetched branch, instead of merging the default branch from the default remote when “git pull” is run. See “branch.<name>.rebase” for setting this on a per-branch basis.

When merges (or just m), pass the –rebase-merges option to git rebase so that the local merge commits are included in the rebase (see git-rebase(1) for details).

When the value is interactive (or just i), the rebase is run in interactive mode.

NOTE: this is a possibly dangerous operation; do not use it unless you understand the implications (see git-rebase(1) for details).

8. 设置 push

初学者不用理会本节的设置。

在较旧的版本上执行 git push 可能会碰到如下提示,它提到了 simplematching 两种模式,很显然 simple 更安全,这个设置按默认就好,不用改。

$ git push
warning: push.default 尚未设置,它的默认值在 Git 2.0 已从 'matching'
变更为 'simple'。若要不再显示本信息并保持传统习惯,进行如下设置:

  git config --global push.default matching

若要不再显示本信息并从现在开始采用新的使用习惯,设置:

  git config --global push.default simple

当 push.default 设置为 'matching' 后,git 将推送和远程同名的所有
本地分支。

从 Git 2.0 开始,Git 缺省采用更为保守的 'simple' 模式,只推送当前
分支到远程关联的同名分支,即 'git push' 推送当前分支。

参见 'git help config' 并查找 'push.default' 以获取更多信息。
('simple' 模式由 Git 1.7.11 版本引入。如果您有时要使用老版本的 Git,
为保持兼容,请用 'current' 代替 'simple')

9. 查看帮助

可以通过执行

$ git config

查看简明的帮助说明。如果要看更详细的帮助文档,可执行

$ git config --help

官方完整参考在这里,非常全面,也非常啰嗦😁

10. .gitignore

前面都是关于 git config 的,这里说一点其他的。

如果工作区有一些文件或目录不希望被 git 管理,可以在工作区的根目录创建文件 .gitignore 并写上它们的路径。一个典型的 Java 项目的 .gitignore 内容是这样的

# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

Ref: https://github.com/github/gitignore/blob/main/Java.gitignore

这里还有非常多的默认的的 .gitignore 配置,可以根据项目选用。


⇦上一章 - 首页🏠 - 下一章⇨