use git smudge/clean to replace file contents
ideally i want the contents in the repo to be changed before i run git checkout -f not changed in the live copy after
The closest is a filter content driver which will replace the value at the git checkout
.
(from Scott Schacon's Pro Git book page on Git Attributes: section "Keyword Expansion")
So in your case: a smudge filter, declared in a .gitattributes
file.
See "Can git automatically switch between spaces and tabs?", except you would use a sed to replace local to live (as in this example)
Git clean filter - retrieve original line, git smudge but not original line
Your smudge script should save the captured group in a file of the same name, with a .smudge
extension (for instance), and a .gitignore
including *.smudge
.
That way, your clean filter script can read the original value from the xxx.smudge, and restore the file to its original content through a reverse sed
.
You can pass the file name to your scripts using %f
. (see .gitattributes#filters
)
git: re-checkout files after creating smudge filter
Simply re-checkout everything.
cd /path/to/your/repo
git stash save
rm .git/index
git checkout HEAD -- "$(git rev-parse --show-toplevel)"
git stash pop
The smudge filter will be applied at that new checkout.
Note, as seen in this answer, you need to remove the index in order to force the filter to run again.
Alexander Amelkin comments below:
I have created an alias '
reattr
' to perform all those steps and now I am happy.
reattr = !sh -c "\"git stash save; rm .git/index; git checkout HEAD -- \\\"$(git rev-parse --show-toplevel)\\\"; git stash pop\""
(multi-line for readability)
reattr = !sh -c "\"git stash save; \
rm .git/index; \
git checkout HEAD -- \\\"$(git rev-parse --show-toplevel)\\\"; \
git stash pop\""
Git smudge and clean using local configuration branch
Although it is not documented anywhere, you cannot change the state of the working tree with a smudge or clean filter. Git expects to invoke the filter once for each file by piping data into it and reading the data from the standard output. In other words, these filters are intended to be invoked on a per-file basis and process only that file, not by modifying the working tree state.
The best solution to your problem is to avoid keeping a separate branch. Simply keep all of the files, both development and production, in some directory, and use a script to copy the correct one into place. The location of the running config file should be ignored, so the script won't cause Git to show anything as modified. Alternatively, keep a template somewhere, and have the script generate the appropriate one based on the environment. This is good if you have secrets for production that should not be checked in; you can pass them to the script through the environment and have the right values generated.
What you're doing is related to ignoring tracked files, which, as outlined in the Git FAQ, generally can't be done successfully.
git attribute using filter smudge/clean to process .cpp files through shell script not finding filename
You have the %f
directive in the wrong place.
As shown in the gitattributes documentation (search for %f
):
Sequence "%f" on the filter command line is replaced with the name of the file the filter is working on. A filter might use this in keyword substitution. For example:
[filter "p4"]
clean = git-p4-filter --clean %f
smudge = git-p4-filter --smudge %f
Hence, to get the path name of the file, you would need to set, e.g., filter.codeformat.clean
to codeformat %f
.
At this point you will also need to modify your bash script, since its syntax for argument substitution is indeed $1
. However, read the immediate next paragraph from the gitattributes documentation:
Note that "%f" is the name of the path that is being worked on. Depending on the version that is being filtered, the corresponding file on disk may not exist, or may have different contents. So, smudge and clean commands should not try to access the file on disk, but only act as filters on the content provided to them on standard input.
The emphasis here is mine, but this is telling you that you cannot simply open the disk file and read it. You must filter only the standard input, providing standard output.
(As it turns out, clang-format is designed to do just that. Diff, however, is not.)
Edit to add working example:
$ cat ~/scripts/dotest
#! /bin/sh
echo "dotest run with $# arguments:" >>/tmp/dotest_log
for i do
printf '%s\n' "$i"
done >>/tmp/dotest_log
cat
$ which dotest
[path edited]/scripts/dotest
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[filter "testfilter"]
clean = dotest %f
smudge = dotest %f
$ cat .gitattributes
*.test filter=testfilter
$ echo 'bar.test' > bar.test
$ git add bar.test
$ cat /tmp/dotest_log
dotest run with 1 arguments:
bar.test
git smudge/clean filter between branches
I expected to see the value true in the file
You just created a new branch, not checked out its content (sice its content is the same as the branch you were in)
To force the smudge to run, do at the top of the repo:
git checkout HEAD --
I have not yet merged the change across from the test branch, I have not made a commit on the production branch, yet the file has changed.
That is the idea of a content filter driver: it modifies the content, without affecting git status
(which still reports the modified file as "unchanged").
To have a smudge acting differently per branch, I would recommend calling a script which starts by looking the name of the current branch.
See an example in my older answer "Best practice - Git + Build automation - Keeping configs separate".
#!/bin/sh
branch=$(git rev-parse --symbolic --abbrev-ref HEAD)
Related Topics
Having Two Different Sessions in Same Domain
How to Perform an Action Every 5 Results
How to Get User Timezone Using Jquery
3Rd Party Dependency Conflict in Developing Wordpress Plugin
Mod_Rewrite, PHP and the .Htaccess File
PHP on Godaddy Linux Shared Trying to Send Through Gmail Smtp
How to Debug Why Simplest MySQL Query Returns False
Why Use Sprintf Function in PHP
Explain $Ci =& Get_Instance();
Memory_Get_Peak_Usage() with "Real Usage"
Detecting a Url Using Preg_Match? Without Http:// in the String
Retrieve (Or Simulate) Full Query from Pdo Prepared Statement
How to Obtain a Nested HTML List from Object's Array Recordset
Dynamic Shipping Fee Based on Custom Radio Buttons in Woocommerce