我可以“git commit”吗?一个文件并忽略其内容更改?

发布于 2024-09-11 20:06:44 字数 336 浏览 5 评论 0原文

我团队中的每个开发人员都有自己的本地配置。该配置信息存储在名为 devtargets.rb 的文件中,该文件在我们的 rake 构建任务中使用。不过,我不希望开发人员破坏彼此的 devtargets 文件。

我的第一个想法是将该文件放入 .gitignore 列表中,这样它就不会提交到 git。

然后我开始想:是否可以提交文件,但忽略对文件的更改?因此,我会提交文件的默认版本,然后当开发人员在本地计算机上更改它时,git 将忽略这些更改,并且当您执行 git status 或 git commit 时,它不会显示在已更改文件列表中。

这可能吗?这肯定是一个很好的功能......

Every developer on my team has their own local configuration. That configuration information is stored in a file called devtargets.rb which is used in our rake build tasks. I don't want developers to clobber each other's devtargets file, though.

My first thought was to put that file in the .gitignore list so that it is not committed to git.

Then I started wondering: is it possible to commit the file, but ignore changes to the file? So, I would commit a default version of the file and then when a developer changes it on their local machine, git would ignore the changes and it wouldn't show up in the list of changed files when you do a git status or git commit.

Is that possible? It would certainly be a nice feature...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不羁少年 2024-09-18 20:06:44

当然,我有时会使用

git update-index --assume-unchanged [<file> ...]

“撤消并再次开始跟踪”来执行此操作(如果您忘记了哪些文件未跟踪,请参阅此问题):

git update-index --no-assume-unchanged [<file> ...]

相关文档

--[no-]假设不变
当指定此标志时,为路径记录的对象名称不会更新。相反,此选项设置/取消设置路径的“假设不变”位。当“假设不变”位打开时,用户承诺不更改文件,并允许 Git 假设工作树文件与索引中记录的内容匹配。如果你想改变工作树文件,你需要取消设置该位来告诉 Git。当在 lstat(2) 系统调用(例如 cifs)非常慢的文件系统上处理大型项目时,这有时会很有帮助。

如果需要修改索引中的此文件,例如合并提交时,Git 将(优雅地)失败;因此,如果假定的未跟踪文件在上游发生更改,您将需要手动处理这种情况。

在这种情况下,优雅地失败意味着,当您进行拉取时,如果该文件的上游有任何更改(合法更改等),它会说:

$ git pull
…
From https://github.com/x/y
   72a914a..106a261  master     -> origin/master
Updating 72a914a..106a261
error: Your local changes to the following files would be overwritten by merge:
                filename.ext
 

并将拒绝合并。

此时,您可以通过恢复本地更改来克服这个问题,这是一种方法:

 $ git checkout filename.ext

然后再次拉取并重新修改本地文件,或者可以设置 –no-assume-unchanged ,您可以这样做此时进行正常的存储和合并等。

Sure, I do exactly this from time to time using

git update-index --assume-unchanged [<file> ...]

To undo and start tracking again (if you forgot what files were untracked, see this question):

git update-index --no-assume-unchanged [<file> ...]

Relevant documentation:

--[no-]assume-unchanged
When this flag is specified, the object names recorded for the paths are not updated. Instead, this option sets/unsets the "assume unchanged" bit for the paths. When the "assume unchanged" bit is on, the user promises not to change the file and allows Git to assume that the working tree file matches what is recorded in the index. If you want to change the working tree file, you need to unset the bit to tell Git. This is sometimes helpful when working with a big project on a filesystem that has very slow lstat(2) system call (e.g. cifs).

Git will fail (gracefully) in case it needs to modify this file in the index e.g. when merging in a commit; thus, in case the assumed-untracked file is changed upstream, you will need to handle the situation manually.

Fail gracefully in this case means, if there are any changes upstream to that file (legitimate changes, etc.) when you do a pull, it will say:

$ git pull
…
From https://github.com/x/y
   72a914a..106a261  master     -> origin/master
Updating 72a914a..106a261
error: Your local changes to the following files would be overwritten by merge:
                filename.ext
 

and will refuse to merge.

At that point, you can overcome this by either reverting your local changes, here’s one way:

 $ git checkout filename.ext

then pull again and re-modify your local file, or could set –no-assume-unchanged and you can do normal stash and merge, etc. at that point.

微暖i 2024-09-18 20:06:44

如果您可以控制存储库,则更喜欢此答案中的方法。如果没有,请继续阅读。

首选方法是使用 git update-index --skip-worktree,如

assume-unchanged 专为检查成本高昂的情况而设计
一组文件是否被修改;当你设置位时,git
(当然)假设文件对应于该部分
工作副本中的索引尚未修改。这样就避免了混乱
统计调用。每当文件进入索引时,该位就会丢失
更改(因此,当上游文件更改时)。

