Skip to main content

Git WTFS

本文档旨在帮助您解决在 Git 中经常遇到的奇怪技术故障情况 (WTFS)。它会随着问题的出现而不断更新。

fatal: refusing to merge unrelated histories (致命错误:拒绝合并不相关的历史分支)

通常,当您从主干代码(skeleton code)拉取更新后,如果其他人修改了主干代码,就会发生这种情况。使用 --allow-unrelated-histories 进行拉取,例如:

$ git pull skeleton main --allow-unrelated-histories --no-rebase

您可能需要解决一些由此产生的合并冲突

或者,如果您从您自己的 s*** 学生仓库(例如,在不同的计算机上)拉取,

$ git pull origin main --allow-unrelated-histories --no-rebase

HEAD detached at [...] ?? (HEAD 处于分离状态 [...] ??)

注意: 从 FA23 课程开始,由于推荐使用 git restore 命令,此问题应该会大大减少。

$ git status
HEAD detached at 1193e06
Untracked files:
(use "git add <file>..." to include in what will be commited)

../seitan/

nothing added to commit but untracked files preset (use "git add" to track)

很可能,您可能使用了 git checkout 命令,但没有指定文件(或目录)。没关系!如果您没有进行任何更改,您可以使用命令 git switch main 来修复此问题。如果一切正常,您应该看到类似以下的消息:

$ git switch main
Previous HEAD position was b405852... added tofu recipes
Switched to branch 'main'

如果您进行了一些更改(即使用命令 git status 告诉您您已修改了一些文件,如下图所示),则需要执行更多步骤。

$ git status
HEAD detached at 1193e06
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: kung_pao_tofu.txt

Untracked files:
(use "git add <file>..." to include in what will be commited)

../seitan/

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

首先,使用命令 git stash。您的修改可能已经神奇地消失了!别担心 - 我们稍后会找回它们!

$ git stash
Saved working directory and index state WIP on (no branch): 1193e06 added tofu
recipes HEAD is now at 1193e06 added tofu recipes

$ git status
HEAD detached at 1193e06
Untracked files:
(use "git add <file>..." to include in what will be commited)

../seitan/

nothing added to commit but untracked files preset (use "git add" to track)

从这里开始,使用命令 git switch main。您应该会看到之前的正常提示信息:

$ git switch main
Previous HEAD position was b405852... added tofu recipes
Switched to branch 'main'

快完成了!让我们去获取我们的更改。使用 git stash pop。等等,出现冲突了!(并非总是如此。如果没有冲突,就可以跳过以下步骤。)

$ git stash pop
Auto-merging tofu/kung_pao_tofu.txt
CONFLICT (content): Merge conflict in tofu/kung_pao_tofu.txt

$ git status
On branch main
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)

both modified: kung_pao_tofu.txt

Untracked files:
(use "git add <file>..." to include in what will be committed)

../seitan/

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

现在使用 git stash drop.

$ git stash drop
Dropped refs/stash@{0} (57f0ac5c5480964cdf29a94ed6b87e38da823488)<Paste>

现在我们需要解决这个合并冲突了。要学习如何解决,请查看这里

错误:无法推送某些引用?

有时,当与他人协作时,推送时会看到如下消息:

$ git push origin main
To https://github.com/gilbertghang/recipes.git
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/gilbertghang/recipes.git"
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

这里发生的情况是,您的远程仓库(也就是您在 GitHub 上的仓库)包含您的本地仓库没有的提交。幸运的是,Git 会很贴心地提示您如何修复这些错误:仔细阅读错误信息,您会发现它会提示您使用 git pull 命令。照着做,解决掉所有合并冲突,然后推送。搞定!

我的代码里这些 >>>> 符号是干嘛的?

有时,当您从存储库中拉取时,您会在拉取时看到如下消息:

$ git pull origin main
From github.com:Berkeley-CS61B/course-materials-sp16
* branch main -> FETCH_HEAD
Auto-merging proj/proj0/solution/canonical/Planet.java
CONFLICT (content): Merge conflict in proj/proj0/solution/canonical/Planet.java
Automatic merge failed; fix conflicts and then commit the result.

这里的问题是,您电脑上的代码和您要拉取的远程仓库里的代码有冲突,Git搞不清楚怎么解决,所以拒绝覆盖您的本地代码。

但是,当您打开 Planet.java 时,您会看到一些疯狂的垃圾,例如:

    public Planet(Planet p) {
<<<<<<< HEAD
this.xPos = p.xPos;
this.yPos = p.yPos;
=======
this.xxPos = p.xxPos;
this.yyPos = p.yyPos;
>>>>>>> 27ddd0c71515e5cfc7f58a43bcf0e2144c127aed

这说明有冲突!<<<<<<< HEAD======= 之间的内容是您电脑上的,=======>>>>>>> 27ddd0c71515e5cfc7f58a43bcf0e2144c127aed 之间的内容是远程服务器上的。

您需要做的就是找到这些标记,然后自己解决冲突。如果远程仓库的内容是正确的,就把 <<<<<<< HEAD======= 之间的内容,以及 >>>>>>> 27ddd0c71515e5cfc7f58a43bcf0e2144c127aed 这个标记删掉,留下:

public Planet(Planet p) {
this.xxPos = p.xxPos;
this.yyPos = p.yyPos;

解决完所有冲突后,把手动修改过的文件都添加并提交,像这样:

git add Planet.java
git commit -m "resolved merge conflict"
git push origin main

错误:您还有未完成的合并 (MERGE_HEAD exists)。

如果您看到如下消息:

error: You have not concluded your merge (MERGE_HEAD exists).
hint: Please, commit your changes before merging.
fatal: Exiting because of unfinished merge.

先添加并提交您当前的修改,然后再拉取。

如果再次拉取后,终端提示类似“Please enter a commit message to explain why this merge is necessary”的信息,请参考后面的章节。

请填写提交信息,说明为何需要合并

如果您看到如下信息:

Merge branch 'main' of https://github.com/Berkeley-CS61B/skeleton-sp24
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.

Git 已经打开了一个终端文本编辑器,让你填写提交信息。你可以直接用默认的提交信息,然后退出编辑器。

如果您在终端底部看到类似以下内容:

^G Get Help      ^O WriteOut      ^R Read File      ^Y Prev Pg      ^C Cur Pos

这说明你正在使用 Nano 文本编辑器。退出的话,按 Ctrl+X (同时按)。

如果终端左边出现一堆波浪线 (~ 符号),并且底部显示类似:

".git/COMMIT_EDITMSG" 9L, 273C      13,1      All

这说明你正在使用 Vim 文本编辑器。要保存并退出,输入 :wq (先按冒号,再按字母 w 和 q)。

fatal: 'skeleton' 似乎不是一个 Git 仓库

如果您看到如下信息:

fatal: 'skeleton' does not appear to be a git repository
fatal: Could not read from remote repository.

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

Git 可能找不到 skeleton 仓库。

尝试运行 git remote -v。如果你的仓库设置没问题,应该能看到:

origin  [email protected]:Berkeley-CS61B/sp24-s*** (fetch)
origin [email protected]:Berkeley-CS61B/sp24-s*** (push)
skeleton https://github.com/Berkeley-CS61B/skeleton-sp24.git (fetch)
skeleton https://github.com/Berkeley-CS61B/skeleton-sp24.git (push)

如果只看到 origin 的两行,没看到 skeleton 的,说明 Git 找不到 skeleton 仓库。

要解决这个问题,运行:

git remote add skeleton https://github.com/Berkeley-CS61B/skeleton-sp24.git

然后再次运行 git remote -v,确认能看到 originskeleton 各自对应的两行。