为啥提交一个文件,但所有文件都在 RStudio 中提交?

Posted

技术标签:

【中文标题】为啥提交一个文件,但所有文件都在 RStudio 中提交?【英文标题】:Why Commiting one file, but all files are committed in RStudio?为什么提交一个文件,但所有文件都在 RStudio 中提交? 【发布时间】:2021-10-22 19:42:23 【问题描述】:

我在 Github 上有一个包含一些文件的存储库,我在 RStudio 服务器上也有一个包含一些文件的文件夹。我对一些文件进行了一些更改,但我只想使用命令提交一个文件(test.Rmd)

git init
git add test.Rmd
git commit -m "Adding some plots" 
git push

而不是仅提交此文件,它会提交文件 test.Rmd 所在文件夹中的所有文件。为什么会这样?我尝试对不同文件夹中的另一个文件执行完全相同的操作,并且提交工作正常。在此之前,我似乎已经做了一些事情,比如

git init
git add .

这就是它在目录中添加所有文件的原因?

使用git status 结果

我现在怀疑问题是取消添加这些大文件?我想我在最后使用git push 时不知道我做了所有文件的所有更改。

【问题讨论】:

您如何确认提交中有多个文件? @TTT 来自终端的输出显示了许多对象,最后说检测到大文件,这就是提交失败的原因。我在这里提交的文件只是一个简单的脚本,与那些大文件没有任何关系。我可能在提交之前不小心添加了这个文件夹中的所有文件?但是做git reset并不能解决它 如果您认为您执行的操作可能与您在问题中编写的命令不同,那么您可能已全部提交。它是 repo 中的第一个提交,文件太多吗?如果是,最简单的方法可能是删除整个 .git 目录,然后重新开始。旁注,你说你已经在 GitHub 中有一个 repo。目前尚不清楚您在本地做的事情是否与现有的 repo 有关,它可能已经有更多的文件...... @TTT 我在哪里可以找到 .git 目录?在我连接到 Github 的目录中的 RStudio 中,我只有 .gitignore 和其他文件类型,例如 .Rmd、.R、.h5ad 等。不幸的是,我无法查看历史记录。但我记得我做过cd project (the folder name), git init, git add ., git remote add origin https://github.com/username/repository.git. (copy from https Github the repository I made already where I want to push the commit)。你的意思是我需要从 Github 中删除 .git? 在提交前尝试使用 git status 来查看提交中包含的内容 【参考方案1】:

我已经通过使用 Git lfs for Large files 解决了这个问题。由于我使用的是 RStudio 服务器,因此我要求管理员安装 Git lfs 然后我执行这些操作

git lfs install
git lfs track "*.h5ad, *.h5Seurat"
git add .gitattributes
git lfs migrate info
git lfs migrate info --everything
git lfs migrate import --everything --a #override changes in your working copy? 
[Y/n] Y

然后它将提交推送到 Github。请注意,*.h5ad 和 *h5Seurat 是我希望 Git lfs 处理的大文件扩展名。 我正在关注这个链接git lfs

【讨论】:

【参考方案2】:

您的问题充其量是模棱两可的,并且包含一些错误的假设,所以这个答案很长。

关于 Git 提交和git init 的一些背景知识

Git 中的所有提交始终包含所有文件。这就是 Git 本身的工作原理。

运行git init 将:

在当前工作目录中创建一个新的空 Git 存储库,或者 重新初始化现有的 Git 存储库。

如果 Git 发现您在某个现有的 Git 存储库中,您将获得 second 行为 - 重新初始化现有的 Git 存储库。 git init 的输出告诉你它做了哪一个:

$ git init
Initialized empty Git repository in [path, redacted]
$ git init
Reinitialized existing Git repository in [path, redacted]

除了一些几乎肯定不适用于您使用 Git 的特殊情况外,“重新初始化”变体实际上并没有做任何事情:您现有的存储库保持不变。

git init 创建一个新的、完全空的存储库时,没有提交,因此还没有分支。因此,您所做的 next 提交是有史以来的第一次提交。这个提交有点特别:它是一个 root 提交,没有历史。它包含你告诉 Git 让它包含的任何文件,使用 git add

不过,在这一点之后,您就有了一个现有的 Git 存储库,其中包含现有的提交。这包括您使用git clone 将一些现有存储库(例如,从 GitHub)复制到您自己机器(例如,您的笔记本电脑)上的新 Git 存储库的情况。你会告诉 Git check out 一些特定的提交——通常是一些 branch name 的提示提交——这意味着 Git 将在它的暂存区和你的工作树中填充来自提交的所有文件。

