tags:

views:

62

answers:

2

I have one branch (let's call it B) that ignores a certain file, which isn't ignored in some other branches (eg branch A). When i switch from branch B to branch A, then back to B again, the file has been deleted.

Is this normal? I can sort of see how it would happen, in the sense that branch B thinks it's not there, and branch A thinks that it is, so when i go back to B it 'tidies it away'. But it's kind of annoying.

Any suggestions? thanks, max

A: 

It's normal, though I'm a little surprised by one step of it.

When you switch from B to A, git sees that the file must be updated to match A's version, and does so silently because you've ignored it, saying that as far as branch B is concerned, the file doesn't matter. It has to do this - the only alternative is to refuse to check out branch A. (It would refuse if the file weren't ignored, saying "Untracked working tree file '' would be overwritten by merge". I'm actually surprised it doesn't do that in this case too. Anyone have any insight as to whether that's feature or bug?)

When you switch back to, git sees that branch B doesn't have that file, and removes it. Again, it has to do this. It has no way to read your mind and realize that that ignored file that was there a minute ago is one you want back - it simply gives you the contents of branch B, which state that the file doesn't exist.

As ewall suggests in the comments, if you want the file to survive these transitions, it needs to be tracked by all branches, or ignored in all branches.

Jefromi
+1  A: 

Since the only viable solution is to track the file 'f' at all times, you could add, only in branch B, a smudge/clean process with a gitattributes filter driver:

link text

When checkouting branch B:

  • the smudge process would change:

    • save the content of f in a temp file
    • replace the content of f with one fbis file (a tracked file which would contain, for branch B, the "B content of f")
  • the clean process would:

    • save f content (as modified in B) in fbis (fbis gets committed with f modifications in branch B)
    • restore f content (with the temp file), meaning f is not committed (ignored in B)

You can add, still in branch B, a custom merge driver which will protect fbis in case of merges from other branches to B:
the merge driver will always keep B version of fbis content, making sure the ignored file f gets back its content whenever branch B is checked-out.

Since those drivers (filter and merge) are not committed in other branches, the file 'f' is committed in other branches with all its modifications.
In branch B, its content will never change, and yet the "local modifications" made to f are still restored whenever B is checked-out.

If that content restoration is not needed, you don't need to manage fbis.
Just keep the filter driver and you will be sure that whatever modification you do to f in branch B, those changes will never be committed, effectively ignoring f content.

VonC
wow, @VonC that is an amazing answer, thank you very much. I'm not sure i'm smart enough to understand it though...hang on, need another cup of coffee...
Max Williams