【问题标题】:.gitignore not ignoring at all.gitignore 根本不忽略
【发布时间】:2015-09-12 11:57:28
【问题描述】:

我创建了一个名为Exploratory Data Analysis/Course Project 1/ 的目录,其中包含household_power_consumption.txt 文件。我试图将它推送到我的 git repo 中,并收到关于 household_power_consumption.txt 大小的警告,所以我添加了一个 .gitignore 文件,其中包含以下行:

Exploratory\ Data\ Analysis/Course\ Project\ 1/household_power_consumption.txt

我尝试按照hereherehere 发布的解决方案进行操作,但这些都不适合我。我总是收到同样的错误:

 git push origin master
Counting objects: 31, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (28/28), done.
Writing objects: 100% (31/31), 20.48 MiB | 221.00 KiB/s, done.
Total 31 (delta 6), reused 0 (delta 0)
remote: error: GH001: Large files detected.
remote: error: Trace: 491a8219bf1d3de4fd08a8e3ea253faa
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File Exploratory Data Analysis/Course Project 1/household_power_consumption.txt is 126.80 MB; this exceeds GitHub's file size limit of 100.00 MB
To https://github.com/jd901215/DataScience_CourseraSpecialization.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://github.com/jd901215/DataScience_CourseraSpecialization.git'

这是我项目的本地目录树:

├── Exploratory Data Analysis
│   └── Course Project 1
│       └── household_power_consumption.txt
├── .git
│   ├── branches
│   ├── COMMIT_EDITMSG
│   ├── config
│   ├── description
│   ├── FETCH_HEAD
│   ├── HEAD
│   ├── hooks
│   │   ├── applypatch-msg.sample
│   │   ├── commit-msg.sample
│   │   ├── post-update.sample
│   │   ├── pre-applypatch.sample
│   │   ├── pre-commit.sample
│   │   ├── prepare-commit-msg.sample
│   │   ├── pre-push.sample
│   │   ├── pre-rebase.sample
│   │   └── update.sample
│   ├── index
│   ├── info
│   │   └── exclude
│   ├── logs
│   │   ├── HEAD
│   │   └── refs
│   │       ├── heads
│   │       │   └── master
│   │       └── remotes
│   │           └── origin
│   │               └── master
│   ├── objects
|   |   ├── (Bunch of SHA-1 checksums I guess )
│   │   ├── info
│   │   └── pack
│   ├── ORIG_HEAD
│   └── refs
│       ├── heads
│       │   └── master
│       ├── remotes
│       │   └── origin
│       │       └── master
│       └── tags
├── .gitignore
├── LICENSE
├── README.md
└── R programming 
    ├── README.md
    ├── Week 1 Programming assignment
    │   ├── complete7.R
    │   ├── complete.R
    │   ├── corr.R
    │   ├── pollutantmean.R
    │   ├── .RData
    │   ├── .Rhistory
    │   └── specdata
    ├── Week 2 Programming assignment
    │   ├── cachematrix.R
    │   └── README.md
    └── Week 4 Programming assignment
        ├── best.R
        ├── hospital-data.csv
        ├── Hospital_Revised_Flatfiles.pdf
        ├── outcome-of-care-measures.csv
        ├── .Rhistory
        └── rprog-doc-ProgAssignment3.pdf

抱歉,这篇文章很长,但我正在尝试提供必要的信息。提前致谢

【问题讨论】:

  • 如果您删除 txt 文件并简单地提交新文件夹会发生什么?如果可行,您能否在该新文件夹中创建一个小文件并成功提交?
  • 嗨@ShawnMehan!如果我在本地删除 .txt 我会得到同样的错误。
  • 抱歉,您仍然收到有关已删除的 txt 文件大小的警告?
  • 是的,先生!即使我使用命令 git rm -r --cached .
  • 所以你应该恢复你的本地以匹配我认为的远程。在这一点上,你对那个更有信心,所以放下这些改变,让自己回到一个好的地方。

标签: git gitignore


【解决方案1】:

首先,值得注意的是,.gitignore 条目并不代表人们最初通常认为的意思。我会(很多)稍后再讨论这个问题。

很明显1这个输出行:

remote: error: Trace: 491a8219bf1d3de4fd08a8e3ea253faa

告诉您,在您尝试推送的一组提交中,哪个提交包含过大的文件。

