如何告诉Git在特定项目中使用正确的身份(姓名和电子邮件)?

145

我在工作和个人项目中都使用了自己的电脑,希望能够在工作中使用我的工作邮箱地址 (gitolite) 进行提交,在其他情况下使用个人邮箱地址 (github)。

我了解到以下几种方法,但它们都是全局或临时的:

  • git config --global user.email "bob@example.com"
  • git config user.email "bob@example.com"
  • git commit --author "Bob <bob@example.com>"
  • 设置 GIT_AUTHOR_EMAILGIT_COMMITTER_EMAILEMAIL 环境变量之一

其中的一个解决方案是手动运行一个 shell 函数,将我的环境设置为“工作”或“个人”,但我很可能会经常忘记切换到正确的身份,导致在错误的身份下提交。

是否有一种方式可以将某个仓库、项目名称等与身份(姓名、电子邮件)绑定?人们通常怎么做呢?

8个回答

155

git config user.email "bob@example.com"

在仓库中执行此命令将会在该仓库上设置配置信息,而非全局。

除非我理解有误,否则似乎这正是您想要的。


我想这样做应该没问题。我希望为同一个项目有多个本地仓库,特别是为了更轻松地在分支之间切换而不必重新编译所有内容。也许这只是一个不好的 SVN 习惯。谢谢。 - Martin Jambon
1
@Martin--我使用git的时间不长,但我的感觉是,在git中使用多个本地仓库会是一种不寻常的工作流程。即便如此,你只需要在一个仓库实例上运行一次,它就会设置为该仓库的生命周期,所以也不算太糟糕。 - Dan Ray
@DanRay,实际上,如果像马丁的情况一样,本地仓库有本地未提交的文件,那么这是一个常见的设置。从一个分支切换到另一个分支不会自动重建文件。如果避免“重新编译所有内容”是一个目标,使用多个本地仓库是正确的方法。 - dolmen
1
git config --global user.email "bob@example.com" 添加 --global 可使其在所有仓库中生效。来源:https://help.github.com/articles/setting-your-username-in-git/ - SashiOno
1
这是一个手动任务,可能会被遗忘。**@dragon788** 和我建议使用自动化解决方案。 - stollr
显示剩余2条评论

74

你需要使用下面的本地设置命令:

本地设置

git config user.email mahmoud@company.ccc
git config user.name 'Mahmoud Zalt'

本地获取

git config --get user.email
git config --get user.name

本地配置文件位于项目目录:.git/config

全局设置

git config --global user.email mahmoud@zalt.me
git config --global user.name 'Mahmoud Zalt'

全局获取

git config --global --get user.email
git config --global --get user.name

全局配置文件位于您的主目录下:~/.gitconfig

请记得引用空格等内容,例如:'FirstName LastName'


惊人的答案...我希望将本地变量与全局变量区分开来。 - Rohit Kumar

26

在“.git”文件夹的配置文件中编辑,以便根据存储库保留不同的用户名和电子邮件

  • 进入您的存储库
  • 显示隐藏文件并进入“.git”文件夹
  • 找到“config”文件
  • 在EOF处添加以下行

[user]

name = Bob

email = bob@example.com

以下命令将向您显示为此存储库设置的用户名和电子邮件。

git config --get user.name

git config --get user.email

示例:对于我来说,该配置文件位于D:\workspace\eclipse\ipchat\.git\config

这里的ipchat是我的存储库名称


17
如果你使用命令git config user.email "foo@example.com",那么它将绑定到你当前所在的项目中。
这是我为自己的项目所做的。当我克隆或初始化存储库时,我设置适当的身份标识。尽管不是百分之百可靠的(如果你忘记设置并在弄清楚之前进行推送,你就会出问题),但这是你能够做到的最好的方法,除非你有能力运行git config --global user.email 'ILLEGAL_VALUE'
实际上,你可以设置一个非法值。键入git config --global user.name $(perl -e 'print "x"x968;')
然后,如果你忘记设置你的非全局变量,你将收到一个错误消息。
[编辑] 在另一个系统上,我不得不将x的数量增加到968才能让它失败,提示“fatal: Impossibly long personal identifier”。这是相同版本的git。奇怪。

听起来是个好办法,但对我没用。提交和推送到gitolite远程都成功了。 - Martin Jambon
@Martin Jambon:很奇怪。我正在使用git版本1.7.4.5。 - Seth Robertson
@Martin Jambon:你也可以尝试将全局用户名/电子邮件地址设置为“x”。一些旧版本的git会拒绝太小的值。如果这样不起作用,请报告您使用的git版本/操作系统。 - Seth Robertson
@Martin Jambon:尝试使用968 "x",看看是否对您更有效。 - Seth Robertson

12
从Git 2.13开始,您可以在gitconfig中使用includeIf,根据运行git命令的存储库的路径,包含一个具有不同配置的文件。由于Ubuntu 18.04已安装了足够新的Git,因此我一直在愉快地使用我的~/.gitconfig配置。
[include]
  path = ~/.gitconfig.alias # I like to keep global aliases separate
  path = ~/.gitconfig.defaultusername # can maybe leave values unset/empty to get warned if a below path didn't match
