Git - 在线存储库中有未跟踪的文件[重复]

2023-12-14

我正在使用 git (bitbucket) 来控制我的 Linux 配置文件。所有文件都在目录中~/.cfg/。然后我另外还有一些本地配置文件~/.cfg/local/这些应该因机器而异。

我想在我的在线存储库中保留本地文件的副本作为一种示例本地配置,但希望不跟踪这些文件。我真的不在乎他们是否被克隆git clone不过,无论哪种方式都可以。

我尝试以下这个答案但这会从在线存储库中删除文件。

我也尝试了中概述的解决方案这篇博文,效果更好,但不幸的是有 2 个缺点:1)它必须在每台机器上重复,2)它实际上并没有取消关注文件。因此,如果我不小心从某台机器上传了本地配置(忘记运行帖子中的命令),那么下一个git pull在任何其他机器上都会覆盖该机器的本地配置。


总而言之,我想要一个具有以下功能的解决方案:

  1. 它保留整个的初始上传~/.cfg/(包括~/.cfg/local/)在在线存储库中。
  2. 它推送的内容~/.cfg/但不是的内容~/.cfg/local/每当我执行标准时git add -A; git commit -m "asdf"; git push
  3. 它拉取内容~/.cfg/但不是的内容~/.cfg/local/ when I git pull.

我想要一个可以做 [Git 做不到的事情] 的解决方案

抱歉,但答案是:不,Git 不能这样做。你可以得到close,但这并不有趣:它需要每个跑步者的努力git clone,从此以后反复遭遇可能导致烧伤的情况。这就是为什么标准方法是推荐的方法这个答案 to 我可以“git commit”一个文件并忽略其内容更改吗?

它可能有助于理解whyGit 无法做到这一点。让我们更具体地看看“那”是什么:

  • 保留整个初始上传~/.cfg/(包括~/.cfg/local/)在在线存储库中。

是你can做。但这种措辞很奇怪,因为 Git 不存储files。 Git 商店commits, which contain文件。这可能看起来只是语义,但话又说回来,这只是关于“热水”是否适合淋浴(40°C / 104°F:热,但不烫伤)的“纯粹语义”,或者会给你第二个——度灼伤(95°C / 203°F:接近沸腾,标准压力)。

So, you can有一个包含以下文件的提交cfg/foo and cfg/local/bar。到目前为止,没有真正的问题 - 主要问题是你不能有一个包含空目录的提交cfg/local/,因为 Git 在每次提交中只存储文件本身,而不存储包含的目录:它假设任何人using存储库稍后将根据需要自动创建目录,只要有一个文件要存储,其名称会强制将来/其他 Git 调用os.mkdir或创建包含该文件的目录的任何内容。

  • 推送内容~/.cfg/但不是的内容~/.cfg/local/每当我执行标准时git add -A; git commit -m "asdf"; git push

这是第一个问题,那些“纯粹”的语义至少有点烫手:Git 不推送files。 Git 推送commits.

这里有三个命令。第一个,git add -A,告诉 Git:通过将其替换为我的工作树中的新版本,更新索引中记录的所有文件的索引副本。第二个,git commit,告诉 Git:使用存储在索引中的文件进行新的提交。第三,git push,告诉 Git:将一些提交发送到其他某个 Git,然后要求其他 Git 设置其一个或多个引用,例如其refs/heads/master—its master分支——到某个哈希 ID。

这就引入了这个新术语,索引,这就是麻烦开始的地方。

If your cfg/local/bar文件在您的索引中,它将在您的提交中。如果是not在你的索引中,它会not在你的承诺中。这很简单,但其含义却很糟糕:

  • You can remove索引中的文件而不触及工作树版本(git rm --cached cfg/local/bar),但这会导致未来的问题。

  • 或者,您可以设置--assume-unchanged or --skip-worktree文件副本上的位in你的索引。这几乎已经足够好了,但还不够。 (顺便说一句,两者或多或少是等价的,但“跳过工作树”就是专门用于这种用途的,只不过它的真正意图是用于稀疏结帐。我将在下面写“跳过工作树”,但是这实际上意味着其中之一。)

设置该位需要您在之后手动运行命令git clone。该索引是私有的your存储库的副本,因此每个运行的人git clone必须运行这个git update-index命令,至少一个,紧随其后git clone。 (Git 不会让您通过 Git 本身自动执行此操作,尽管您当然可以编写一个脚本来执行此操作并分发该脚本。)

正如您可能已经看到的,这只是almost works.

  • 拉取内容~/.cfg/但不是的内容~/.cfg/local/ when I git pull

再一次,Git 会在这里烧死你。问题是git pull它本身并不是一个真正的东西:它意味着run git fetch,然后运行第二个 Git 命令secondGit 命令会带来麻烦。

第二个 Git 命令通常是git merge,我们现在假设是这样。另一种选择,git rebase, is worse对你来说,因为 rebase 本质上是重复的git cherry-pick每个挑选操作本身就是一个合并,导致multiple merges.

