Is there some cleaner way to make Git just ignore some of my changes and never commit them?
.gitattributes:
config_to_be_deviated.xml filter=qqq
.git/config:
[filter "qqq"]
clean = "perl -ne 'print unless /git_please_dont_look_here/'"
smudge = (Q=$(mktemp) && cat > $Q && patch -s $Q < /tmp/pp && cat $Q && rm $Q)
The patch /tmp/pp adds my changes with "git_please_dont_look_here" in each line.
Git removes all such lines before getting the file into repository and readds my changes when checking out it; I can continue adding and committing useful changes to config_to_be_deviated.xml
, but changes in the patch will not be seen by Git.
Put them into separate file, ignore the file in git and hook it up to your build so it gets included?
try git update-index --assume-unchanged --<path>
. It acts like gitignore for files under source control. The original purpose of the feature though, was to improve performance of git checking modifications in a folder with lots of files. Here is the doco:
--assume-unchanged
--no-assume-unchanged
When these flags are specified, the object names recorded for the
paths are not updated. Instead, these
options set and unset the "assume
unchanged" bit for the paths. When the
"assume unchanged" bit is on, git
stops checking the working tree files
for possible modifications, so you
need to manually unset the bit to tell
git when you change the working tree
file. This is sometimes helpful when
working with a big project on a
filesystem that has very slow lstat(2)
system call (e.g. cifs).
This option can be also used as a coarse file-level mechanism to ignore
uncommitted changes in tracked files
(akin to what .gitignore does for
untracked files). You should remember
that an explicit git add operation
will still cause the file to be
refreshed from the working tree. 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.
It looks like this "filter" approach is the best suited for me.
Pros:
- No need to use custom scripts or special commands every time. One-time setup.
- No extra commits in history or in stash. Clean diffs and patches.
- Low rick of committing the wrong thing.
- Relatively easy to make minor deviations (like overriding some port number in config file), like simple sed script both for smudge and for clean.
Cons:
- Filter programs runs every time Git reads or writes the file, it can be slow (especially in Windows).
- Put the canonical, default configuration in the git tree, but play no games with it. It's in the tree, and if you make changes to it, they'll be committed.
- The software looks for the default configuration, but it also looks for a configuration in the developer's home directory. If it finds both, it merges the two. Any configuration items found in the developer's config file override those in the default config file.
Now the default config is tracked, and your customizations of the default config are not.
I am not all to familiar with git. With Mercurial I use a patch queue (MQ) or the shelve (similar to git stash) for such things.
git stash
can be convenient to use, if you're "localizable" information is easy to locate (e.g. all in a single config file).
Using a patch queue is a little more complex but once setup correctly superior because you can manage localizable information in a transparent push/pop manner. You can find a list of patch queues on top of git here on SO.