# If using multiple identities can use per path user/email
# The trailing / is VERY important, git won't apply the config to subdirectories without it
[includeIf "gitdir:~/projects/azure/"]
  path = ~/.gitconfig.azure # user.name and user.email for Azure
[includeIf "gitdir:~/projects/gitlab/"]
  path = ~/.gitconfig.gitlab # user.name and user.email for GitLab
[includeIf "gitdir:~/projects/foss/"]
  path = ~/.gitconfig.github # user.name and user.email for GitHub

https://motowilliams.com/conditional-includes-for-git-config#disqus_thread

如果您想使用Git 2.13,您需要添加PPA(Ubuntu早于18.04 / Debian)或下载二进制文件并安装(Windows /其他Linux)。


2
非常有帮助,正是我所需要的。结合 git config core.sshCommand 用于多个私钥,提供完整无缝的 git 身份管理。 - topr

9
如果不使用--global参数,它将仅为当前项目设置变量。

3

我非常喜欢Micah Henning在其文章中(参见设置Git身份信息)的方法。他强制每个创建/克隆的存储库都应用并强制使用身份信息,这是一种不会忘记每次进行此设置的好方法。

基本的git配置

取消当前用户在git中的配置:

$ git config --global --unset user.name
$ git config --global --unset user.email
$ git config --global --unset user.signingkey

强制在每个新的本地代码库中配置身份标识:

$ git config --global user.useConfigOnly true

identity 命令创建 Git 别名,稍后我们会用到:

$ git config --global alias.identity '! git config user.name "$(git config user.$1.name)"; git config user.email "$(git config user.$1.email)"; git config user.signingkey "$(git config user.$1.signingkey)"; :'

身份创建

使用 GPG 创建一个身份(根据系统上的情况使用 gpggpg2)。对于每个要使用的身份,请重复以下步骤。

Note: [keyid] here is the identifier of created secret key. Example here:

sec   rsa4096/8A5C011E4CE081A5 2020-06-09 [SC] [expires: 2021-06-09]
      CCC470AE787C057557F421488C4C951E4CE081A5
uid                 [ultimate] Your Name <youremail@domain>
ssb   rsa4096/1EA965889861C1C0 2020-06-09 [E] [expires: 2021-06-09]

The 8A5C011E4CE081A5 part after sec rsa4096/ is the identifier of key.

$ gpg --full-gen-key
$ gpg --list-secret-keys --keyid-format LONG <youremail@domain>
$ gpg --armor --export [keyid]

复制公钥并将其作为GPG密钥添加到您的GitHub/GitProviderOfChoice设置中。

向Git配置中添加身份信息。对于每个需要添加的身份,也要重复这个步骤:

注意:在这里我使用gitlab来作为我的身份名称,但是根据您的问题它可以是任何东西,例如:gitolitegithubwork等。

$ git config --global user.gitlab.name "Your Name"
$ git config --global user.gitlab.email "youremail@domain"
$ git config --global user.gitlab.signingkey [keyid]

为仓库设置身份

如果一个新的仓库没有关联的身份信息,提交时会出现错误提示,提醒您进行身份设置。

*** Please tell me who you are.

## parts of message skipped ##

fatal: no email was given and auto-detection is disabled

请指定您希望在新存储库上使用的身份标识:

$ git identity gitlab

现在,您已经可以使用 gitlab 身份进行提交了。


值得一提的是,git identity 不是一个有效的 git 命令。我认为你的答案受到了这篇文章的启发(https://www.micah.soy/posts/setting-up-git-identities/),非常好。谢谢。 - Ahmad Alfy
是的,源代码在帖子中提到了 :) - sgy

0
一个解决方案是手动运行一个设置我的工作或个人环境的 shell 函数,但我很确定我经常会忘记切换到正确的身份,导致提交错误的身份。
这正是我的问题。我编写了一个钩子脚本,如果您有任何 github 远程并且没有定义本地用户名,则会发出警告。
以下是设置步骤:
1. 创建一个目录来保存全局钩子
``` mkdir -p ~/.git-templates/hooks ```
2. 告诉 git 在运行 `git init` 或 `clone` 时将 `~/.git-templates` 中的所有内容复制到您的每个项目的 `.git` 目录中
``` git config --global init.templatedir '~/.git-templates' ```
3. 现在将以下行复制到 `~/.git-templates/hooks/pre-commit` 中,并使文件可执行(不要忘记这一点,否则 git 将无法执行它!)
#!/bin/bash

RED='\033[0;31m' # red color
NC='\033[0m' # no color

GITHUB_REMOTE=$(git remote -v | grep github.com)
LOCAL_USERNAME=$(git config --local user.name)

if [ -n "$GITHUB_REMOTE" ] && [ -z "$LOCAL_USERNAME" ]; then
    printf "\n${RED}ATTENTION: At least one Github remote repository is configured, but no local username. "
    printf "Please define a local username that matches your Github account.${NC} [pre-commit hook]\n\n"
    exit 1
fi

如果您使用其他主机作为私有存储库,您必须根据自己的需求替换github.com
现在每次执行git initgit clone时,git都会将此脚本复制到存储库并在进行任何提交之前执行它。如果您没有设置本地用户名,它将输出警告并且不允许您提交。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接