如何更改CS50拥有的回购的默认分支



我正在参加哈佛大学的CS50网络课程,我正在努力提交我的Capstone项目。我们需要将我们的项目推向以下确切的分支:

web50/projects/2020/x/capstone

每当我对代码进行更改时,我都会将其推送到这个分支。最近,我意识到我在不该推送venv文件夹的时候一直在推送它,所以我将其添加到.gitignore,但该文件夹没有从分支中删除。因此,我通过GitHub的web界面手动删除了该文件夹。现在,每当我试图将我的项目推送到这个分支时,它都会被拒绝,因为我的本地文件和远程文件不同步。

我原以为我会删除这个分支然后重新开始,但事实证明web50/projects/2020/x/capstone是默认的分支(我不确定它是怎么变成这样的),我只能删除非默认的分支。我认为在GitHub上没有办法更改默认分支。我无法访问回购的设置,因为它不是我的回购。

我可以将所有文件推送到另一个分支,但作业必须在该分支(web50/projects/2020/x/capstone)上交,否则将不会进行评分。

如果不明显的话,我是新手。有没有办法改变不是我的回购的默认分支?

TL;DR

保存任何无法轻松重新生成的文件,1在现有工作树之外的某个地方。然后,GitHub存储库中的git fetch合并或重新基础。这可能会删除一些文件。这没关系,因为你已经把它们保存在Git无法破坏它们的地方,所以现在你可以把它们放回并继续使用它们。


1除了requirements.txt等,.venv中的几乎所有内容都应该是微不足道的,无法重新生成。


要回答标题和此处的问题:

。。。事实证明,web50/projects/2020/x/capstone是默认的分支(我不确定它是怎么变成这样的),我只能删除非默认的分支。我认为在GitHub上没有办法更改默认分支。我无法访问回购的设置,因为它不是我的回购。

GitHub上存储库的所有者——或者更准确地说,任何拥有";管理员访问"--是可以设置默认分支的人。有关详细信息,请参阅此GitHub文档页面。

要回答您可能应该问的问题,需要更多的内容:

最近,我意识到我一直在推送我的venv文件夹,而我不应该推,所以我把它添加到.gitignore,但文件夹没有从分支中删除。因此,我通过GitHub的web界面手动删除了该文件夹。现在,每当我试图将我的项目推送到这个分支时,它都会被拒绝,因为我的本地文件和远程文件不同步。

哈佛大学可能应该在这里开设一门关于源代码管理的迷你课程,因为在这一点上你可能需要取消学习一些东西。Git中发生的一些事情必然很困难,因为Git实际上是一种分布式数据库,它选择可用性和分区容忍度而不是一致性(请参阅维基百科关于布鲁尔定理的文章)。其他一些事情很困难,也许是因为Git太刻薄了。然后我们将GitHub添加到混合中,事情变得非常复杂。

不管怎样,你在这里介绍了一个";一致性";问题,使事情不同步。但不一致的不是文件。Git在单个文件上不起作用——至少在这个级别上是这样——而是在提交时起作用。你不推送文件:你推送提交。你不推送文件夹——事实上,Git一开始就不存储文件夹;请参阅以下内容,而不是提交(或单个提交)。

提交实际上是Git存储库中的基本存储单元。因此,您必须准确了解Git提交是什么以及它对您有什么作用。因为这不是你所问的(答案会很长),我不会在这里讨论所有细节,但我要说的是,每次提交都会以一种特殊的、奇怪的、Git化的方式存储所有文件的完整快照,压缩和消除重复的表单。然后,每个提交都用一个唯一的哈希ID(在每个Git存储库中的所有提交中)对进行编号。一旦您进行了一些提交,它的每一部分都被永久冻结:这个哈希ID现在意味着提交(在每个存储库中,甚至是那些没有提交的存储库中),因为如果两个不同的Git数据库相遇,并且每个人都必须就数字达成一致,那么提交将被移交给其他存储库,所以这里的一切都不会改变。

