当我尝试将一点回购推送到新服务器时出现错误:
$ git push -f research master
Enumerating objects: 13060, done.
Counting objects: 100% (13060/13060), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3397/3397), done.
Writing objects: 100% (13060/13060), 5.59 MiB | 364.00 KiB/s, done.
Total 13060 (delta 9516), reused 13060 (delta 9516)
remote: Resolving deltas: 100% (9516/9516), done.
remote: error: bad config line 14 in blob .gitmodules
remote: error: object 4f098d01fb9671a7f5ff5f617ef89b289a8ea9bb: gitmodulesParse: could not parse gitmodules blob
remote: fatal: fsck error in pack objects
error: remote unpack failed: index-pack abnormal exit
To gitlab.research.com:proj/repo.git
! [remote rejected] master -> master (unpacker error)
error: failed to push some refs to 'git@gitlab.research.com:proj/repo.git'
$
奇怪的是,我在本地运行git fsck
时遇到相同的错误:
$ git fsck
Checking object directories: 100% (256/256), done.
warning in blob 4f098d01fb9671a7f5ff5f617ef89b289a8ea9bb: gitmodulesParse: could not parse gitmodules blob
Checking objects: 100% (13060/13060), done.
$
事实证明,.gitmodules
文件中的“第14行”不在文件的当前版本中,该版本只有11行。由于存在提交的.gitmodules
版本存在冲突,因此导致了问题。
我可以删除Blob并将其推送到新的仓库中吗,还是有一个我无法轻易解决的深层问题?
编辑-新信息!
给出下面@torek的出色文章,并结合Which commit has this blob?中的脚本(第一个脚本有效,但第二个脚本无效),我能够找到有问题的提交:
$ ~/.bin/git-find-object 4f098d01fb9671a7f5ff5f617ef89b289a8ea9bb
06407fd merged changes from master and stats
我的git repo只有一个分支可见:
$ git branch -v
* master e8ff018 minor
我可以检查有问题的提交:
$ git checkout 06407fd
Checking out files: 100% (321/321), done.
fatal: bad config line 14 in file /home/xv32/gits/repo/.gitmodules
$
我直接编辑了.gitmodules
文件,并删除了有问题的行:
<<<<<<< HEAD
branch = ee
=======
>>>>>>> master
我做了一个git add .gitmodules
我做了一个:
$ git commit --amend -m 'fixed conflict in .gitmodules'
OMG改变了很多东西。
然后我做了一个git状态:
$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: submodule1 (new commits)
modified: submodule2 (new commits)
modified: submodule3(new commits)
no changes added to commit (use "git add" and/or "git commit -a")
$
git fsck不再报告问题:
$ git fsck
Checking object directories: 100% (256/256), done.
Checking objects: 100% (15206/15206), done.
但是我仍然无法推送到远程仓库:
$ git push -f research master
Counting objects: 13245, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3395/3395), done.
Writing objects: 100% (13245/13245), 5.68 MiB | 2.81 MiB/s, done.
Total 13245 (delta 9746), reused 13180 (delta 9702)
remote: error: bad config line 14 in blob .gitmodules
remote: error: object 4f098d01fb9671a7f5ff5f617ef89b289a8ea9bb: gitmodulesParse: could not parse gitmodules blob
remote: fatal: fsck error in packed object
error: remote unpack failed: index-pack abnormal exit
To https://gitlab.research.com/repo/repo.git
! [remote rejected] master -> master (unpacker error)
error: failed to push some refs to 'https://gitlab.research.com/censyn-sensitive/das_decennial.git'
$
此外,当我执行git --amend
时,一堆重要的事情消失了,除了对象中的坏线。
老实说,我不明白为什么我甚至遇到错误,因为错误不在树的顶部。
答案 0 :(得分:2)
我可以删除Blob吗...
否:有一个树对象 T ,上面写着“我应该有斑点4f098d01fb9671a7f5ff5f617ef89b289a8ea9bb
”。因此,您必须找到 tree 并进行处理。树 T 由某些提交对象 C 引用。由于文件为.gitmodules
,因此这可能是该提交的顶级树。您可能必须找到该提交,但是:
导致问题出现的原因是提交的
.gitmodules
版本存在冲突。
... 这 是提交,或者可能只是几个提交中的第一个提交,其中有一个树,上面写着“我应该有斑点”。换句话说,您已经找到了相关的提交。
现在的诀窍是用新的和改进的版本重写提交。新版本应该与原始版本几乎相同,不同之处在于其提交的.gitmodules
(斑点)应该是正确的,而不是错误的。
一旦替换了那个提交,就必须替换该提交的一个或多个子项,因为该子项通过其哈希ID引用了错误的提交,并且新的,更正后的替换具有不同的含义。哈希ID。当然,一旦替换了这些子项,就必须替换它们的子项,依此类推,一直到任何后代分支提示提交。
理想情况下,您只需使用git rebase
即可解决此问题(如phd suggested)。不幸的是,你说:
...发生冲突
表示第一个错误的提交本身就是合并。您无法为合并设置基础:您必须构造一个新的,更正的合并。
这到底有多难或容易取决于许多因素,例如您对Git的内部运作有多熟悉,以及错误合并的“下游”有多少个提交。如果只有少数几个,则可能需要重复合并,这次没有错误,然后手动复制剩下的一两个提交。
假设错误合并是提交X
,并且它的第一个父级是提交P
:
...--o--P--X--1--2 <-- master (HEAD)
/
...---o--o <-- otherbranch
这里只有两个后续提交,因此您可以:
git checkout <hash-of-P>
git merge otherbranch
与上次相同的冲突也会发生,但是这次您可以正确地解决它们,因此.gitmodules
是正确的。然后:
git cherry-pick <hash-of-1>
git cherry-pick <hash-of-2>
将在此新的替换合并上方复制提交1
和2
:
,-X'-1'-2' <-- HEAD
/ /
...--o--P-/-X--1--2 <-- master
| /
|/
...---o--o <-- otherbranch
其中X'
,1'
和2'
是新的和改进的版本。 (当选择1
或2
固定的.gitmodules
中的任意一个时,您可能必须采取更正的.gitmodules
来解决合并冲突;或者Git可能会看到两者变化会导致同一件事,并确定没有冲突。)
然后,您可以强制名称master
来标识提交1'
,此后您就可以忘记曾经提交过X
,1
和2
存在:
...--o--P--X'-1'-2' <-- master (HEAD)
/
...---o--o <-- otherbranch
现在您可以git push -f research master
。
除此方法外,您还可以:
git checkout
直接合并错误(git checkout hash-of-X
); .gitmodules
文件以对其进行修复,并git add
结果; git commit --amend
:使X'
。这可能至少要容易一些,因为您不必重复其余的合并。然后,您可以重复摘樱桃。
如果在错误合并之后有很多提交,那么可以一次使用git rebase --onto
来大量复制它们,而不必一次选择一次。这只能确保在这一系列的提交中没有合并。也就是说,上述几种图形都可以正常工作,但是:
3--4--5
/ \
...--o--P--X--1--2------6--7--8 <-- master (HEAD)
/
...---o--o <-- otherbranch
可能不会,因为提交7
是合并:git rebase
将完全删除它,并尝试在X'
或{{1 }}。 可以可以,取决于您的需求。
最新版本的Git具有1-2-3-4-5-6-8
标志,它将重新执行合并(在复制其他提交时,则提交1-2-6-3-4-5-8
)。您可以在这种情况下使用它。
或者,最后,您可以将--rebase-merges
与git cherry-pick
结合使用。如果您在坏的一个和/或许多分支和合并操作的下游“下游”提交了成千上万的提交,那将是最合适的。否则,您不妨坚持修复错误的合并,然后重新定基或挑选剩余的提交。