不过,要到达这里,您必须了解很多关于 git 的知识,而这些知识通常在各种文档中都没有得到很好的解释。 (关于的解释,请参阅Git Book。)在这种特殊情况下,要知道的一件事是git push 调用了一个“远程”,即另一台拥有自己独立 git 存储库的计算机然后你的 git 要求其他 git 接受你的任何新提交并将它们添加到它自己的存储库中。


在这种情况下,你和你的 git 调用远程“origin”,这是“我最初克隆的地方”的标准名称。

为了说明,下面是一个简单的情况,即在分支 master 上克隆一个只有三个提交的源:

他们的 git:C1 <- C2 <- C3 <-- master

你:$ git clone <url>

你的 git:(使用互联网电话呼叫他们的 git)“这是一个 URL, 你有什么?”

他们的 git:“我有 master 指向提交 C3

你的 git:“好的,给我,哦,我知道我还需要 C2C1

他们的 git:(给你的 git 提供所有东西)

你的 git:“kthxbye!” (解压一切,创建新的仓库 这和你从他们的 git 得到的一样,加上 远程名称“来源”和网址)

现在您有了克隆,您可以做一些工作并进行一些提交。我们称他们为C4C5。这些C<digit>s 中的每一个都代表那些丑陋的 40 字符 SHA-1 之一,例如 491a8219bf1d3de4fd08a8e3ea253faa。每个提交“指向”其父提交,因此C3 指向C2C2 指向C1。 (因为C1 是第一个提交,它没有出站箭头:一个提交指向零个或多个父级,并且初始提交是具有零的那个。)现在让我们画出C4C5

C1 <- C2 <- C3 <- C4 <- C5   <-- master

注意分支标签master 现在指向提交C5,不再指向C3

(您的 git 将创建一个附加标签 origin/master,指向 C3。这就是您的 git 可以告诉您“提前 2”提交的方式。因为您的 git 并不总是在互联网电话上但是,与他们的 git 保持同步,这些信息可能会变得陈旧。但我们现在将忽略它。)

最终,您决定:

$ git push origin master

这告诉你的 git 回到他们的 git 上。现在的对话有点不同:

你的 git:“我有一些东西给你。”

他们的 git:“嗯,好吧,把东西给我,我看看。我有 master 是提交 C3。”

你的 git:“好的,既然你在 C3,这是我的 C4C5。”

他们的 git:(开始检查,在这种情况下,运行“预接收挂钩”)

“预接收挂钩”是他们(无论他们是谁)编写的任意代码。它可以做任何他们想做的事情,但在这种情况下,它显然(又是那个词:-))检查你正在移交的新提交。这两个提交中的至少一个显然在其关联的源代码树中有一个大文件。

这个任意代码可以只是说“不”,但它打印的是关于为什么它说“不”的细节。明智的做法是打印具有大文件的提交的身份,因为提交 ID 是唯一的,即使在互联网电话中也是如此,因此您的存储库中将拥有相同的 ID,并且可以使用看看哪里出了问题。

在此示例中,提交 C4 或提交 C5。 (大文件可能在两个提交中;远程可能会在找到第一个找到的那个后停止,而不是告诉你第二个。但无论如何它只是告诉你一个提交。)

查看那个特定的提交:

$ git log 491a8219bf1d3de4fd08a8e3ea253faa

或:

$ git show 491a8219bf1d3de4fd08a8e3ea253faa

使用其他可能有助于使其更易于查看的方法:

$ git log --name-status

向您显示添加、删除或更改的文件(通过将每个提交与其父提交进行比较)。


现在,真正的问题是如何处理这个问题。在这种特殊情况下,使用交互式变基可能是最简单的,如Rewriting History section of the Git Book 所示。您需要在这里做的是用“好”提交替换原来的“坏”提交。

(Git 实际上并没有replace 提交,它只会添加 new 提交,但是一旦你有了新的,你和你的 git 就可以假装旧的不存在。最终——默认情况下,在 30 天左右——旧的被遗忘的提交“过期”并将被删除,但它们会一直保留到那时。这种保留意味着你总是可以从期间犯的任何错误中恢复交互式变基。)

为了说明,假设错误发生在提交 C4 中(如果它发生在 C5 中,则更容易修复,并且不需要整个交互变基,尽管它仍然可以工作) .我们还要说——这似乎是合理的,因为你的git push 失败了——你还没有在其他任何地方推送C4C5。 (如果你有,那么无论谁得到了你当前的 C4C5 提交,生活都会变得更加痛苦。)

