你被哪些 Git 陷阱所困扰?

12
我曾经遇到的最糟糕的情况是与 git 子模块有关。我在 Github 上有一个项目的子模块。由于该项目已经不再维护,我想要提交补丁,但是无法提交,所以我进行了 fork。现在子模块指向原始库,而我需要将其指向 fork 版本。因此,我在同一次提交中删除了旧的子模块,并用新项目的子模块来代替它。结果发现这破坏了其他人的代码库。我仍然不确定处理这种情况的正确方法是什么,但最终我删除了子模块,让所有人拉取和更新,然后我创建了新的子模块,并让所有人再次拉取和更新。整个过程花了大部分时间。
其他人有哪些非明显方式误操作 Git 代码库,该如何解决?

1
这是一个重复的问题,链接为https://dev59.com/DnI_5IYBdhLWcg3wMf5_,应该合并回答。 - innaM
“Gotcha”并不是“反模式”的同义词。我问了关于存储库销毁的问题,他问了关于最糟实践的问题。 - Bob Aman
9个回答

15

添加子模块时通常不要使用尾部斜杠:

当您在子模块上使用git add命令时,请确保没有使用尾部斜杠。

> git add local/path
  -- adds the submodule

> git add local/path/
  -- adds all the files in the submodule directly into your repository, big no-no

13

这不是圈套,而是Git的难点。


25
哈哈,+1好笑,-1应该留言。 - Byron Whitlock

7

在没有意识到我的git config user.name有误的情况下发布到公共存储库。


这意味着公共存储库现在会得到一个我不想要发布的名称(和电子邮件)。如果该存储库被复制,...那就太晚了。

这就是为什么我更喜欢在我的git提示符shell中显示我的user.name,而不是这样:

 MY_HOSTNAME /c/Prog/myGitProject (master)$

我看到这个:

 MY_HOSTNAME /c/Prog/myGitProject (master) VonC $

我知道在这个Git bash会话中,我从第一个输入的命令就可以确认自己的身份!

设置一个你满意的全局用户名通常可以避免这种情况。 - Kzqai
@Tchalvak:是的,但你有几个本地仓库,每个仓库需要不同的名称才能推送到各自的上游(远程)仓库……全局变量是不够的。 - VonC
当然可以,但这就成为设置一个默认的名称/电子邮件,您不介意公开,只在特定情况下使用更敏感的名称/电子邮件的问题了。 耸耸肩 - Kzqai

6
  1. 当你的分支上出现了很多匹配项时,才意识到在 .gitignore 中忘记添加某个条目。

  2. 忘记了 git add 不会添加不存在的文件...

    git add .
    git commit
    git status
    //嘿!为什么我的删除没有提交?哦,是我太糊涂了
    git add -u
    git commit --amend
    

  3. 如果你执行 git branch list 命令,你会得到一个名为 list 的新分支;但如果你执行 git stash 命令,你会将你的工作区存储起来;对于存储,如果你想要这个列表,你就需要 这个 list...

很快就会有更多内容...


2
显然有"git add -A"这个命令,它可以同时完成两种操作。 - Benjol
但是你说的“不存在”的意思是什么? - Mads Skjern

3
  1. 工作 工作 工作
  2. 隐藏更改
  3. 获取最新版本
  4. 变基
  5. 获取冲突,解决它们
  6. 忘记执行 "git rebase --continue"
  7. 弹出存储
  8. 意识到我忘记执行 "git rebase --continue"
  9. git rebase --abort
  10. 我最初隐藏的更改 - 消失了。

8
不,这只是个小烦恼。你的备份仍然在你的代码库中,你只需要找到它。如果你在控制台会话中看到哈希值,那么就可以找到了!如果没有,使用 'git fsck'来定位备份。更多详细信息请参见此SO答案:https://dev59.com/NXVD5IYBdhLWcg3wGXlI - Bob Kerns

2

工作,工作,工作……

git commit

