问题
I've made a single simple change to a large number of files that are version controlled in git and I'd like to be able to check that no other changes are slipping into this large commit.
The changes are all of the form
- "main()",
+ OOMPH_CURRENT_FUNCTION,
where "main()" could be the name of any function. I want to generate a diff of all changes that are not of this form.
The -G and -S options to git diff are tantalisingly close--they find changes that DO match a string or regexp.
Is there a good way to do this?
Attempts so far
Another question describes how regexs can be negated, using this approach I think the command should be
git diff -G '^((?!OOMPH_CURRENT_FUNCTION).)*$'
but this just returns the error message
fatal: invalid log-grep regex: Invalid preceding regular expression
so I guess git doesn't support this regex feature.
I also noticed that the standard unix diff has the -I option to "ignore changes whose lines all match RE". But I can't find the correct way to replace git's own diff with the unix diff tool.
回答1:
Try the following:
$ git diff > full_diff.txt
$ git diff -G "your pattern" > matching_diff.txt
You can then compare the two like so:
$ diff matching_diff.txt full_diff.txt
If all changes match the pattern, full_diff.txt
and matching_diff.txt
will be identical, and the last diff
command will not return anything.
If there are changes that do not match the pattern, the last diff
will highlight those.
You can combine all of the above steps and avoid having to create two extra files like so:
diff <(git diff -G "your pattern") <(git diff) # works with other diff tools too
回答2:
Use git difftool
to run a real diff
.
Example: https://github.com/cben/kubernetes-discovery-samples/commit/b1e946434e73d8d1650c887f7d49b46dcbd835a6
I've created a script running diff
the way I want to (here I'm keeping curl --verbose
outputs in the repo, resulting in boring changes each time I rerun the curl):
diff --recursive --unified=1 --color \
--ignore-matching-lines=serverAddress \
--ignore-matching-lines='^\* subject:' \
--ignore-matching-lines='^\* start date:' \
--ignore-matching-lines='^\* expire date:' \
--ignore-matching-lines='^\* issuer:' \
--ignore-matching-lines='^< Date:' \
--ignore-matching-lines='^< Content-Length:' \
--ignore-matching-lines='--:--:--' \
--ignore-matching-lines='{ \[[0-9]* bytes data\]' \
"$@"
And now I can run git difftool --dir-diff --extcmd=path/to/above/script.sh
and see only interesting changes.
An important caveat about GNU diff -I
aka --ignore-matching-lines
: this merely prevents such lines from making a chunk "intersting" but when these changes appear in same chunk with other non-ignored changes, it will still show them. I used --unified=1
above to reduce this effect by making chunks smaller (only 1 context line above and below each change).
回答3:
I think that I have a different solution using pipes and grep
. I had two files that needed to be checked for differences that didn't include @@
and g:
, so I did this (borrowing from here and here and here:
$ git diff -U0 --color-words --no-index file1.tex file2.tex | grep -v -e "@@" -e "g:"
and that seemed to do the trick. Colors still were there.
So I assume you could take a simpler git diff
command/output and do the same thing. What I like about this is that it doesn't require making new files or redirection (other than a pipe).
来源:https://stackoverflow.com/questions/15878622/ignoring-changes-matching-a-string-in-git-diff