您首先运行git rebase -i。由于您在master 上,并且它的“上游”分支(正如 git 所说的那样)是origin/master,这意味着“将master 重新设置为origin/master”:也就是说,将提交C4C5 复制到origin/master 的提示用于进行新的、复制但略有更改的提交 C4'C5'

                 C4 <- C5  <-- [master, before rebase]
               /
C1 <- C2 <- C3             <-- origin/master
               \
                 C4' ...   <-- temporary rebase branch

当你的编辑器中出现变基命令时,将提交C4pick 行更改为edit 行。写出指令并退出编辑器。 (你不需要为 C5 做任何事情,因为一旦 rebase 完成,它将是最尖端的提交。如果你需要更改它,你可以简单地 git commit --amend 它。)

交互式 rebase 将挑选原始提交,但在此时停止,此时提交 C4' 实际上与 C4 相同(有时除了一些时间戳和其他作者/提交者元数据) .您现在可以“修改”提交。

由于提交添加了一个你不想要的文件,你需要先git rm 它,也许用git rm --cached 将文件留在你的工作树中:

$ git rm --cached Exploratory\ Data\ Analysis/Course\ Project\ 1/household_power_consumption.txt

如果有必要或适当,您还可以将该路径添加到.gitignore 文件,并将git add 添加到.gitignore。这个文件只是给你带来了一点便利,所以你要不要这样做。

现在您已准备好使用 git commit --amend 将修改后的提交 C4' 永久化,然后再继续 rebase:

$ git commit --amend --no-edit
[master d106870] blah blah ...
$ git rebase --continue

--no-edit 标志跳过在提交消息上打开编辑器。如果您也想对提交消息进行更改,请忽略它。)

continue 步骤只是通过复制提交 C5 来完成变基,并将其添加到临时分支的尖端:

                 C4 <- C5  <-- [master, before rebase]
               /
C1 <- C2 <- C3             <-- origin/master
               \
                 C4' - C5' <-- temporary rebase branch

然后——就像所有rebases 所做的那样——删除标签master 并将其粘贴到临时分支上:

C1 <- C2 <- C3             <-- origin/master
               \
                 C4' - C5' <-- master

现在您有一组添加大文件的提交,您可以重新运行git push origin master。您的 git 和他们的 git 将重新进行对话,但是这一次,您的 git 将移交提交 C4'C5',这会忽略大文件。然后你的 git 会要求他们的 git 将C5' 标记为分支master,大概这一次就可以了。


回到.gitignore 文件:我有时认为这个文件命名错误,因为这些不是 git 忽略的文件。特别是,如果一个文件已经被跟踪——在索引中——git 不会忽略它。因此,如果您 git add 错误地编辑了一个文件,提交了该文件,然后将其放入 .gitignore,它仍然在较早的提交中。即使你从那时起git rm-ed 它也是如此。

(.gitignore 中的条目做两件事,通常更重要的一件事是“让 git 不要抱怨这个文件未被跟踪”,因此,一个更好的名称可能是 .gitignore,而不是 .gitignore,或者一些这样的。但是这个文件中的条目阻止git add将该文件添加到索引中,如果它还没有索引中,所以它也需要名称.git-dont-add-files 或类似的东西。所以,我们只使用.gitignore 并且必须理解它并不真正意味着“忽略”。)


1“明显”的意思是“一点也不明显,除非你写了一些预接收钩子。”

【讨论】:

  • 哇,这是一个非常详尽的答案。谢谢,我会全部阅读并询问是否需要
  • 我刚读完,哈哈,再次感谢。我忘了接受它
【解决方案2】:

当我添加该行时为我工作

Exploratory\ Data\ Analysis/Course\ Project\ 1/household_power_consumption.txt

到.gitignore

我怀疑您由于之前的提交而无法推送。尽管您是在本地删除它,但我认为之前使用该文件创建了一个提交。 检查'git log'并查看您在txt文件中签入的提交是否存在。

如果是,执行

git reset --soft HEAD^

删除该提交(如果它是最新的提交)。

重置提交后, 在 'git status' 中,如果您在以下位置看到文件:

    "Changes to be committed:" area, execute "git reset HEAD <file>".
    "Changes not staged for commit:" area, execute "git checkout -- <file>".

执行 'git status' 并检查文件是否在“未跟踪文件:”区域中。

然后,将文件添加到 .gitignore。它会起作用的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 2022-11-16
    • 2019-04-29
    • 2018-05-02
    相关资源
    最近更新 更多