随后,您将编辑一些文件,甚至可能创建一些新文件。然后在其中一个或多个文件上运行git add。如果你git add-ing 一个文件已经存在在 Git 的暂存区,Git 会从它的暂存区扔掉旧的副本,并用你工作的新副本覆盖暂存区的副本树。或者,如果您 git add 一个全新的文件,Git 会将文件复制到其暂存区域中,作为一个新文件。

在所有这些情况下,暂存区中的所有现有文件都保留在那里。您的下一个 git commit 会获取 所有 Git 暂存区中的文件,并从中制作快照。

一个具体的例子

假设您有一个现有的存储库,其中主分支(不管它的名称是什么:GitHub 现在鼓励人们使用main,而较旧的存储库倾向于使用master)在其最近的提交中有十个文件。你 git clone 这个存储库到你的笔记本电脑,所以你的笔记本电脑 Git 软件(“你的 Git”)检查最后一次提交,将十个文件提取到 Git 的暂存区和你的工作树中。

您现在更改了工作树中十个文件中的 五个,但仅对五个更新文件中的 一个 运行 git add。这意味着您的 Git 暂存区中有十个文件:九个文件与 当前提交 中的文件匹配,一个与您的 工作树 中的更新文件匹配。四个暂存区文件不同于它们的四个工作树对应文件;其余六个暂存区文件与其对应的工作树匹配。

如果您现在运行git commit -m haaaaaands,您将获得一个包含十个文件的新提交,与它们现在出现在暂存区域中的完全相同。您的工作树中仍然拥有所有更新的工作树文件,但暂存区域副本仍然与先前提交的副本匹配,因此新提交的副本与旧提交的副本匹配,除了您运行 @987654340 的一个文件@。

您刚刚进行的新提交成为 当前 提交,它现在是当前分支上笔记本电脑存储库中的最新提交。您现在可以使用 git push 将此 commit 发送到 GitHub 存储库;如果并且当您最终这样做时,他们收到的提交将逐位匹配您的 Git 存储在笔记本电脑存储库中的提交。它将有 9 个文件匹配一个文件不匹配的情况;他们获得的提交将以先前的提交作为其父提交;等等。

关于git status的注意事项

首先,git status 告诉您有关当前分支的信息。它会说类似on branch main。这是您的 Git,告诉您您的笔记本电脑存储库有 main 作为当前分支。您的 Git 也可能会告诉您“领先”和/或“落后”某个其他名称,例如 origin/main:这使用存储在您的笔记本电脑上完全本地的信息。此信息可能已过时,具体取决于其他 Git 存储库在 GitHub 上或其他任何地方的活跃程度。

接下来,如果您没有处于冲突合并的中间——如果是,其余的会变得更加复杂——git status 命令运行两个比较:

首先,它将当前提交中的文件与暂存区中的文件进行比较。其中一些文件通常会完全匹配,因为自从它们从某个提交中提取后,您没有对它们做任何事情。对于这些文件,你的 Git 什么也没说。

暂存区中的其他文件不会与您当前的提交匹配,因为例如您在它们上运行了git add。在这种情况下,您的 Git 会说这些文件是暂存以供提交。这仅仅意味着暂存区副本与当前提交的副本在某些方面有所不同。

请注意,暂存区中的某些文件可能是新文件。也就是说,这些文件在 current 提交中根本不存在。对于这些文件,Git 会说这些是“新文件”。

列出了“暂存待提交”的文件,或者没有找到任何要列出的文件,您的 Git 现在继续将暂存区域中的文件与工作树中的文件进行比较。和以前一样,某些文件可能匹配。其他文件可能有所不同——甚至在工作树中可能有一些文件在暂存区根本没有对应文件:与以前一样是新文件。

不过,这一次,您的 Git 只会告诉您有关 已更改 文件的信息,并表示这些文件不会为提交暂存。它确实也收集了每个 new 文件的列表,但将它们推迟到下一部分。

列出所有“未暂存以供提交”的文件后,您的 Git 会继续告诉您未跟踪的文件。这些是工作树中不在 Git 暂存区中的所有文件。换句话说,这些是“新”文件。

这些的奇怪之处在于它们是如何被分离出来的,作为一个单独的类别进入“未跟踪”。原因是 Git 作者预计大量未跟踪的文件不应在此处报告。尤其是 Git 是为与创建“目标文件”和其他“构建工件”的编译器一起工作而构建的,虽然它们可能很重要,但不应添加到提交中并因此永久保存。1