合并,就像提交一样,发生在索引中或通过索引发生。 Git 加载all文件来自three提交到索引中,在两个单独的步骤中将文件配对(基础与“我们的”,基础与他们的),然后组合配对。因此,这会合并索引中的每个文件,或者,如果文件was在早期提交的索引中isn't现在在索引中,删除或重命名 files.

这意味着如果一个文件cfg/local/bar存在于合并基础提交和“他们的”提交中——如果你想要一个初始的,它就需要在那里git clone填充cfg/local with cfg/local/bar——那么它也需要存在于“我们的”提交中,否则 Git 会坚持removing它可以保留我们的零钱。反过来,这意味着如果他们改变了their复制进去their提交时,Git 也会希望将其更改应用到您提交中的副本。

如果你用过git update-index大惊小怪--skip-worktree标志,您已经重新提交了原始版本cfg/local/bar一直。该标志只是告诉 Git:嘿,不要看我自己的这个文件版本,就假设索引中的副本仍然正确。这会影响git add -A步骤:代替更新索引中列出的所有文件,它实际上是:更新所有未特别标记的文件。你可以改变cfg/local/bar你喜欢的一切,以及git add -A will 省略更新:它不会复制您的工作树cfg/local/bar返回到索引中,而不是将其放入索引中的副本保留在您第一次使用时git clone run git checkout为你。

所以所有的your提交有一个cfg/local/bar,但是contents这些提交存储in that cfg/local/bar,在每次提交中,都是你运行时得到的相同内容git clone,即使您更改了工作树副本。你的skip-worktree位告诉你的Git只留下索引副本cfg/local/bar独自一人,它已经做到了。

但现在既然是合并时间, and they已改变their cfg/local/bar无论出于什么原因——原因并不重要,重要的是他们did更改-now你的 Git 面临着将你的更改(无)与他们的更改(一些)结合起来的工作。它通过采取唯一的改变(当然是他们的改变)来做到这一点now你的 Git 会坚持copying更新后的cfg/local/bar进入你的工作树。这会覆盖你的cfg/local/bar,这就是痛点:这就是这种方法让你感到痛苦的地方。

If they never(从来没有,一次也没有)改变他们的cfg/local/bar,这种做法——设置skip-worktree——will实际上工作。但这取决于陌生人的善意,或者至少取决于本地配置的想法cfg/local/bar in 每一次提交完全相同……在这种情况下,犯下这件事还有什么意义呢?

但是,如果他们真的改变了它,当你将他们的改变与你缺乏改变的东西合并时,你就会被烧伤(轻微的或其他的),因为 Git 会想要覆盖你的cfg/local/bar与他们更新的一个。

另一种选择是,您remove your cfg/local/bar从你早期的索引来看,情况更糟:现在每次提交you push 根本没有该文件。 Git 将此视为命令:从包含该文件的提交转到不包含该文件的提交时,请删除该文件。所以如果你采取这种方法,you're更改文件的人!你告诉其他所有人:删除这个文件!

The only确实,100% 有保证,正确的处理方法是:首先不要提交文件。 If every在存储库中提交doesn't have cfg/local/bar,该文件将never被纳入索引。如果该名称列在.gitignore同样,不会自动“添加所有文件”add它到索引,所以它不会在future承诺。这意味着当您开始或结束时它都不会在那里。 Git 永远不会想要合并它,也不会覆盖它的副本。它始终是一个未跟踪和忽略的文件,存在于您的工作树中,但不存在于您的任何提交中。

当然,这意味着最初会有一点痛苦:每次跑步时git clone <url>你还必须这样做:cp -r .cfg/local-committed/ .cfg/local。但如果你要使用--skip-worktree,那么每次你跑步的时候git clone <url>你必须立即遵循git update-index --skip-worktree .cfg/local/bar。所以就是完全相同的疼痛程度作为糟糕的选择,没有任何坏处。

