如何更改.gitattributes生效 [英] How to make change to .gitattributes take effect

查看:408
本文介绍了如何更改.gitattributes生效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个最近开始使用git的项目。这个设置从一开始就不完美,所以我在人们开始克隆/工作之后设置了.gitattributes,我仍然对这个文件进行了一些修改。



考虑一下以下设置...

Alice和Bob都克隆了repo.git,并且存储库包含文件/myproj/src/file.ending,其中 \\\
作为行尾,即文件不包含 \r 字符。



它们都具有 .gitattributes ,并具有以下设置:

  /myproj/src/file.ending-text 

这告诉git file.ending 不应该被认为是一个文本文件,因此不应该发生行结束转换。


$ b $因此,Alice和Bob的工作树中的文件也有 \ n 作为行尾。



现在,Alice对.gitattributes进行了以下更改:

  /myproj/src/file.ending text 

Alice希望此更改能够对她和Bob生效。



我现在知道的唯一方法是相当侵入性的:

  git rm --cached -r。 
git reset --hard

我想避免两件事:





  • 在她实际测试之前,Alice必须提交`.gitattributes`文件(上面的重置会覆盖她的更改)。


  • Bob必须擦除其索引和工作树才能获得更新。鲍勃不开心。



这样做的首选方式是什么?

解决方案

通过希望此更改生效,是否意味着Alice希望工作副本切换到Windows和她的Bob的Windows样式行尾?那么第一个问题是,为什么Alice要为Bob的工作树负责?



如果文件更好地被新属性描述,那就这样吧; .gitattributes 文件可以像其他编辑,测试和提交一样。



您建议的过程让新的属性生效没有多大意义,原因有两个:首先,你为什么要擦掉索引? text属性影响索引和工作副本之间的关系。在你的例子中,它似乎是你需要改变的工作副本,而不是索引。

第二,你为什么要从索引中删除所有内容 ?只有属性发生变化的路径才需要解决。

因此,在你的例子中,如果Alice想要在本地反映新的属性,那么最需要的是

  rm myproj / src / file.ending 
git checkout - myproj / src / file.ending

由于此过程不会覆盖.gitattributes文件,因此无需过早提交。



我不清楚究竟是什么让Bob对你原来的程序感到不满,所以我不知道这是否让他更快乐。也许他只是希望更新在他拉时自动完成;虽然期望不是不合理的,但我不确定它是否在git中起作用。



问题是如何检测到更改。几乎在任何情况下,如果git在合并或快进结束时更新工作树(例如完成一次拉),它只需比较旧提交和新提交的索引对象的散列,以确定是否存在适用的更改。

如果属性(或过滤器定义)发生变化(如上所述),则不会更改索引。但是这些条件相对来说比较少见,并且对它们的检查比散列检查更加昂贵,几乎每次都是这样,所以不必为每次比较都加上大多无谓的代价。git允许当你知道你时已经做了某些事情,你必须采取额外的步骤。

所以如果这种情况发生一次,让团队沟通。 此路径的属性正在改变,您可能需要刷新受影响文件的工作副本。



如果这种情况一再发生,我的最佳建议是弄清楚为什么这一直在发生并修复它。您可以尝试设置某种脚本自动化,甚至可以使用挂钩来检测和解决属性更改;但是这很复杂,并且可能会比修复更麻烦。


I'm working on a project where we have recently started using git. The setup was not perfect from start, so I've set up .gitattributes after people started cloning/working and I'm still making some changes to this file.

Consider the following setup...

Both Alice and Bob have cloned "repo.git" and the repository contains the file /myproj/src/file.ending with \n as line ending, i.e. the file does not contain \r characters.

They also both have .gitattributes with the following setting:

/myproj/src/file.ending -text

This tells git that file.ending should not be considered a text file and thus no line ending conversion should take place.

Accordingly, the files in Alice's and Bob's working tree also have \n as line ending.

Now, Alice makes the following change to .gitattributes:

/myproj/src/file.ending text

Alice would like this change to take effect, both for her and for Bob.

The only way I know of right now is quite intrusive:

git rm --cached -r .
git reset --hard

I would like to avoid two things:

  • Alice has to commit her `.gitattributes` file before she can actually test it (reset above will overwrite her changes).
  • Bob has to wipe his index and working tree to get the update. Bob is not happy.

What is the preferred way of doing this?

解决方案

By "would like this change to take effect", do you mean that Alice wants the working copies to switch to Windows-style line endings for both her and Bob? Then the first problem is, why is Alice taking responsibility for what's in Bob's working tree?

If the file is better described by the new attributes, so be it; the .gitattributes file can be edited, tested, and committed just like any other.

The procedure you suggest for getting the new attributes to take effect doesn't make a lot of sense, for two reasons:

First, why are you wiping the index? The text attribute affects the relationship between the index and the working copy. In your example it seems it's the working copy you need to change, not the index.

Second, why are you wiping everything from the index? Only the paths whose attributes have changed need to be addressed.

So in your example, if Alice wants to locally reflect the new attributes, the most that should be necessary is

rm myproj/src/file.ending
git checkout -- myproj/src/file.ending

Since this procedure doesn't overwrite the .gitattributes file, there's no need to prematurely commit it.

It's not clear to me what exactly makes Bob unhappy about your original procedure, so I don't know if this one makes him any happier. Perhaps he just wants the update to be automatic when he pulls; while it's not unreasonable to expect that, I'm not sure it's in the cards as git works.

The problem is how changes are detected. In almost every situation, if git's updating the working tree at the end of a merge or fast-forward (e.g. completing a pull), it need only compare the hashes of the indexed objects for the old commit and the new commit to tell if there's a change to apply.

The exception is if attributes (or filter definitions) change - as noted above, that doesn't change the index. But those conditions are relatively rare, and the checks for them are much more expensive than hash check that's right almost every time, so rather than burden every comparison with mostly-pointless costs git allows that when you know you've done certain things, you have to take an extra step.

So if this is going to happen once, just let the team communicate. "The attributes for this path are changing; you may want to refresh your working copies of the affected files."

If it's going to happen repeatedly, my best advice is to figure out why this keeps happening and fix it. You could try to set up some kind of scripted automation, maybe even with hooks, to detect and address attribute changes; but it's a lot of complication and will likely cause more trouble than it fixes.

这篇关于如何更改.gitattributes生效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