在这方面,Git 有一个排除工具,通过.gitignore 和其他排除文件。在这里,您列出了 Git 应该关闭____的文件。它应该抱怨这些未跟踪的文件未被跟踪。此外,当这些文件未被跟踪时,您可以使用整体git add 操作,例如git add .,来添加所有个未跟踪文件...除了那些标记为“忽略”的。

.gitignore 的误导性在于它不会忽略任何被跟踪的文件。这里的tracked这个词是根据untracked的定义来定义的。 untracked 文件是存在于工作树中但不在 Git 索引中的文件。 tracked 文件是位于 Git 索引中的文件,无论它是否存在于 Git 索引中。跟踪的文件永远不会被忽略。

.gitignore 文件的良好维护使 Git 使用起来更加愉快:git status 告诉你有用的东西; git add . 只添加正确的东西。


1这样做的原因是构建工件(至少在理想情况下)完全可以从原始来源重现。我们只想保存原件,而不是派生的工作产品。这至少可以节省大量的空间和时间以及以后的人工工作。请注意,这里有很多“理想”和“潜力”。这些事情并不总是按计划进行,有时保存一切实际上是合理的。不过,Git 在这方面并不是那么出色,因此您可能不想为此目的使用 Git


“所有文件始终提交”的可能来源

如果你运行git add .,你是在告诉Git:扫描我当前的工作目录,找到所有更新的文件、所有新文件和任何删除的文件,并在每个文件上使用git add来更新你的暂存区副本。这里唯一的例外是.gitignore 中列出的文件或其他尚未跟踪的排除文件。

如果您运行git add *,其行为在某种程度上取决于您的命令行解释器:Unix 风格的 CLI(例如 bash 或 zsh)具有 shell 扩展 *,而 MS- DOS 风格的 CLI(例如 CMD.EXE)将文字星号 * 传递给 Git,然后扩展 *。我不会在此处全部详细介绍差异的细节,但这往往会批量添加很多或全部文件,具体取决于许多细节。

如果你运行git add -u,你告诉Git去寻找更新的文件并添加它们。

你可以有一个预提交钩子。 Git 中的钩子相当复杂,但一些软件安装程序不仅会为您安装 Git,还会设置某种自动钩子创建。 (这是一种重新初始化 Git 存储库可以产生影响的设置,尽管为此,安装程序必须将这些钩子放入 Git“模板”中,这似乎很少使用。)预提交钩子可以,取决于你如何运行git commit,为你运行git add,即使你不想要它。

如果你运行git commit -a,你实际上是在告诉 Git 运行:

git add -u
git commit

这里有一个与 pre-commit 挂钩的交互,因此两个命令序列并不完全相同,但这可能是您问题的根源。

【讨论】:

git status 输出告诉您如何“取消添加”文件(使用 git resetgit restore,具体取决于您的 Git 版本)。 如果他们已经提交,你就会遇到一个非常不同的问题!请注意,git push 推送 commits(此时您必须已经拥有),因此存在不同的问题。 您有一些选择:构建不包含大文件的新提交(并删除包含它们的旧提交),负面影响是您无法保存这些文件, 如果你想保存它们;安装 LFS 并使用 LFS 迁移工具(GitHub 的 LFS 支持存在,但是当我们在之前的工作中对此进行调查时,它相当薄,直到您付费为止);使用 GitHub 以外的东西。 Git-LFS 是一组 Git 包装器。您不必必须成为管理员来安装它们;成为管理员只会让事情变得更容易,因为从那时起它总是存在于所有 Git 存储库中(作为非管理员,你必须做更多的工作)。我们最终没有使用 Git-LFS,因为我们没有看到价格足够的价值。 人们这样做的通常方式似乎是使用 BFG 或 git filter-branch:参见 ***.com/q/2100907/1256452 和 ***.com/q/68477232/1256452。我建议在 repo 的 副本 上执行此操作(保留旧的,直到您对新的感到满意;将它们视为完全独立的项目)。

以上是关于为啥提交一个文件,但所有文件都在 RStudio 中提交?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 RStudio/R 中显示为 1 GB 大小的对象会被 RData 或 RDS 文件格式以更大的大小保存,即使没有压缩?

RStudio安装后,打开显示如下窗口,点击file等都没反应,不知为啥?请问怎么解决啊?

在所有文件 rstudio 中查找和替换文本

为啥 django 强制所有模型类都在 models.py 中?

为啥SVN老是提交失败?提示空间不足。

每次单击按钮时都在提交表单