此外,如果您可以控制该软件,则可以设置该软件,以便在.cfg/local/当你第一次时不存在run程序,程序creates .cfg/local/通过复制.cfg/local-committed/。那么“第一次设置”的痛苦也消失了!这就是为什么将默认配置提交到一个单独的文件中,用户可以手动或自动copies到本地配置文件,它永远是一个未跟踪的文件,是正确的解决方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Git - 在线存储库中有未跟踪的文件[重复] 的相关文章

  • git subtree pull -P 不管 总是合并冲突

    问题 即使我没有进行任何更改 每次尝试拉入子树时 我都会遇到合并冲突 我在做什么 In 子树仓库 Make some changes git commit am Changes made git push origin master In
  • Git 无效的修订范围 Symfony2 Composer 外部包

    RuntimeException Failed to execute git log 18efcf67d236d5bbf46ac67820250dffd0474b6e 94e2146f525fa1367e15646fa273e5b34f92
  • git 预提交钩子格式代码 - Intellij/Android Studio

    本要点展示了如何在预提交时使用 Eclipse 格式化程序自动格式化 Java 代码 Source https gist github com ktoso 708972 https gist github com ktoso 708972
  • 相当于“svn update -r”的 git 是什么?

    我是最近的 git 转换者 能够使用 git svn 将我的分支保留在本地而不干扰 svn 服务器真是太棒了 最新版本的代码中存在一个错误 我想确定一个它起作用的时间 以便我可以使用 git bisect 我找不到正确的命令来及时返回 谢谢
  • Git:如何变基到特定提交?

    我想变基到特定的提交 而不是另一个分支的 HEAD A B C master D topic to A B C master D topic 代替 A B C master D topic 我怎样才能做到这一点 您可以通过在您喜欢的提交上创
  • git diff 在尖括号中显示 unicode 符号

    我有一个带有 unicode 符号 俄语文本 的文件 当我修复一些拼写错误时 我使用git diff color words 看看我所做的改变 如果是 unicode 西里尔文 符号 尖括号会造成一些混乱 如下所示 cat p1 cat p
  • 如何解决 VSTS 中拉取请求中的合并冲突?

    我已经创建了拉取请求 我进入了这个 批准 按钮不执行任何操作 并且 完成 被禁用 如何解决拉取请求中的冲突 Update 微软刚刚添加了基于浏览器的合并 这可能会让你摆脱小冲突的困境 并提供自 Sprint 150 起改进了不同场景的可视化
  • git push heroku master 权限被拒绝

    我正在关注 ruby railstutorial 我运行命令 git push heroku master 它吐出了这个错误 Permission denied publickey fatal Could not read from rem
  • git pull,忽略深度,如何不拉取整个历史记录?

    我们有一个巨大的多 GB git 存储库 主要是二进制对象 克隆需要几天时间 实际的主分支 没有历史记录 只有大约 20MB 所以我想 深度为 1 的 git 克隆就是解决办法 然而 现在我需要将某人的更新拉到主服务器 我们没有分支 当我拉
  • Git:显示分支之间的差异,忽略合并的提交

    我的存储库历史记录看起来像这样 x y z branch a b c d e master 我想获得 branch 完整历史记录的单个差异 即 像 git diff 输出 我不想要像 git log p 产生的一大堆差异 而不包括任何从 m
  • 如何将更改移出主分支

    基本问题 但这一直发生在我身上 进行更改working branch 切换到master git merge working branch git push cap deploy 到舞台 泡一杯新茶 然后我回来思考其他事情并开始做出一些改变
  • 为什么我无法创建/签出该分支?

    我正在尝试创建本地 Git 分支 但它不起作用 以下是我正在使用的命令 tablet edit11 git checkout b edit 11 Switched to a new branch edit 11 tablet edit11
  • 如何正确使用“mvn release:prepare”?

    我尝试了这个命令 用dryrun在我的 Maven 项目上进行测试 mvn release clean release prepare DdryRun true DgenerateBackupPoms false Dtag solocal
  • 致命:.git/info/refs 无效:这是一个 git 存储库吗?

    我有一个托管在 Assembla 上的 Git 存储库 我正在尝试执行以下操作 git push u origin master 我一遍又一遍地收到以下错误 fatal https url repo name git info refs n
  • Ansible bitbucket 克隆存储库配置 ssh 错误

    我之前发布过这个问题 但那里的答案不再有效 总之 当使用 Ansible 配置我的 vagrant box 时 在尝试使用 ssh 克隆我的 bitbucket 私有存储库时 我遇到了一个神秘的错误 该错误指出 权限被拒绝 公钥 然而 如果
  • Netbeans 和 Git,.obj 文件被忽略

    我正在开发一个涉及 obj 文件的小型 git 项目 当我查看 项目选项卡 时 我发现它们被忽略了 但如果我查看我的 gitignore 我无法理解为什么 DepthPeeling nbproject private DepthPeelin
  • git 日志历史记录图,每次提交一行,彩色,带有日期

    我需要的格式如下 git log decorate graph oneline date order 但我也需要它 包含日期 短 具有相同的颜色 I tried git log decorate graph oneline date ord
  • 自定义 SSH 端口上的 Git

    我的 VPS 提供商建议我将 SSH 端口保留为他们默认分配的自定义端口号 不是 22 问题是 虽然我知道我可以在创建远程配置时提供端口号 但在进行 Git 克隆时似乎无法提供相同的操作 我在用gitolite https wiki arc
  • Android 存储库初始化失败

    我想我非常仔细地遵循该网站的说明 http source android com source downloading html http source android com source downloading html 但是当我尝试这
  • Git - 如何将整个目录恢复到特定提交(删除任何添加的文件)

    我想恢复 git 中的目录 恢复其中的所有文件 并删除自该提交以来添加的所有文件 进行结账似乎只能满足我的第一个要求 但不会删除任何文件 我想出了最简单的解决方案 git rm path to dir git checkout

随机推荐