忽略git中文件的特定更改,但不忽略整个文件

Kev*_*ica 40 git ignore gitignore

我在git存储库中有一个文件,它有一个本地更改.我想让git永远忽略本地更改,但不是文件.特别是,

  • 如果除了此更改之外未触及该文件,git add .则永远不应该暂存它.
  • 同样,git commit -a不应该提交它.
  • 如果我对文件进行了额外的更改,我应该能够进行更改 - 但是我忽略的更改应该暂存和提交.

有没有办法做到这一点?做一些研究,我读到了"涂抹/清洁周期",如果我读得正确,

  1. 该文件将被标记为未更改,
  2. 结帐时,我所做的更改会被覆盖,
  3. 然后脚本会自动重新应用更改,然后再次将文件标记为未更改.

我对git和脚本很新,(我是C#和Java经验的实习生),所以如果这就是我需要做的,请你发布详细的指示或链接到如何设置涂抹的教程/清洁周期?

背景:我希望我的工作分支与主干不同步.有一个低优先级的错误只影响开发机器,所以我们只是评论出有问题的代码,而不是修复它.显然,我们不希望从生产中删除此代码,它可以正常工作.

Mar*_*ato 40

你可以使用这个skip-worktree位.打开它:

git update-index --skip-worktree <file>
Run Code Online (Sandbox Code Playgroud)

在那之后,git将永远不会为本地更改进行调整,<file>并且如果git本身必须写入<file>(例如,在合并或结账中)将会失败(大声).

如果您想要进行未来的更改,可以将其关闭,暂存新更改,然后重新打开:

git update-index --no-skip-worktree <file>
git add -p <file>
git update-index --skip-worktree <file>
Run Code Online (Sandbox Code Playgroud)

虽然不完美,但这可能还不错.<file>由于git不再告诉你这一点,你应该注意到它有未分级的变化

注意:我最初的建议是使用assume-unchanged.正如Git中所解释的那样- '假设未改变'和'跳过工作树'之间的差异,这真的skip-worktree是你想要的.特别assume-unchanged是,Git承诺你不会更改文件,如果你违反了这个承诺,Git可以删除你的更改或提交它们!相反,Git不会删除或提交您的skip-worktree更改.

  • -1 不正确。这将使 git 忽略对文件的*所有*更改。OP 要求 *“如果我对文件进行其他更改,我应该能够暂存并提交该更改 - 但我忽略的更改不应该暂存并提交。”*。 (4认同)
  • 在这种情况下,`--assume-unchanged`是否比`--skip-worktree`有任何优势? (2认同)
  • @MarkLodato评论*"并且如果必须写入<file>(例如,在合并或结账时)将会失败(大声)."*和*"这不是完美的,因为你不会得到任何通知对<file>"*的更改似乎彼此不一致.如果我理解正确,如果遥控器对此文件进行了更改,并且我进行了结帐或拉取,则git将失败并指出基本上锁定的文件.然后我可以使用`--no-skip-worktree`然后再次尝试拉动并重新设置`--skip-worktree`之后,这是正确的吗? (2认同)
  • @DelightedD0D,两种说法都是正确的。前者是关于 git 本身写入文件,而第二个是如果“你”写入文件并有未暂存的更改。我改写了我的答案,希望能够澄清。对于你的最后一个问题,是的,你的理解是正确的。希望这可以帮助! (2认同)

小智 18

这些答案很好,但可能无法最好地解决 @Kevin 的问题。我也有类似的担忧,经常编辑配置文件,这样我正在开发的应用程序将访问我自己的私有开发数据库而不是生产数据库。我不小心签入并推送这些配置更改只是时间问题!我只需要一种轻量级的方式来忽略文件。这是我学到的:

  • 首先,对文件进行所需的更改。我会打电话给它my_config

  • 制作该更改的补丁文件 git diff >../somewhere-else/my_config.patch

  • 现在告诉 git 忽略该文件(无需更改签入的 .gitignore): git update-index --assume-unchanged my_config

现在,只要你不更改my_config,你需要检查中,你可以自由地工作。停止无视my_config,做git update-index --no-assume-unchanged my_config。在将其他人的更改拉入 之后my_config,您可以轻松地使用 恢复您的私人更改git apply ../somewhere-else/my_config.patch,然后...再次假设未更改,如上所述,然后重新开始工作!

以下是一些有用的别名,您可以将其放入~/.gitconfig

[alias]
    unchanged = update-index --assume-unchanged
    changed = update-index --no-assume-unchanged
    show-unchanged = !"git ls-files -v | sed -e 's/^[a-z] //p; d'"
Run Code Online (Sandbox Code Playgroud)

  • 不仅感谢您的回答,还感谢之后的工作流程!我想很多人都回避了,因为不知道之后该怎么办。您的解释和补丁文件被低估了。 (2认同)

Rik*_*ing 6

Git的“补丁模式”非常适合仅将文件中的某些更改添加到提交中。

要启动它,请键入git add -pgit commit -p(完成后直接提交消息)或git add --interactive(更多提示)。

从本质上讲,它带您阅读了所示的每个代码段,git diff并询问您是否要暂存它。

进行更改后,请回答n o或e,以在$ EDITOR中打开补丁。


小智 0

在我看来,您所描述的情况是这样的:您想要维护一个与本地存储库不同的工作目录。

这是不可取的;因为这些更改并未提交,所以如果文件被意外删除或以您不希望的方式更改,您将几乎没有追索权。

因此,建议您实际上提交所有更改。如果您想分离这些更改,您可以使用分支轻松地做到这一点。例子

git checkout -b new-branch
# now you can change the file without affecting master
echo bar >> foo
git add
git commit
# and back to master
git checkout master
Run Code Online (Sandbox Code Playgroud)