skip-worktree 不仅如此:即使 git 知道该文件
已被修改(或需要通过重置 --hard 或
像),它会假装它没有,使用来自
索引代替。这将持续到索引被丢弃为止。

要撤消此操作,请使用 git update-index --no-skip-worktree

从 git 版本 2.25.1 开始,这也不再是推荐的方式,引用:

用户经常尝试使用假设未更改和跳过工作树位来告诉 Git 忽略对所跟踪文件的更改。这不会按预期工作,因为 Git 在执行某些操作时仍可能根据索引检查工作树文件。一般来说,Git 不提供忽略跟踪文件更改的方法,因此建议使用替代解决方案。

例如,如果您要更改的文件是某种配置文件,则存储库可以包含一个示例配置文件,然后可以将其复制到忽略的名称中并进行修改。存储库甚至可以包含一个脚本,将示例文件视为模板,自动修改和复制它。

If you are in control of the repository, prefer the method from this answer. If not, read on.

The preferred way to do this is to use git update-index --skip-worktree <file>, as explained in this answer:

assume-unchanged is designed for cases where it is expensive to check
whether a group of files have been modified; when you set the bit, git
(of course) assumes the files corresponding to that portion of the
index have not been modified in the working copy. So it avoids a mess
of stat calls. This bit is lost whenever the file's entry in the index
changes (so, when the file is changed upstream).

skip-worktree is more than that: even where git knows that the file
has been modified (or needs to be modified by a reset --hard or the
like), it will pretend it has not been, using the version from the
index instead. This persists until the index is discarded.

To undo this, use git update-index --no-skip-worktree <file>

Since git version 2.25.1, this is no longer the recommended way either, quoting:

Users often try to use the assume-unchanged and skip-worktree bits to tell Git to ignore changes to files that are tracked. This does not work as expected, since Git may still check working tree files against the index when performing certain operations. In general, Git does not provide a way to ignore changes to tracked files, so alternate solutions are recommended.

For example, if the file you want to change is some sort of config file, the repository can include a sample config file that can then be copied into the ignored name and modified. The repository can even include a script to treat the sample file as a template, modifying and copying it automatically.

淡写薰衣草的香 2024-09-18 20:06:44

常见的做法似乎是创建一个 devtargets.default.rb 并提交它,然后指示每个用户将该文件复制到 devtargets.rb (位于 . gitignore 列表)。例如,CakePHP 对其数据库配置文件执行相同的操作,该文件自然会随着计算机的不同而变化。

Common practice seems to be to create a devtargets.default.rb and commit it, and then instruct each user to copy that file to devtargets.rb (which is on the .gitignore list). For example, CakePHP does the same for its database configuration file which naturally changes from machine to machine.

宛菡 2024-09-18 20:06:44

使用 Git 无法忽略对跟踪文件的更改。 Git 常见问题解答对此进行了解释

Git 没有提供执行此操作的方法。原因是,如果 Git 需要覆盖此文件(例如在签出期间),它不知道对文件的更改是否宝贵并应保留,或者它们是否不相关且可以安全地销毁。因此,它必须走安全路线并始终保护它们。

尝试使用 git update-index 的某些功能(即假设不变和跳过工作树位)很诱人,但这些功能不能正常用于此目的,因此不应以这种方式使用。

如果您的目标是使用配置文件,那么最好的办法是添加示例或模板文件,然后让用户将其复制到位或让脚本创建适当的文件。然后,您应该忽略实际配置文件的位置,只签入示例或模板。

It is not possible to ignore changes to a tracked file with Git. The Git FAQ explains this:

Git doesn’t provide a way to do this. The reason is that if Git needs to overwrite this file, such as during a checkout, it doesn’t know whether the changes to the file are precious and should be kept, or whether they are irrelevant and can safely be destroyed. Therefore, it has to take the safe route and always preserve them.

It’s tempting to try to use certain features of git update-index, namely the assume-unchanged and skip-worktree bits, but these don’t work properly for this purpose and shouldn’t be used this way.

If your goal is to work with a configuration file, then the best thing to do is add an example or template file and then either have the user copy it into place or have a script create the appropriate file. You should then ignore the location of the actual configuration file and only check in the example or the template.

差↓一点笑了 2024-09-18 20:06:44

对于 IntelliJ IDEA 用户:如果您想忽略一个或多个文件的更改,您可以将其移动到不同的更改集

  • 前往本地更改 (Cmd + 9)
  • 选择您想要忽略的文件
  • F6 将它们移动到另一个更改设置

For IntelliJ IDEA users: If you want to ignore changes for a file (or files) you can move it to different Change Set.

  • Head over to Local Changes (Cmd + 9)
  • Select file(s) you want to ignore
  • F6 to move them to another Change Set
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文