将子文件夹推送到 GitHub,而不是父目录

如何解决将子文件夹推送到 GitHub,而不是父目录

我有一个名为“Project”的父目录,其中包含两个子文件夹“Data”和“Writing”。我在“项目”上有一个 git 目录,我想将“Data”文件夹push 放到一个私有的 GitHub 存储库中。我有一个到 GitHub 的 SSH 连接。

  1. 我如何git push只将“Data”文件夹放到 GitHub 上(同时将“Writing”文件夹保留在我的本地计算机上)?
  2. 我是否应该为“Data”文件夹创建另一个 git 目录并将其 git remote 放到 GitHub 存储库中?还是子模块更好?

如果您提供个别步骤,我将不胜感激。谢谢。

解决方法

Git 不推送目录/文件夹;它甚至不推送文件。 Git 推送的是提交,因为这是 Git 包含的内容。 Git 存储库 实际上是一个大型提交数据库。每个提交都有编号,有一个丑陋的大哈希 ID,该 ID 对该特定提交是唯一的,1 并且您的存储库要么有一些特定的提交(它通过编号找到),要么没有完全提交。所以 Git 需要知道的只是数字;这就是 Git 如何实现其分布式版本控制系统存在的“分布式”部分。你连接两个 Git,然后他们比较他们的数字(只是数字!)来找出谁拥有什么。

当然,提交本身包含文件。这些文件具有完整路径,例如 Data/some/name.extWriting/another/file 或其他任何内容。请注意,斜杠是文件名的一部分:此处没有文件夹。文件夹是你操作系统的产物,它需要 Git 用斜杠将它们分解,然后创建文件夹。

当您使用通过 Git 存储库获得的文件时,您处理/使用的文件不是存储库中提交中的文件! (那些文件以 Git-only 格式存储,只读,压缩,并在所有提交中进行重复数据删除。因此,每个提交都有一个 每个文件的完整副本并不重要,因为共享某个文件的相同版本的两个或多个提交实际上共享一个副本。)Git 只是复制某个文件的提交版本——嗯,整个将文件版本的快照提交到您的工作空间,供您处理/使用。那些文件,在文件夹中,在你的工作树中。但它们并不 Git中:它们是 Git中复制出来的,如果您进行新的提交,Git将制作它们的新副本——或者通过以下方式共享现有副本它的重复数据删除过程——在一个新的提交中。

当您使用 git push 时,您选择 commits 以发送到其他一些 Git。整个提交进行。如果您希望提交仅包含名为 Data/some/name.ext 的文件,而不包含任何名为 Writing/another/file 的文件,则需要进行此类提交。

可以在一个存储库中做到这一点,或者您可以通过创建多个不同的存储库(每个存储库都有自己独立的工作树)来做到这一点。在单个存储库中执行此操作非常棘手如果该存储库将具有其中包含 Writing/another/file 的提交,但可以做到。

所有这些都是人们在使用 Git 时实际使用的组织的原因。一般来说,一个仓库有一个工作树;一个工作树中包含来自该存储库中提交的文件。所有这些文件都将进入该存储库中的未来提交。2每个提交都有每个文件的完整快照,即使文件没有更改。 (这就是为什么在提交中使用特殊的 Git-only、not-normal-files-at-all 存储格式对它们进行重复数据删除的原因。这也是 Git 可以存储实际上不能的文件的方式em> 在您的计算机上解压缩(如果您运行的是 Windows)。3)

你提到了子模块。关于子模块需要了解的是:它们只是另一个 Git 存储库。也就是说,您可以拥有一个您克隆的 Git 存储库(我们称之为 outer):

git clone <url-of-outer>
cd outer                  # get into the clone we just made

您现在可以 git checkout 使用 git clone 创建的存储库中的任何提交,它复制了其他一些提交4 Git 在给定的 URL 上接听电话/短信/任何你喜欢的类比。

与此同时,部分或全部提交你刚刚创建的克隆中说,实际上:现在,在sub/中,让我从另一个 Git 存储库。 另一个 Git 存储库的 URL 位于每个提交中的一个名为 a123456 的文件中,因此您的系统上的 Git 可以执行以下操作:

.gitmodules

或等价物(如果需要),以创建 (mkdir -p sub && cd sub && git clone <url> .) 克隆。一旦 sub 目录存在并克隆了 other Git 存储库,您在 sub/ 中运行的 Git 就可以运行:

outer

检出该提交。请注意,我们现在最多有 4 个 Git 存储库:一个在您列出的 URL 中,您的在 (cd sub && git checkout a123456) 中,一个在 outer 中列出的 URL 中,一个在 .gitmodules 中。>

子模块可以很好地工作,但有几个问题。简而言之,它们比没有任何子模块的存储库更重要。它们曾经非常痛苦,以至于人们称它们为 sob 模块。现在情况好多了,但仍然不是很好。