Git从Git的索引中生成提交快照。这个";索引";thingy是如此重要,和/或命名如此糟糕,以至于它有另外两个名字:Git也称它为暂存区,指的是你如何使用它,以及(现在很少)缓存。您通常在git rm --cached之类的东西中看到这个姓氏,它从Git的索引中删除一个文件,而不从工作树中删除它。

你不能看到提交中的内容——至少,不能直接或容易地看到。提交中的内容被一直冻结,这意味着它作为一个存档很好,但对于完成任何实际的工作都毫无用处。这样做的结果是,要完成任何实际的工作,Git必须提取一些提交到一个有普通非Git化文件的区域。Git将此工作区域称为工作树的工作树

重要的是要意识到工作树中的文件不是Git中的。它们很可能刚刚从Git中退出(从提交中退出),但因为它们是普通文件夹中的普通文件,而Git并没有;做";文件夹,至少不在它提交的索引中——它们不是Git文件。它们只是普通的文件。

索引/暂存区的存在是Git让你一直使用git add的原因。命令git addpath/to/file打开Git并读取工作树中名为path的文件夹中名为to文件夹中的名为file文件。这是一个普通的文件。然后,Git将其内容压缩为Git将在下一次提交时使用的内部格式,并确保这些内容以Git文件的形式准备就绪,该文件的名称现在是path/to/file,并带有(正向)斜杠(即使您的操作系统使用反向斜杠)。Git(间接地)将压缩、消除重复、Git化的数据存储在索引中,准备提交。

当您运行git commit时,Git只需将封装在其索引中。这将成为您即将进行的新提交的快照。(元数据,我们在这里没有讨论过,现在是动态构建的。)因此,索引充当了一个区域,你可以,嗯;阶段";一些用于提交的文件:因此名称为";"集结区">2你没有的文件"阶段性";仍然存在于现有的舞台上

这就是在.gitignore中添加文件名时出错的地方在Git索引的文件在Git索引中,无论其名称或某些前缀(如.venv/)是否出现在.gitignore中。这意味着git commit将包含它。要下一次提交中删除文件,您必须从Git的索引中删除该文件,在这里您的恐惧是合理的:

这会有更改/删除任何本地文件的风险吗?

使用git rm移除文件告诉Git:从您的索引和我的工作树中移除此文件。从两个位置都删除后,它现在已经消失了,不会出现在下一次提交中。

这就是git rm --cached存在的原因:它告诉Git将文件从索引中移除,但保留我的工作树副本。现在,该文件已从索引中消失,不会出现在下一次提交中,并且现在列出该文件的前缀(如文件夹名)将阻止该文件使用普通git add返回Git的索引中。

不幸的是,故事还没有结束。幸运的是,现有的提交(实际上是)不能被更改,并且每个提交都有一个每个文件的完整副本。因此,如果你不小心从Git的索引中删除了venv/important-data,并从你的工作树中删除了等效文件,并且想要回你的重要数据,你可以从任何有它的旧提交中获得它——或者至少是它的冻结版本

要取回某个文件的旧冻结版本,您可以:

  • 检查整个旧提交(使用Git的"分离的HEAD"模式):这将从旧提交中填充Git的索引和工作树,现在文件又回来了;或
  • 使用git restore:3从旧提交中提取一个文件,这样可以控制文件的副本是否进入Git的索引

令人困惑的是,一旦文件在Git的索引中返回(例如,如果您git switch --detach HEAD@{yesterday}),如果您稍后切换回提交,省略文件,Git现在将文件删除(从Git的索引和工作树中)。这是提交-签出操作的自然结果,这意味着提取给定的提交,这反过来意味着使Git的索引和我的工作树与给定的提交匹配。这需要在工作树中创建和/或删除各种文件。


2索引在合并操作中扮演着扩展的角色,尤其是在出现冲突时。这是以用户为导向的主要原因,称之为";索引";而不是";集结区":有时,每个文件有三个副本,而不是只有一个。但在平时;索引";以及短语";集结区";几乎可以互换。

