Does multi-file unified diff requires Index: lines? - diff

When creating a multi-file unified diff is Index line required like in the following example?
Index: /file1
--- /file1
+++ /file1
_changes in file 1_
Index: /file2
--- /file2
+++ /file2
_changes in file 2_
And what is the purpose of this Index line?

The program patch man page tells that:
If there is an Index: line in the leading garbage and if either the old and new names are both absent or if patch is conforming to POSIX , patch takes the name in the Index: line.
I believe it's more a "old" thing used for the legacy patch format, and the patch generator that you use still generates that (in contextual and unified format the +++/---/*** lines already do that job). It does not harm.

Related

clang-tidy: How to suppress warnings?

I recently started experimenting with the clang-tidy tool of llvm. Now I am trying to suppress false warnings from third party library code. For this I want to use the command line options
-header-filter=<string> or -line-filter=<string>
but so far without success. So for people with limited time I will put the question here at the beginning and explain later what I already tried.
Question
What option do I need to give to the clang-tidy tool to suppress a warning from a certain line and file?
if this is not possible
What option works to suppress warnings from external header files?
What I did so far
My original call to clang-tidy looks like this
clang-tidy-3.8 -checks=-*,clang-analyzer-*,-clang-analyzer-alpha* -p Generated/LinuxMakeClangNoPCH Sources/CodeAssistant/ModuleListsFileManipulator_fixtures.cpp
and the first line of the yielded warning that I want to suppress looks like this
.../gmock/gmock-spec-builders.h:1272:5: warning: Use of memory after it is freed [clang-analyzer-cplusplus.NewDelete]
return function_mocker_->AddNewExpectation(
The gmock people told me that this is a false positive so I want to suppress it. First I tried to use the -line-filter=<string> option. The documentation says:
-line-filter=<string> - List of files with line ranges to filter the
warnings. Can be used together with
-header-filter. The format of the list is a JSON
array of objects:
[
{"name":"file1.cpp","lines":[[1,3],[5,7]]},
{"name":"file2.h"}
]
I assumed that warnings in the given lines are filtered out. But the doc doesent say if they are filterd out or in.
After some fiddeling arround I created a .json file with the content
[
{"name":"gmock-spec-builders.h","lines":[[1272,1272]]}
]
and modified the command line to
clang-tidy-3.8 -checks=-*,clang-analyzer-*,-clang-analyzer-alpha* -p Generated/LinuxMakeClangNoPCH -line-filter="$(< Sources/CodeAssistant/CodeAssistant_ClangTidySuppressions.json)" Sources/CodeAssistant/ModuleListsFileManipulator_fixtures.cpp
which writes the content of the file into the argument. This suppresses the warning, but not only this warning, but all warnings from the ModuleListsFileManipulator_fixtures.cpp file. I tried more stuff but I could not make it work.
So I tried the -header-filter=<string> option. Here the documentation states that one has to give a regular expression that matches all the header files from which diagnostics shall be displayed. Ok, I thought, lets use a regualar expression that matches everything that is in the same folder as the analyzed .cpp file. I can live with that although it may remove warnings that result from me using external headers wrong.
Here I was not sure if the regular expression must match the full (absolute) filename or only a part of the filename. I tried
-header-filter=.*\/CodeAssistant\/.*.h
which matches all absolute header filenames in the CodeAssistant folder but it did not suppress the warnings from the gmock-spec-builders.h file.
So preferably I would like to suppress each warning individually so I can determine for each if it is a real problem or not, but if this is not possible I could also live with suppressing warnings from entire external headers.
Thank you for your time.
I solved the problem by adding // NOLINT to line 1790 of gmock-spec-builders.h
Here is the diff:
--- gmock-spec-builders.orig.h 2016-09-17 09:46:48.527313088 +0200
+++ gmock-spec-builders.h 2016-09-17 09:46:58.958353697 +0200
## -1787,7 +1787,7 ##
#define ON_CALL(obj, call) GMOCK_ON_CALL_IMPL_(obj, call)
#define GMOCK_EXPECT_CALL_IMPL_(obj, call) \
- ((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call)
+ ((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call) // NOLINT
#define EXPECT_CALL(obj, call) GMOCK_EXPECT_CALL_IMPL_(obj, call)
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
It would be nice to either upstream this patch (I see other NOLINT in the code) or post a bug report with the clang-tidy folks.
I have found another non-invasive (without adding // NOLINT to a third-party library) way to suppress warnings. For example, the current version of Google Test fails some cppcoreguidelines-* checks. The following code allows you to validate the current diff excluding lines that contain gtest's macros:
git diff -U3 | sed '
s/^+\( *TEST(\)/ \1/;
s/^+\( *EXPECT_[A-Z]*(\)/ \1/;
s/^+\( *ASSERT_[A-Z]*(\)/ \1/;
' | recountdiff | interdiff -U0 /dev/null /dev/stdin | clang-tidy-diff.py -p1 -path build
It assumes that file build/compile_commands.json is generated before and clang-tidy-diff.py is available from your environment. recountdiff and interdiff from patchutils are the standard tools for manipulating patches.
The script works as follows:
git diff -U3 generates a patch with 3 context lines.
sed ... removes prefix + from the undesired lines, i.e. transform them to the context.
recountdiff correct offsets (in first ranges) in the chunk headers.
interdiff -U0 /dev/null /dev/stdin just removes all context lines from a patch. As a result, it splits the initial hunks.
clang-tidy-diff.py reads only second ranges from chunk headers and passes them to clang-tidy via -line-filter option.
UPD: It's important to provide interdiff with a sufficient number of context lines, otherwise it may produce some artifacts in the result. See the citation from man interdiff:
For best results, the diffs must have at least three lines of context.
Particularly, I have found that git diff -U0 | ... | interdiff generates some spurious literals $!otj after splitting chunks.
Use -isystem instead of -I to set your system and 3rd party include paths. -I should only be used to include code that is part of the project being built.
This is the only thing required to make clang-tidy ignore all errors in external code. All the other answers (at the point of writing) are just poor workarounds for something that is perfectly solved with -isystem.
If you use a build system like CMake or Meson it will automatically set -I and -isystem correctly for you.
-isystem is also the mechanism that is used for telling compilers, at least GCC and Clang, what's not your code. If you start to use -isystem you can also enable more compiler warnings without getting "false positives" from external code.
I couldn't achive what I wanted with the commmand line options, so I will use the // NOLINT comments in the cpp files which was proposed by the accepted answer.
I will also try to push the fix to googletest.
I found out that lines in the -line-filter options are filtered in.
But giving concrete lines is no real solution for my problem anyways.
I rather need a suppression mechanism like it is implemented in Valgrind.

Retain code highlighting when converting .Rmd to .md

I have an .rmd file that I want to put on GitHub. In order for the results to be visible along with the code I converted my .rmd file to .md via RStudio.
After conversion, however, the (r-)code is not highlighted anymore, when I view the .md file on GitHub. I noticed that a code block in the .md file is identified by indending 4 times instead of three backticks + language definition. So obviously the language definition from the .rmd file gets lost.
How can I fix this?
Note: To reproduce you can just open a new .rmd file in RStudio and change the YAML header to:
---
title: "TestRun"
output:
md_document:
variant: markdown_github
---
Help is much appreciated!
Indentation is important in YAML.
Here's an example from the R Markdown documentation:
---
output:
md_document:
variant: markdown_github
---
This YAML document has a mapping with the key output, whose value is a mapping with one key, md_document, whose value is a mapping with one key, variant, whose value is the scalar markdown_github.
The equivalent in JSON (for example) would be:
{ "output": {
"md_document": {
"variant": "markdown_github"
}
}
}
Here's your document (disregarding the title key for clarity):
---
output:
md_document:
variant: markdown_github
---
Your document has a mapping with the key output, whose value is a mapping with two keys, md_document (with an empty or null value) and variant (with the scalar value markdown_github). The JSON equivalent would be:
{ "output": {
"md_document": null,
"variant": "markdown_github"
}
}
See the difference?
Fenced code blocks (backticks + language definition) is a non-standard (although increasingly common) way of marking up code blocks. Therefore, it is not understood by all Markdown implementations. In fact, standard Markdown offers no way to identify the language of a code block. That being the case, when converting to standard Markdown, that info is appropriately lost. If you would like to retain that info, then I would suggest converting to something other that standard Markdown. Although, according to another answer, if you fix your YAML config, then you would be using the non-standard GitHub Flavored Markdown, which does support fenced code blocks.
If you really need standard Markdown, then you may find that a JavaScript highlighting engine will serve you fine. Some of the better JavaScript highlighting engines have pretty good language detection, so you usually don't need to label the language of the code blocks.

Code folding in external files with knitr and RStudio

I can find no way to insert syntactically acceptable RStudio style folds into an external R code file that is set up for use from a knitr document. Or am I missing something. There are several ways this might be done:
1) Allow a code header such as:
## #knitr Q1 ----
or perhaps
## #knitr 'Q1' ----
2) Fold every code chunk (this would be a change in RStudio), but this is not as
general as I would ideally like.
3) Allow the inclusion of some kind of comment line in code files that would indicate a fold. I have not been able to find a way to do this that does not add the comment line to the previous code chunk.
[Since initially posting this, I have noticed that the arguments 'from' and 'to' in read_chunk() can be regular expressions that specify start and from character strings for code chunks. So this gives one way to allow the insertion of comment lines that can specify folds. It would be nice however to be able to use one or more of mechanisms 1-3 above.]
From knitr v1.2.11 and above, the RStudio style code headers are supported consistently in knitr. The rule is basically # ---- label:
one or more hashes # in the beginning
followed by at least four dashes ----
followed by the chunk label
and optionally followed by any number of dashes
This is supported in both read_chunk() and purl(), i.e., this style of comments is used in both importing and exporting code in knitr.
For RStudio to support code-folding, however, you will have to add at least four dashes to the end of the comment header, e.g.,
# ---- chunk-label -----------------------------
knitr 1.2.11 is a development version on Github, which will become 1.3 eventually on CRAN.

How to patch only a particular hunk from a diff

Is there a way to apply a single hunk from a diff to a file? For example, say I do a diff from file A and B, and that produces three chunks of differences, each denoted with something like...
## -971,30 +977,28 ##
...(in the case of unified diffs). I'd then want to be able to feed that diff into stdin, and ask patch to only apply hunk N.
The manual method would be to cut-and-paste the interesting hunks, but I'm not after that kind of a solution.
filterdiff might help.
It allows extraction of subset of patches matching a variety of requirements, from one/many patch files. For example, here we extract from the file unified_diff.patch, the patches applicable to files with name matching one_file.c, only to lines 950 to 1050 of the original file:
filterdiff -i *one_file.c --lines=950,1050 unified_diff.patch
To extract specific/range of hunks:
filterdiff --hunks=1,3,5-8,15 file.patch
Extracting patches from mail messages:
filterdiff message-with-diff-in-the-body > file.patch
etc.
Some of the GUI diff/patch tools have a way to select blocks or even individual lines. I know TortoiseDiff from TortoiseSVN can work this way. I think I've seen windiff do it, but it's been a while since I had to use it.
As far as command line tools, I have not seen anything that will do what you are asking.
Emacs can not only edit diffs intelligently (including the ever-useful split-hunk operation), but can apply them one hunk at a time itself (avoiding the need to switch from the editor to run patch).

Using the output of diff to create the patch

I have something like this
src/sim/simulate.cc
41d40
< #include "mem/mem-interface.h"
90,91d88
< dram_print_stats_common(curTick/500);
<
src/mem/physical.hh
52d51
< public:
55,56d53
< public:
<
58a56,57
> public:
>
61,62c60,61
< virtual bool recvTiming(PacketPtr pkt); //baoyg
<
---
I believe this was created using the diff command in a source tree. What I want is to create the patch using that output, and to apply the same changes to my source tree.
I believe that diff -u oldfile newfile > a.patch is used to create patch files, although some other switched may be thrown in as well (-N?).
Edit: OK, 4 years later and finally going to explain what the switches mean:
-u creates a Unified diff. Unified diffs are the kind of diffs that the patch program expects to get as input. You can also specify a number after the u (min 3, default 3) to increase the number of lines output. This is in case 3 lines isn't unique enough to pinpoint just one spot in the program.
-N treats absent files as being empty, which means it will produce a lot of additional content if one of the files is empty (or see next point).
Also, newfile and oldfile can both be directories instead of single files. You'll likely want the -r argument for this to recurse any subdirectories.
If you want to get the same patch output as SVN or git diff, given two different files or folders:
diff -Naur file1.cpp file2.cpp
What you have there is a non-unified diff. patch can read it, but will be unable to make context matches and is more likely to make mistakes.
That is a (partial) patch file, though it would have been better if they provided you with a unified diff output.
The main issue with that patch is that it doesn't mention which files are being modified, and since there is no context provided, the files must be exact, patch will be unable to allow for minor changes in the file.
Copy the diff in the original post to a patch file named test.patch then run
patch <original file> test.patch
#Sparr and #Arafangion point out that this works best if you have the exact original file used to create the original diff.