Git 解决因 Author 中有特殊字符引起的 push 失败

pizzq · 2012年07月21日 · 最后由 lihuazhang 回复于 2020年09月03日 · 9554 次阅读

今天打算同步 RubyChina 的 source code,但在 merge 到本地的 branch 后,push 到 github 时确碰到了问题, 错误如下:

Pushing to https://github.com/hunkshi/ruby-china.git error: unpack failed: index-pack abnormal exit

通过 googgle 搜索,有人建议 check 一下数据库,fsck-objects 显示,果然有一条错误

error in commit 0c804057994a56a1d649653675365b3ad12d7ad8: invalid author/committer line - bad name

在 history 中找到这条 commit,发现这条 commit 的 Author、Committer 中有特殊字符=> /, 为了验证是否因为这些特殊字符引起,从这条 commit 的上一条建了一个 branch,push 到 github,成功!把之后的 commit merge 过来再次上传,失败!因此可以断定是特殊字符引起。

解决办法,Git Bash 中运行如下命令:

git filter-branch -f --commit-filter ' if [ "$GIT_AUTHOR_EMAIL" = "xxx@gmail.com" ]; then GIT_AUTHOR_NAME="xxxxx"; GIT_COMMITTER_NAME="xxxxxx"; git commit-tree "$@"; else git commit-tree "$@"; fi ' HEAD

xxxx 为去除特殊字符的新 name。然后 push 到 github(选择 force 选项,强制覆盖),成功!

我使用 git 和 github 时间还不长,有以下一些疑问:

  1. 大家碰到过类似的问题吗?怎么解决的?是否有简单办法?
  2. Git 对 Author、Committer 名字有规范吗?可以使用> /这样的字符吗?

表示同样遇到,貌似我名字很 Bug,在 Github 上提交出错,在社区 @ 也出错...

@linjunpop @huacnlee @hunkshi

我回忆一下当时提交的流程,希望有帮助排查问题

0c80405 https://github.com/ruby-china/ruby-china/commit/0c804057994a56a1d649653675365b3ad12d7ad8 这条 commit 是我在线阅读 ruby-china 代码时,发现给翻译问题,顺手在 github 直接点了 Edit 这个文件,在线做了文件修改后点保存,github 网站给我 fork 的 ruby-china 的代码自动创建了一个 patch1 分支并保存了修改 https://github.com/huobazi/ruby-china/tree/patch-1 接下来我提交了 pull request

和平时不同的就是此次修改代码的操作是在 github 网站上直接操作的

我猜测在线编辑文件时 github 网站取了我在 github 上留的信息 (包含了有汉字和斜杠的昵称) 来作为 [user] 信息了,而平时,我本地的 gitconfig 内是没有这些信息的

huobazi 回复

0.0 今天试了下,推不上去。。。。

commit 0c804057994a56a1d649653675365b3ad12d7ad8
Author: Marble Wu => 武眉博 / 活靶子 <huobazi@gmail.com>
Date:   Fri Jul 20 02:13:53 2012 +0800

    Update config/locales/users.zh-CN.yml

@huobazi 老铁,这个是你吗? 这个特殊字符搞得我有点头疼。😂

最近也面临到需要把 homeland 整个仓库推送到新仓库并保留历史记录的需求(非 fork 方式)。我测试了一下,日常我们 fork 项目是没有问题的(应该是不需要推送该 commit 的缘故,因为记录已经在 github 那边),然而当我们向 github 推送整个仓库(包括历史提交记录的时候)就会报错。

remote: error: object 0c804057994a56a1d649653675365b3ad12d7ad8: badName: invalid author/committer line - bad name

通过 git 命令git fsck可以在本地检测到问题

git fsck

➜  homeland git:(master) git config  fsck.badName   warn
➜  homeland git:(master) git fsck
Checking object directories: 100% (256/256), done.
warning in commit 0c804057994a56a1d649653675365b3ad12d7ad8: badName: invalid author/committer line - bad name
warning in commit 0c804057994a56a1d649653675365b3ad12d7ad8: badName: invalid author/committer line - bad name
Checking objects: 100% (38925/38925), done.

貌似就是它的锅了。相关的配置参数在git-fsck,我一直以为是客户端配置,本地调试了好久都没能通过。今天才知道这是服务端,错误来自于 github 服务端,用来规避一些非法的名字。我自己搭建了一个 git 服务测试了一下,这些配置都能生效,只要在自己搭建的 git 服务端配置

>  git config receive.fsckObjects false

就能在推送的时候关闭检测。遗憾的是 github 上的配置我们似乎控制不了。😂

如果想要基于 homeland 做改进,并保留以前的 commit 记录现在看来最好的方式就是直接 fork,不过 fork 的坏处在于无法闭源。 要想要整个项目推送到新仓库看来只能自己搭建一个 git 服务了。

除非通过rebase的方式来修改你那个 commit 的作者名字,但这种方式需要把 commit 之后的所有 commit 的 id 都刷新一遍,非常的不现实。

cc @huacnlee

@lanzhiheng 啊,我八年前在线 commit 的那条记录还影响 push 啊, 按你的分析,这个要不要给 github 提个 issue 让他们搞呢,毕竟是他们的在线编辑工具 push 后引起 的,这么想来,他们的 在线编辑器修改后 push 是在服务器上运行的,那他们的服务器上的 push 和 我们 client 看来还是有差别的。

huobazi 回复

😂 我怀疑是不是 8 年前没有这个限制。如果他们能够帮忙处理就更好了,最好有个配置能够让管理员进行操作。

huobazi 回复

8 年前么。。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册