这里最重要的是围绕 Git 模型:一个 存储库 保存 提交:

  • 您通过哈希 ID 检查提交——不过,通常使用分支名称来查找哈希 ID——现在您将快照中的文件存储在提交中.每个提交都有每个文件的完整快照。

  • 您在您的工作树中使用这些文件的副本。

  • 您使用 outer/sub/ 来让 Git 更新其提议的 next 提交——它开始匹配您得到的提交。 git add 命令的工作原理是将您在 Git 索引(即暂存区)中提议的下一次提交与您使用 git status 或(在 Git 2.23 或更高版本中)检出的当前提交中的内容进行比较 {{1} }.5 它还单独比较下一次提交建议中的内容与您的工作树中的内容。

  • 最终,您运行 git checkout 从提议的下一次提交创建一个提交。该提交使用索引/暂存区中的文件——它充满了每个文件; git switch 仅告诉您关于不同 文件以保持输出较小 — 以制作新快照。它还添加了各种额外信息,例如您的姓名和电子邮件地址。6

  • 一个新的提交改变了存储在您的分支名称中的哈希 ID。你的分支名称是你的,不是别人的。

  • 一旦您有新的提交,您就可以使用 git commit 将这些提交发送到某个其他 Git 存储库。这会将您的提交直接添加到他们的 分支。也就是说,推送要求他们更改他们的分支名称。

  • 无论您是否有新的提交,您都可以使用 git status获取 新的提交来自某个其他 Git 存储库——通常是您克隆,称为 git push。这不会影响您的分支!这只会更新您的远程跟踪名称:您的 Git 对其分支的记忆。

  • 一旦您从其他人那里获得新的提交,您可能希望将它们合并到 的一些分支中。这需要第二个命令,例如 git fetchorigin

  • 这个由两个命令组成的序列——获取,然后是合并或变基——非常常见,所以 Git 将它包装成一个 git merge 命令。如果您是初学者,我建议避免这个提交,因为有些事情会出错。很难知道当它运行两个你还不真正理解的命令时发生了什么。如果您知道实际运行的是哪个命令,那么事情可能仍然会出错,但现在您知道要询问什么。 (但人们仍然喜欢 git rebase,所以如果你喜欢,请记住:它运行两个命令。)


1此 ID 在所有 Git 存储库中是唯一的。在一些不寻常的情况下,一个哈希 ID 号可能用于两个不同 Git 存储库中的两个不同提交,但如果是这种情况,这两个 Git 存储库将无法再相互通信,因为提交 ID 需要是独一无二的。在当前时间,ID 被错误使用的几率是 2160 中的 1(并且最终会更高),这小到可以忽略。

2这些未来的提交由 Git 调用的东西组成,例如索引暂存区缓存,但我不会在这里详细介绍。请注意,Git 实际上并没有从工作树文件中进行新的提交。索引在某些方面与工作树很好地配对,但是您必须显式地将 git pull 文件复制回工作树,提交之前的索引。

如果您选择使用 git pull,请注意这仅意味着 在进行提交之前运行 git add 的一个版本,因此您实际上仍在使用 {{1 }}。使用 git commit -a 试图忽略这个索引/暂存区的存在很诱人,但我发现这是不明智的:Git 偶尔会设法用它的索引,如果你不知道它是什么,你会讨厌使用 Git。

3例如,Git 可以存储名为 git add 的文件,但 Windows 不能。如果您有一个包含 git add 的提交,并检查它,您将收到关于文件名的投诉。 Git 仍然可以处理这些提交,甚至可以进行包含更新的 commit -a 的新提交,尽管这样做很棘手:正常的工作方式并不(工作),因为 Windows 无法存储 { {1}} 个文件。但是 Git 可以,因为提交的文件不是文件:它们是特殊的 Git 对象,采用冻结和重复数据删除的格式。

4这有点棘手,但认识到这一点也很重要:当你克隆一个存储库时,你会得到他们所有的提交,但没有他们的 >分支机构

技术上更正确的是,您会在克隆中获得一个分支名称。您获得的分支名称由您决定:您可以在 aux.h 时间将 aux.h 参数提供给它。例如,aux.h 让您的 Git 创建并签出名为 aux.h 的分支。如果您提供 git clone 选项,您的 Git 会询问他们的 Git 他们推荐哪个分支名称,并使用该名称。通常默认情况下,您的 Git 使用 -bgit clone -b develop <url>,如果他们已将其主分支名称切换为 develop(例如,较新的 GitHub 存储库)。

与此同时,您的 Git 确实知道他们分支的名称。您的 Git 在 -b 操作期间看到了所有这些。但是,您的 Git 对它们的分支名称所做的是将它们转换为您的远程跟踪名称。这些名称类似于 master(或 main)、main 等。也就是说,我们只需在他们的分支名称前面加上 git clone 字样,就可以使您的远程跟踪名称。这些名称​​记住它们的分支名称。

这些远程跟踪名称允许您的 Git 从它们的名称​​创建自己的分支名称。但是当您这样做时,该分支名称现在是您的。他们的 Git 不能弄乱您的 分支,因为您的 Git 不断将其名称更改为您的远程跟踪名称。这里还有很多东西要了解,但这足以让您入门。

5origin/master 命令有两种模式:一种“安全”模式,不会破坏工作树中未保存的工作,另一种“不安全”模式,如果你问Git 使用它,。不幸的是,一些不安全的 origin/main 看起来与安全的完全一样。这是一个糟糕的情况,因此在 Git 2.23 中,Git 人员将 origin/develop 命令拆分为 origin/(这只是“更安全”的部分)和 git checkout,后者运行“不安全”请清除我的工作,我决定将其扔掉套操作。如果您有 Git 2.23 或更高版本,那么教您的手指养成新的 git checkout 习惯是明智之举。 (我自己仍在努力。)

6这个额外的信息是提交元数据。您不需要学习这个技术术语,但您最终需要至少了解此元数据中的一些内容。不过,我们也将其留待以后使用。

,

我是否应该为“Data”文件夹创建另一个 git 目录并将其远程 git 远程到 GitHub 存储库?
还是子模块更好?

实际上,即使您将 Data 作为子模块引用,这仍然意味着 Data 是它自己的存储库。

是的:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?