{"thread":{"id":"44023","subject":"How to simulate a real checkout to test a new smudge filter?","startedAt":"2016-09-06T17:47:18Z","lastAt":"2016-09-10T16:31:46Z","messageCount":11,"participants":["john smith","Torsten Bögershausen","Michael J Gruber","Jakub Narębski","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"301212","messageId":"CAKmQUfa_U-g6vC+SjbQSicEUwO+WofNfzezEEwikeOAeL31W5g@mail.gmail.com","threadId":"44023","inReplyTo":null,"subject":"How to simulate a real checkout to test a new smudge filter?","fromName":"john smith","fromEmail":"wempwer@gmail.com","sentAt":"2016-09-06T17:47:12Z","receivedAt":"2016-09-06T17:47:18Z","isPatch":false,"sender":{"key":"wempwer@gmail.com","avatar":null},"body":"I am looking for a way to force smudge filter to run by simulating a\nreal life checkout. Let's say I just created a new branch and did not\nmodify any files but want to test my new smudge filter. According to\nsome answers such as\nhttps://stackoverflow.com/questions/22909620/git-smudge-clean-filter-between-branches\nand\nhttps://stackoverflow.com/questions/21652242/git-re-checkout-files-after-creating-smudge-filter\nit should be possible by running:\n\ngit checkout HEAD --\n\nbut in doesn't work with git 2.9.0. Method suggested in accepted\nanswer here\nhttps://stackoverflow.com/questions/17223527/how-do-i-force-git-to-checkout-the-master-branch-and-remove-carriage-returns-aft\nworks but I don't like because it seems fragile. Is there a safe way\nto do what I want to do in Git still today?\n\n-- \n<wempwer@gmail.com>\n"},{"id":"301230","messageId":"b71adc54-2ae6-ef8e-1dca-0883cd617e6e@web.de","threadId":"44023","inReplyTo":"CAKmQUfa_U-g6vC+SjbQSicEUwO+WofNfzezEEwikeOAeL31W5g@mail.gmail.com","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2016-09-06T19:48:57Z","receivedAt":"2016-09-06T19:49:12Z","isPatch":false,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"On 06.09.16 19:47, john smith wrote:\n> I am looking for a way to force smudge filter to run by simulating a\n> real life checkout. Let's say I just created a new branch and did not\n> modify any files but want to test my new smudge filter. According to\n> some answers such as\n> https://stackoverflow.com/questions/22909620/git-smudge-clean-filter-between-branches\n> and\n> https://stackoverflow.com/questions/21652242/git-re-checkout-files-after-creating-smudge-filter\n> it should be possible by running:\n>\n> git checkout HEAD --\n>\n> but in doesn't work with git 2.9.0. Method suggested in accepted\n> answer here\n> https://stackoverflow.com/questions/17223527/how-do-i-force-git-to-checkout-the-master-branch-and-remove-carriage-returns-aft\n> works but I don't like because it seems fragile. Is there a safe way\n> to do what I want to do in Git still today?\n>\nIt depends what you mean with \"safe way\".\n\ngit checkout, git checkout -f or other combinations will only\n\noverwrite/rewrite the files in the working tree, if, and only if,\n\ngit comes to the conclusion that \"git add\" will do something,\n\nlike replace a blob for a file in the index.\n\n(And by running \"rm .git/index git will evaluate the \"clean\" filters,\n\nand the CRLF->LF conversion).\n\n\nIf you want to test a smudge filter, simply remove the file:\n\nmv file /tmp && git checkout file\n\n\n\n\n"},{"id":"301233","messageId":"CAKmQUfbemaid61xPyvNheLM2jVGXGjiyF_x=NZnxkZ=5wccQ=Q@mail.gmail.com","threadId":"44023","inReplyTo":"b71adc54-2ae6-ef8e-1dca-0883cd617e6e@web.de","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"john smith","fromEmail":"wempwer@gmail.com","sentAt":"2016-09-06T21:01:07Z","receivedAt":"2016-09-06T21:01:13Z","isPatch":false,"sender":{"key":"wempwer@gmail.com","avatar":null},"body":"On 9/6/16, Torsten Bögershausen <tboegi@web.de> wrote:\n> On 06.09.16 19:47, john smith wrote:\n>> I am looking for a way to force smudge filter to run by simulating a\n>> real life checkout. Let's say I just created a new branch and did not\n>> modify any files but want to test my new smudge filter. According to\n>> some answers such as\n>> https://stackoverflow.com/questions/22909620/git-smudge-clean-filter-between-branches\n>> and\n>> https://stackoverflow.com/questions/21652242/git-re-checkout-files-after-creating-smudge-filter\n>> it should be possible by running:\n>>\n>> git checkout HEAD --\n>>\n>> but in doesn't work with git 2.9.0. Method suggested in accepted\n>> answer here\n>> https://stackoverflow.com/questions/17223527/how-do-i-force-git-to-checkout-the-master-branch-and-remove-carriage-returns-aft\n>> works but I don't like because it seems fragile. Is there a safe way\n>> to do what I want to do in Git still today?\n>>\n> It depends what you mean with \"safe way\".\n\nI want to store all my dotfiles in a single repoitory.  The problem is\nthat that some specific pieces of these files are different on\ndifferent machines.  I have a special .conf file that is different on\nevery branch and contains machine-specific definitions of some\nvariables such as EMAIL or SMTP server.  In my smudge filter I call a\nscript which parses .conf file and replace all template variable\ndefinitions saved in the given file with correct definitions.  For\nexample in my ~/.bashrc I have this on all branches:\n\nexport EMAIL=\"@EMAIL@\"\n\nand in my .conf file on `home' branch\n\nEMAIL=home@address.com\n\nand on `work' branch:\n\nEMAIL=work@address.com\n\nAnd in .gitattributes on both branches:\n\nbash/.bashrc     filter=make-usable\n\nI also have single `master' branch that only contains template\ndotfiles and no .conf.  When setting up a new machine I could just\ncreate a new branch off master branch and add a new .conf.\n\nIn turn, clean filter replace all correct definitions in the given\ndotfiles back into template definitions.\n\nI'd prefer smudge/clean filters instead of `make' scripts etc. to\nconvert template dotfiles into something usable and back because\nfilters:\n\n1. could be run automatically\n\n2. do not modify files as shown by `git show HEAD:<file>' and\ntherefore no files are reported as modified by git status and also\nthere are not conflicts when merging master into work/home branch.\n\nI have problems because with point 1 because apparently smudge filter\nis not run automatically every time when branch is changed if files\nlisted in .gitattributes do not change. As the last resort I could\nforce smudge/clean filter to run just to keep advantage specified in\npoint 2.\n\n-- \n<wempwer@gmail.com>\n"},{"id":"301248","messageId":"24dcd36d-dce9-879b-5bb0-0c40021be47f@drmicha.warpmail.net","threadId":"44023","inReplyTo":"CAKmQUfbemaid61xPyvNheLM2jVGXGjiyF_x=NZnxkZ=5wccQ=Q@mail.gmail.com","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-09-07T08:52:04Z","receivedAt":"2016-09-07T08:52:14Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"john smith venit, vidit, dixit 06.09.2016 23:01:\n> On 9/6/16, Torsten Bögershausen <tboegi@web.de> wrote:\n>> On 06.09.16 19:47, john smith wrote:\n>>> I am looking for a way to force smudge filter to run by simulating a\n>>> real life checkout. Let's say I just created a new branch and did not\n>>> modify any files but want to test my new smudge filter. According to\n>>> some answers such as\n>>> https://stackoverflow.com/questions/22909620/git-smudge-clean-filter-between-branches\n>>> and\n>>> https://stackoverflow.com/questions/21652242/git-re-checkout-files-after-creating-smudge-filter\n>>> it should be possible by running:\n>>>\n>>> git checkout HEAD --\n>>>\n>>> but in doesn't work with git 2.9.0. Method suggested in accepted\n>>> answer here\n>>> https://stackoverflow.com/questions/17223527/how-do-i-force-git-to-checkout-the-master-branch-and-remove-carriage-returns-aft\n>>> works but I don't like because it seems fragile. Is there a safe way\n>>> to do what I want to do in Git still today?\n>>>\n>> It depends what you mean with \"safe way\".\n> \n> I want to store all my dotfiles in a single repoitory.  The problem is\n> that that some specific pieces of these files are different on\n> different machines.  I have a special .conf file that is different on\n> every branch and contains machine-specific definitions of some\n> variables such as EMAIL or SMTP server.  In my smudge filter I call a\n> script which parses .conf file and replace all template variable\n> definitions saved in the given file with correct definitions.  For\n> example in my ~/.bashrc I have this on all branches:\n> \n> export EMAIL=\"@EMAIL@\"\n> \n> and in my .conf file on `home' branch\n> \n> EMAIL=home@address.com\n> \n> and on `work' branch:\n> \n> EMAIL=work@address.com\n> \n> And in .gitattributes on both branches:\n> \n> bash/.bashrc     filter=make-usable\n> \n> I also have single `master' branch that only contains template\n> dotfiles and no .conf.  When setting up a new machine I could just\n> create a new branch off master branch and add a new .conf.\n> \n> In turn, clean filter replace all correct definitions in the given\n> dotfiles back into template definitions.\n> \n> I'd prefer smudge/clean filters instead of `make' scripts etc. to\n> convert template dotfiles into something usable and back because\n> filters:\n> \n> 1. could be run automatically\n> \n> 2. do not modify files as shown by `git show HEAD:<file>' and\n> therefore no files are reported as modified by git status and also\n> there are not conflicts when merging master into work/home branch.\n> \n> I have problems because with point 1 because apparently smudge filter\n> is not run automatically every time when branch is changed if files\n> listed in .gitattributes do not change. As the last resort I could\n> force smudge/clean filter to run just to keep advantage specified in\n> point 2.\n\nI'm afraid smudge/clean are not a good match for your use case:\nsmudge can do anything that clean removes again, i.e.: if you smudge a\nblob, then clean it, it has to be the same blob.\n\nYour smudge filter seems to give different results for the same blob\ndepending on other variables (your .conf), but git doesn't care as long\nas clean output is the same. Also, git cannot possibly know when \"it is\ntime\" to rerun smudge.\n\nMaybe \"source\"-ing .conf files would be an alternative approach for you,\nor using hooks?\n\nCheers\nMichael\n\n"},{"id":"301400","messageId":"e17a88cd-2de7-dc84-2262-743e82d8b047@gmail.com","threadId":"44023","inReplyTo":"CAKmQUfbemaid61xPyvNheLM2jVGXGjiyF_x=NZnxkZ=5wccQ=Q@mail.gmail.com","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"Jakub Narębski","fromEmail":"jnareb@gmail.com","sentAt":"2016-09-08T13:12:41Z","receivedAt":"2016-09-08T13:13:06Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"W dniu 06.09.2016 o 23:01, john smith pisze:\n\n> I'd prefer smudge/clean filters instead of `make' scripts etc. to\n> convert template dotfiles into something usable and back because\n> filters:\n> \n> 1. could be run automatically\n> \n> 2. do not modify files as shown by `git show HEAD:<file>' and\n> therefore no files are reported as modified by git status and also\n> there are not conflicts when merging master into work/home branch.\n> \n> I have problems because with point 1 because apparently smudge filter\n> is not run automatically every time when branch is changed if files\n> listed in .gitattributes do not change. As the last resort I could\n> force smudge/clean filter to run just to keep advantage specified in\n> point 2.\n\nCouldn't you use post-checkout hook plus clean filter instead of\nclean/smudge filter pair, if the smudge part depends on the branch?\n\nOr make post-checkout hook invoke smudge filter... though\n`git cat-file --filters` is not in any released version, I think...\n\nBest,\n-- \nJakub Narębski\n\n"},{"id":"301573","messageId":"CAKmQUfafCP6ZwUm7Ec5n2PzvNzBHnFWEJL1usMTFB6Ef0m=8pw@mail.gmail.com","threadId":"44023","inReplyTo":"e17a88cd-2de7-dc84-2262-743e82d8b047@gmail.com","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"john smith","fromEmail":"wempwer@gmail.com","sentAt":"2016-09-09T22:03:26Z","receivedAt":"2016-09-09T22:03:32Z","isPatch":false,"sender":{"key":"wempwer@gmail.com","avatar":null},"body":"On 9/8/16, Jakub Narębski <jnareb@gmail.com> wrote:\n> W dniu 06.09.2016 o 23:01, john smith pisze:\n>\n>> I'd prefer smudge/clean filters instead of `make' scripts etc. to\n>> convert template dotfiles into something usable and back because\n>> filters:\n>>\n>> 1. could be run automatically\n>>\n>> 2. do not modify files as shown by `git show HEAD:<file>' and\n>> therefore no files are reported as modified by git status and also\n>> there are not conflicts when merging master into work/home branch.\n>>\n>> I have problems because with point 1 because apparently smudge filter\n>> is not run automatically every time when branch is changed if files\n>> listed in .gitattributes do not change. As the last resort I could\n>> force smudge/clean filter to run just to keep advantage specified in\n>> point 2.\n>\n> Couldn't you use post-checkout hook plus clean filter instead of\n> clean/smudge filter pair, if the smudge part depends on the branch?\n>\n> Or make post-checkout hook invoke smudge filter... though\n> `git cat-file --filters` is not in any released version, I think...\n\nI moved smudge-filter functionality to post-checkout hook and only\nleft clean filter. Now post-checkout hooks is called every time when\nchanging branches but it's not working together with clean filter when\nchanging branches.  For example, when I have this on master in\nbash/.bashrc:\n\nexport EMAIL=\"@EMAIL@\"\n\nAfter moving to `work' it becomes this thanks to post-checkout hook\nwhich replaces @EMAIL@ with correct definition:\n\nexport EMAIL=\"work@address.com\"\n\nBut when I move to `home' branch from `work' I still get this:\n\nexport EMAIL=\"work@address.com\"\n\npost-checkout didn't work here because it can't see @EMAIL@ part in\nbash/.bashrc because clean filter has not been run. I need to run this\nsingle command to force `clean' filter to run to replace\nwork@address.com with @EMAIL@ and let post-checkout replace it with\ncorrect value:\n\ngit checkout .\n\nAnd now I get the correct definition:\n\nexport EMAIL=\"home@address.com\"\n\nSo it seems that clean filter is only run when checking out paths but\nnot when checking out branches.  Is my thinking correct?\n-- \n<wempwer@gmail.com>\n"},{"id":"301574","messageId":"xmqqwpik8zy3.fsf@gitster.mtv.corp.google.com","threadId":"44023","inReplyTo":"CAKmQUfafCP6ZwUm7Ec5n2PzvNzBHnFWEJL1usMTFB6Ef0m=8pw@mail.gmail.com","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-09-09T22:34:44Z","receivedAt":"2016-09-09T22:35:11Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"john smith <wempwer@gmail.com> writes:\n\n> So it seems that clean filter is only run when checking out paths but\n> not when checking out branches.  Is my thinking correct?\n\nIf the new branch you are going to and your current branch record\ndifferent contents for a path, that path will have to be checked out\nto the working tree, and smudge will be involved in the process to\nturn the \"clean\" contents stored in a Git object needs to be smudged\nfor use in the outside world.  If both branches have the same\ncontents, then there is no need to overwrite the path in the working\ntree with the same thing, so it is not touched.\n\nThe clean and smudge operations should look _only_ at the contents\nthey are filtering, and nothing else, and the clean/smudge filtering\nmechanism is designed to support that use case.  It is not designed\nto do things like embedding the name of the branch that is being\nchecked out into the result.\n\n"},{"id":"301580","messageId":"CAKmQUfYCUq=kUTau1-3NjjPVBk6WkP3KdTjgMC8sZtU8h=H4iQ@mail.gmail.com","threadId":"44023","inReplyTo":"xmqqwpik8zy3.fsf@gitster.mtv.corp.google.com","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"john smith","fromEmail":"wempwer@gmail.com","sentAt":"2016-09-09T23:07:00Z","receivedAt":"2016-09-09T23:07:06Z","isPatch":false,"sender":{"key":"wempwer@gmail.com","avatar":null},"body":"On 9/10/16, Junio C Hamano <gitster@pobox.com> wrote:\n> The clean and smudge operations should look _only_ at the contents\n> they are filtering, and nothing else, and the clean/smudge filtering\n> mechanism is designed to support that use case.  It is not designed\n> to do things like embedding the name of the branch that is being\n> checked out into the result.\n\nOk, I think I get it. It was actually my original problem with smudge\nfilters because I wanted them to be run after *every* checkout even if\nfile contents stayed the same (hence the subject).\n\nNow Jakub suggested post-checkout hook in conjunction with only clean\nfilter for my problem of managing dotfiles but I think I don't fully\nget it.  The problem is that in the scenario presented in my last\ne-mail clean filter is run in the situation which doesn't like a\ncheckin to me.  Is `git checkout <PATH>' doing a *checkin*\" under the\nhood so that the clean filter is called?  What does actually `checkin'\nmean in Git?  I thought that checkin it's the same as committing a\nfile into the repository.\n\n-- \n<wempwer@gmail.com>\n"},{"id":"301581","messageId":"xmqqd1kc8y6i.fsf@gitster.mtv.corp.google.com","threadId":"44023","inReplyTo":"CAKmQUfYCUq=kUTau1-3NjjPVBk6WkP3KdTjgMC8sZtU8h=H4iQ@mail.gmail.com","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-09-09T23:12:53Z","receivedAt":"2016-09-09T23:15:49Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"john smith <wempwer@gmail.com> writes:\n\n> ... get it.  The problem is that in the scenario presented in my last\n> e-mail clean filter is run in the situation which doesn't like a\n> checkin to me.  Is `git checkout <PATH>' doing a *checkin*\" under the\n> hood so that the clean filter is called?  What does actually `checkin'\n> mean in Git?  I thought that checkin it's the same as committing a\n> file into the repository.\n\nI do not know what Jakub meant.\n\nWhen we need to see if we need to update a working tree file, and\nwhen we cannot tell if you modified the working tree file since you\nchecked it out, we may have to run the clean filter (and other\nconversions collectively called \"convert-to-git\") on the contents in\nit and see if the resulting blob matches what is recorded in the\nindex (if they match, there is no need to update the working tree\nfile; if they don't match, we either report that you have a local\nmodification, or we overwrite it with the contents, depending on\nwhat operation we are doing for the user).\n"},{"id":"301597","messageId":"a00fa147-291c-536c-35da-56f88221e0f8@gmail.com","threadId":"44023","inReplyTo":"CAKmQUfYCUq=kUTau1-3NjjPVBk6WkP3KdTjgMC8sZtU8h=H4iQ@mail.gmail.com","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"Jakub Narębski","fromEmail":"jnareb@gmail.com","sentAt":"2016-09-10T10:32:47Z","receivedAt":"2016-09-10T10:32:58Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"W dniu 10.09.2016 o 01:07, john smith pisze:\n> On 9/10/16, Junio C Hamano <gitster@pobox.com> wrote:\n>> The clean and smudge operations should look _only_ at the contents\n>> they are filtering, and nothing else, and the clean/smudge filtering\n>> mechanism is designed to support that use case.  It is not designed\n>> to do things like embedding the name of the branch that is being\n>> checked out into the result.\n> \n> Ok, I think I get it. It was actually my original problem with smudge\n> filters because I wanted them to be run after *every* checkout even if\n> file contents stayed the same (hence the subject).\n\nAnd that's not the case, for performance reasons.\n\n> \n> Now Jakub suggested post-checkout hook in conjunction with only clean\n> filter for my problem of managing dotfiles but I think I don't fully\n> get it.  The problem is that in the scenario presented in my last\n> e-mail clean filter is run in the situation which doesn't like a\n> checkin to me.  Is `git checkout <PATH>' doing a *checkin*\" under the\n> hood so that the clean filter is called?  What does actually `checkin'\n> mean in Git?  I thought that checkin it's the same as committing a\n> file into the repository.\n\nI was wrong, I'm sorry. My mistake.\n\nYou would need post-checkout hook together with clean / smudge filters\n(though you could get by without smudge filter, at least in theory...).\nThe `post-checkout` hook could run e.g. \"git checkout -- '*.conf'\"\nto force use of smudge filter, after checking that it was a change\nof branch (\"git checkout <commit-ish>\").  See githooks(5) for details\n(last, third parameter passed to hook script is 1, rather than 0).\n\nUnfortunately I don't see a way to query .gitattributes files to\nfind out all patterns that match specific attribute; you would need\nto duplicate configuration:\n\n  .gitattributes:\n  *.conf filter=transform\n\n  .git/config\n  [filter \"transform\"]\n  \tclean  = replace-with-placeholder %f\n  \tsmudge = expand-with-branchname %f\n\n  .git/hooks/post-checkout\n  #!/bin/sh\n\n  test \"$3\" -eq \"1\" && git checkout -- '*.conf'\n\nOr something like that.\n-- \nJakub Narębski\n\n"},{"id":"301603","messageId":"CAKmQUfagUP6xia5_KjQ=pdtBzU2DHpV0=F1FGCh0P1yWNY5Hfw@mail.gmail.com","threadId":"44023","inReplyTo":"a00fa147-291c-536c-35da-56f88221e0f8@gmail.com","subject":"Re: How to simulate a real checkout to test a new smudge filter?","fromName":"john smith","fromEmail":"wempwer@gmail.com","sentAt":"2016-09-10T16:31:36Z","receivedAt":"2016-09-10T16:31:46Z","isPatch":false,"sender":{"key":"wempwer@gmail.com","avatar":null},"body":"On 9/10/16, Jakub Narębski <jnareb@gmail.com> wrote:\n> You would need post-checkout hook together with clean / smudge filters\n> (though you could get by without smudge filter, at least in theory...).\n> The `post-checkout` hook could run e.g. \"git checkout -- '*.conf'\"\n> to force use of smudge filter, after checking that it was a change\n> of branch (\"git checkout <commit-ish>\").  See githooks(5) for details\n> (last, third parameter passed to hook script is 1, rather than 0).\n\nNeat idea.  I could still have an advantage of filter as git status\nwouldn't show that files are changed and there would be no merge\nconflicts and additionally filters would run after every checkout even\nif files stayed the same.  But are sure that `git checkout -- <FILE>'\nactually forces checkout and runs smudge filter?  It doesn't work for\nme neither with 2.9.0 nor 2.10.0.85.gcda1bbd.  For a minimal example,\nlet's say that I have this in .gitattributes:\n\na     filter=test-filter\n\nAnd this in .git/config:\n\nsmudge = touch /tmp/SMUDGE_RUN && cat\n\nAnd also have a tracked file named `a' in the repository. Now this\nshould create /tmp/SMUDGE_RUN:\n\ngit checkout  -- a\n\nbut it doesn't.\n\nThis also doesn't work:\n\ngit checkout -f -- a\n\nBut this does:\n\ngit checkout HEAD^ && git co -\n\n> Unfortunately I don't see a way to query .gitattributes files to\n> find out all patterns that match specific attribute; you would need\n> to duplicate configuration:\n>\n>   .gitattributes:\n>   *.conf filter=transform\n>\n>   .git/config\n>   [filter \"transform\"]\n>   \tclean  = replace-with-placeholder %f\n>   \tsmudge = expand-with-branchname %f\n>\n>   .git/hooks/post-checkout\n>   #!/bin/sh\n>\n>   test \"$3\" -eq \"1\" && git checkout -- '*.conf'\n\nIt's a secondary issue, but - in my repository I only have one .conf\nfile on every branch with real definitions of machine-specific\nvariables and a number of various config files for various programs\nsuch as bash/.bashrc or screen/.screenrc so in my case it would be:\n\n  .gitattributes:\n  bash/.basrc filter=transform\n  git/.gitconfig filter=transform\n  (...)\n\n  .git/config\n  [filter \"transform\"]\n        clean  = replace-with-placeholder %f\n        smudge = expand-with-branchname %f\n\n  .git/hooks/post-checkout\n  #!/bin/sh\n\n  test \"$3\" -eq \"1\" && (\n       git checkout -- bash/.bashrc &&\n       git checkout -- git/.gitconfig\n       (...)\n       )\n\nOf course a list of files in .git/hooks/post-checkout could be\ngenerated at runtime from first column of .gitattributes.\n\n-- \n<wempwer@gmail.com>\n"}]}