Work work work ...

git commit

哦,是时候进行集成了。
git rebase -i origin/master

什么?冲突了?让我们重新开始。
git reset --hard origin/master

哭泣哭泣哭泣...


Git让你毫不犹豫地清除本地历史记录。最大的陷阱是,就是安全网。


7
那太棒了,感谢git reflog。 :) - Bombe
git reflog 能让我看到被删除的提交吗?它只列出活动记录,而我已经执行了 reset --hard(已更新答案,之前是错误的)。 - Robert Munteanu
“git reset --hard” 是导致自己犯下大错的主要方式之一。因此,我不再使用它了。我只是使用“git reset HEAD~1”,然后根据需要使用“git checkout”单独检出文件。 - Kzqai
5
这是完全错误的。你的历史记录仍然存在,只是你不知道如何找到它。可以使用'git reflog'作为起点。找到你想要的提交版本,并创建一个分支。即使您不知何故丢失了指向提交版本的所有指针,它也不会被垃圾收集器删除,大约需要30天时间(可配置)。请参见'git fsck'。使用git实际上很难真正丢失任何东西。如果使用SVN,您可能根本不会首先提交这些更改,因此如果您丢失它们,它们将永远消失。 - Bob Kerns
你在使用 git reset --hard origin/master 命令时想要输入什么?为什么要使用除了 git rebase --abort 以外的其他方法来中止失败的 rebase? - Max Nanasy

1

我在使用git存储库时遇到了一个最尴尬的时刻,虽然这更多是关于sed的:

有一次我在存储库的子目录中执行了find ... -exec sed -i ...操作。我先测试了没有-i的情况,然后分心了一下,回来时在运行它之前成功地切换到了我的存储库的顶级目录。现在,git的重要文件都是只读的,但是默认情况下sed -i通过重命名文件并写回原始文件的方式来处理只读文件,因此它可以在像git对象这样的只读文件上正常工作。替换是不可逆的,我不得不通过克隆和从跟踪我的存储库作为远程的某个人那里获取来恢复存储库。

我甚至从未想过sed会在只读文件上起作用。故事的寓意是:使用sed -i -c,它会复制文件,然后尝试覆盖原始文件。


0
创建一个新分支:
git branch new-branch

工作,提交,工作... 发现我的所有工作都在主分支上,而不是新分支上。

我应该这样做:

git checkout -b new-branch

为什么我不能做这样的事情:
git branch -c new-branch

(c表示结账),其中有一个选项可以将其设置为默认行为???


git checkout -b new-branch 应该是首先要做的事情。如果之前没有这样做,可以通过以下步骤进行修复:git checkout new-branchgit merge master(现在两个分支处于相同状态),git checkout master,最后使用 git reset --hard origin/master 将主分支恢复到原始状态。 - Ulrich Eckhardt

0

工作,工作,工作。开始进行一个更改的分期。注意不想提交所有内容。仔细地分期提交一部分。

最终决定这不适用于当前分支。我想将已分期的更改提交到一个新的临时分支。概念上听起来很琐碎,对吧?

搜索如何做到这一点。排名第一的答案说stashcheckout -b newbranchstash pop。勉强这样做,想知道为什么没有更简单的方法。

发现这完全抹去了您已分期和未分期更改之间的区别。谢谢,Git!


工作,工作,工作。在多次迭代的git statusgit diffgit add中进行痛苦而小心的部分提交。最后决定完成任务,输入git commit -a。然后……咕噜噜? - damian
只需提交当前分支的更改。然后,提交其余正在进行中的工作。切换到新分支,在那里挑选出提交。在之前的分支上,使用git revert移除不需要的更改,这样可以将之前挑选的提交还原。最后,在那里使用git reset @~3以从停下来的地方继续开始。;-) - Ulrich Eckhardt
@UlrichEckhardt 是的,这就是我现在做的。先提交,以后再考虑分支。 - Roman Starkov

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