3在2.23之前的Git版本中,此操作必须使用git checkout。这是一种不同于完全提交签出的类型,并且这种老式的git checkout总是";通过";索引,在计算机硬件设计中具有写通缓存的风格。新的restore命令在这里显然更好。


合并或重定基础

为了达到您需要的目的,您需要将您现有的提交合并或重新设置为通过GitHub web界面进行的新提交的基础。

git merge命令从根本上来说要简单得多,它就是这里要描述的命令。但由于篇幅的原因,我不会详细介绍:请参阅其他StackOverflow问答;A了解详细信息。

之后:

git fetch origin

您将在自己的(本地)Git存储库中有一个更新的origin/web50/projects/2020/x/capstone名称。该名称在"em"中查找最近的提交;分支";,其中分支表示以特定的最近提交结束的系列提交。参见我们所说的";分支"?

同时,您有自己的最新提交,以您现在的任何提交结束,作为您当前分支的最近提交,无论其名称是什么(master?)。这个分支名称对Git来说根本不重要:重要的是提交。分支名称只是一个设备,通过它你不必记住大而丑陋的随机Git哈希ID。

要将您自己的最新提交与GitHub的最新一次提交相结合,您现在需要运行:

git merge origin/web50/projects/2020/x/capstone

这使用名称origin/web50/projects/2020/x/capstone来定位您刚刚通过git fetch获得的最新GitHub提交。这使用任何分支名称";关于";现在——就像在中一样,git statuson branch master或其他什么——来定位您自己的最新提交。然后它使用历史提交";在"后面";这两个最新提交中的每一个都是为了找出过去您的存储库和GitHub存储库最后一次同步的位置。这是一系列的提交,以"提交"结束;最好的";(最新)共享提交,在这张图中很容易被视为提交*

o--o   <-- master (HEAD)
/
...--o--o--*

o   <-- origin/web50/projects/2020/x/capstone

(这里,较新的提交向右,每个提交都表示为o*;这些提交通过提交元数据向后链接到它们的父级提交)。

在获得这三个提交的哈希ID后,Git开始合并(作为动词)自该共同起点以来完成的工作。Git会看到,在GitHub端(底部一行的提交);工作完成";涉及删除一些文件。如果你没有在你的提交中修改这些文件(沿着最上面的一行),Git将合并"他们的";(你真的)用你自己的";对这些文件什么都不做";以获得";删除这些文件";作为最终结果。

因此,此git merge操作将从索引和工作树中删除您通过web界面删除的文件。就好像您在每个这样的文件上运行了git rm

如果一切顺利——而且很可能会——就Git本身而言,Git现在将提交结果,生成:

o--o
/    
...--o--o--*   ,--M   <-- master (HEAD)
 /
o   <-- origin/web50/projects/2020/x/capstone

注意新的合并提交CCD_;点后";到您上一个提示提交(最右边的顶行o)";他们的";提示提交(底部行o)。因此,commitM添加到两个存储库中的所有commit数据库中。

这意味着您现在可以使用git push origin master:web50/projects/2020/x/capstone将提交M发送到GitHub,并且这两个独立的存储库数据库再次保持一致。

注意:如果将本地master重命名为web50/projects/2020/x/capstone(您可以随时执行此操作),并将其上游设置为origin/web50/projects/2020/x/capstone:

git branch -m web50/projects/2020/x/capstone
git branch --set-upstream-to=origin/web50/projects/2020/x/capstone

您将能够在没有参数的情况下运行git push,并且git status将打印更多信息。这并没有做任何你以前做不到的事情,它只是让Git更易于使用(无论如何,对大多数人来说)。

首先,将所有origin/refs更新为最新版本:

git fetch --all

备份您当前的分支机构:

git branch backup-branch

跳转到origin/web50/projects/2020/x/capstone上的最新提交并签出这些文件:

git reset --hard origin/web50/projects/2020/x/capstone

从这里开始,您应该能够将备份分支与web50/projects/2020/x/capstone分支合并,并推动新的更改。

查看此线程:https://stackoverflow.com/a/8888015/2255327

最新更新