unified diff: text after second ## of a hunk - diff

I could not find a specification for the unified diff format on the web. Often one sees text from the diffed files after the second ## of a hunk, like this:
## -209,4 +196,4 ## cleanup:
_TEMPLATE(T, vec) (X);
}
-#endif
\ No newline at end of file
+#endif
Does the text after the second ## matter at all?

This stumped me too as it was breaking the open-source patch parser I was using. It seems this isn't well understood even by tool makers.
Apparently the text after the ## is generated by the --show-c-function flag to diff, documented here. In your case the title is a bit of misnomer, since your text is not a function definition, but (probably) a label which gets caught when diff looks above the edited lines for the most identifier which isn't indented.
You can see an example of how this feature works here:
Normal
diff --unified=3 <(curl -s https://raw.githubusercontent.com/gcc-mirror/gcc/97574c57cf26ace9b8609575bbab66465924fef7/gcc/config/sparc/sparc.c) <(curl -s https://raw.githubusercontent.com/gcc-mirror/gcc/17fc6eeba9352b97ba16d64fd1de9a5bdc081062/gcc/config/sparc/sparc.c) | sed -n '3p'
output: ## -648,7 +648,6 ##
--show-c-function
diff --show-c-function --unified=3 <(curl -s https://raw.githubusercontent.com/gcc-mirror/gcc/97574c57cf26ace9b8609575bbab66465924fef7/gcc/config/sparc/sparc.c) <(curl -s https://raw.githubusercontent.com/gcc-mirror/gcc/17fc6eeba9352b97ba16d64fd1de9a5bdc081062/gcc/config/sparc/sparc.c) | sed -n '3p'
output: ## -648,7 +648,6 ## static reg_class_t sparc_secondary_reloa
As far as I can tell, the text after ## is mostly for human consumption and you can safely ignore it if you want to.

Related

Search for files & file names using silver searcher

Using Silver Searcher, how can I search for:
(non-binary) files with a word or pattern AND
all filenames, with a word or pattern including filenames of binary files.
Other preferences: would like to have case insensitive search and search through dotfiles.
Tried to alias using this without much luck:
alias search="ag -g $1 --smart-case --hidden && ag --smart-case --hidden $1"
According to the man page of ag
-G --file-search-regex PATTERN
Only search files whose names match PATTERN.
You can use the -G option to perform searches on files matching a pattern.
So, to answer your question:
root#apache107:~/rpm-4.12.0.1# ag -G cpio.c size
rpm2cpio.c
21: off_t payload_size;
73: /* Retrieve payload size and compression type. */
76: payload_size = headerGetNumber(h, RPMTAG_LONGARCHIVESIZE);
the above command searches for the word size in all files that matches the pattern cpio.c
Reference:
man page of ag version 0.28.0
Note 1:
If you are looking for a string in certain file types, say all C sources code, there is an undocumented feature in ag to help you quickly restrict searches to certain file types.
The commands below both look for foo in all php files:
find . -name \*.php -exec grep foo {}
ag --php foo
While find + grep looks for all .php files, the --php switch in the ag command actually looks for the following file extensions:
.php .phpt .php3 .php4 .php5 .phtml
You can use --cpp for C++ source files, --hh for .h files, --js for JavaScript etc etc. A full list can be found here
Try this:
find . | ag "/.*SEARCHTERM[^/]*$"
The command find . will list all files.
We pipe the output of that to the command ag "/.*SEARCHTERM[^/]*$", which matches SEARCHTERM if it's in the filename, and not just the full path.
Try adding this to your aliases file. Tested with zsh but should work with bash. The problem you encountered in your example is that bash aliases can't take parameters, so you have to first define a function to use the parameter(s) and then assign your alias to that function.
searchfunction() {
echo $(ag -g $1 --hidden)
echo $(ag --hidden -l $1)
}
alias search=searchfunction
You could modify this example to suit your purpose in a few ways, eg
add/remove the -l flag depending on whether or not you want text results to show the text match or just the filename
add headers to separate text results and filename results
deduplicate results to account for files that match both on filename and text, etc.
[Edit: removed unnecessary --smart-case flag per Pablo Bianchi's comment]
Found this question looking for the same answer myself. It doesn't seem like ag has any native capability to search file and directory names. The answers above from Zach Fogg and Jikku Jose both work, but piping find . can be very slow if you're working in a big directory.
I'd recommend using find directly, which is much faster than piping it through ag:
Linux (GNU version of find)
find -name [pattern]
OSX (BSD version of find)
find [pattern]
If you need more help with find, this guide from Digital Ocean is pretty good. I include this because the man pages for find are outrageously dense if you just want to figure out basic usage.
To add to the previous answers, you can use an "Or" Regular Expression to search within files matching different file extensions.
For example to just search a string in C++ header files [.hpp] and Makefiles [.mk] ) :
ag -G '.*\.(hpp|mk)' my_string_to_search
After being unsatisfied with mdfind, find, locate, and other attempts, the following worked for me. It uses tree to get the initial list of files, ag to filter out directories, and then awk to print the matching files themselves.
I wound up using tree because it was more (and more easily) configurable than the other solutions I tried and is fast.
This is a fish function:
function ff --description 'Find files matching given string'
tree . --prune --matchdirs -P "*$argv*" -I "webpack" -i -f --ignore-case -p |
ag '\[[^d].*' |
awk '{print $2}'
end
This gives output similar to the following:
~/temp/hello_world $ ff controller
./app/controllers/application_controller.rb
./config/initializers/application_controller_renderer.rb
~/temp/hello_world $

Annotated diff file with "<<<<<<< mine" and ">>>>>>> yours" type markers

I am trying to create a diff file using the Linux diff command that has markers like this (taken from diff3 man page):
<<<<<<< mine
lines from mine
=======
lines from yours
>>>>>>> yours
This format is very intuitive for me and allows me to easily fix merge conflicts in vim and it works great when I am trying to merge three files (mine, yours and original) using diff3 but I would like the same format from plain diff. I was hoping this would be simple but I have not been able to get it. I have tried most of the main options (-e,--ed, etc.) and even tried to create a --changed-group-format but was unsuccessful.
Hopefully this is something simple that I just overlooked.
UPDATE:
Two file diff example with added line, removed line and conflict line:
You could play with the diff options. The shell script below
diff \
--unchanged-group-format='%=' \
--old-group-format='' \
--new-group-format='%>' \
--changed-group-format='<<<<<<< mine
%<=======
%>>>>>>>> yours
' \
orig.txt new.txt
Outputs
This has some stuff
in that gets
modified in
a later version
<<<<<<< mine
and there is a conflict
=======
and there is a conflict (like here)
>>>>>>> yours
about which version
should be used.
newline
For the files as in your screenshot. You could look more formatting options for the diff in a documentation, e.g. here.
One liner (works from command line, at least on linux):
diff --unchanged-group-format="%=" --old-group-format="" --new-group-format="%>" --changed-group-format="<<<<<<< mine%c'\\12'%<=======%c'\\12'%>>>>>>>> yours%c'\\12'" orig.txt new.txt

Organizing my papers in org-mode

I've just started using org-mode, and so far find it quite useful. I have a very large collection of technical papers in a directory tree, and I'd like to go through them and index them through org-mode. What I'd like is to have a way of going through them and look at the unannotated ones, and annotate them one by one. I imagine doing this by first making up a file of links like [[xxx.pdf][not done yet]], and then being presented with the not done ones, glancing at them and deciding how what annotations to put in. In addition I'd like to add tags. What I'd really like is to be able to make up new tags on the fly. Has anyone done anything like this in org-mode?
Victor
If you have your papers organized like this,
% ls -1 ~/References/functional-programming
The Lambda Calculus.pdf
Recursive Functions of Symbolic Expressions and Their.pdf
you can run a quick script to build an org-file. Save the following as make-org and run it from your directory of papers (sh make-org > papers.org).
#! /bin/sh
#
# make-org -- generates an org-mode file from a directory of PDFs
#
# AUTHOR:
# Jon-Michael Deldin
# USAGE:
# cd ~/path/to/papers && make-org > papers.org
#
echo "#+TITLE: Research Papers"
echo "#+STARTUP: align hidestars indent lognotedone"
echo
for f in *.pdf; do
name=${f%.*} # strip extension
path=$(echo $f | sed 's/ /%20/') # encode spaces as %20
echo "* TODO $name :unread:"
echo
echo "[[file:$path][$name]]"
echo
done
Open papers.org in Emacs, run C-u C-c C-q to realign the tags. Your file should now look like this:
In addition I'd like to add tags. What I'd really like is to be able to make up new tags on the fly.
Once you have a headline (thing with * at the beginning, you can hit C-c C-c and add any tag you want.
You may find this detailed write-up of using org-mode and RefTeX or this alternate approach useful, especially if you use LaTeX.
Heres is the modified version that works on a directory.
#! /bin/sh
#
# make-org -- generates an org-mode file from a directory of PDFs
#
# AUTHOR:
# Jon-Michael Deldin
# USAGE:
# cd ~/path/to/papers && make-org > papers.org
#
echo "#+TITLE: Research Papers"
echo "#+STARTUP: align hidestars indent lognotedone"
echo
for f in $(find . -name '*.pdf'); do
name=${f%.*} # strip extension
path=$(echo $f | sed 's/ /%20/') # encode spaces as %20
echo "* TODO $name :unread:"
echo
echo "[[file:$path][$name]]"
echo
done

diff does not work with subdirectories

I want to patch whole directory tree. Although diff finds all differences, patch does apply these to relevant files. When I change a file in subdir I can see patch crate that file one level above it should in the directory tree being patched.
I use command:
diff -Nur extern/ local/ | patch -d extern
what is wrong with that?
Since you're passing -d dir ("Change to the directory dir immediately, before doing anything else.") you also need to tell patch to strip off one level of directories with -p:
diff -Nur extern/ local/ | patch -d extern -p1
That's because diff's output will look something like this:
+++ extern/foo.x
--- local/foo.x
## -21,7 +21,9 ##
- yyy
+ xxx
... so you need to get rid of that first prefix in the path.

Perforce -- generate a diff including added files?

When I use "p4 diff", it ignores files that I have open for add. Is it possible to generate a diff that includes added files as well as changed files?
Considering the diff in Perforce compare the files in the client workspace to revisions in the depot, the short answer is "no".
There is no recorded history to compare to for the added file (not committed to the depot before a submit)
The longer answer would involve a script to complete the diff with the full content of the added files. (kind of like in this SO question)
This is a known missing feature of p4 diff that lots of tools dealing with Perforce have to work around.
The code review tool Reviewboard comes with the tool post-review. It is used to create diffs for a a codereview, but it will just do a diff if you want.
It's in python, you could pull out the diff section for your own use.
I wrote this to help me on cygwin:
#!/bin/bash
if [ $# -ne 1 ]; then
echo "usage: $0 <pathSpec>"
exit 1
fi
pathSpec=$1
doIt () {
p4 opened "$pathSpec" | egrep "#.* - add" | while read f; do
# figure out the workspace path
depotPath=${f%#*}
clientFileLine=$(p4 fstat "$depotPath" | grep clientFile)
workspacePathWin=${clientFileLine#... clientFile }
# diff output
echo ==== $depotPath#1 - $workspacePathWin ====
workspacePath=$(cygpath "$workspacePathWin")
lineCount=$(wc -l < "$workspacePath")
echo ## -0,0 +1,$lineCount ##
# the actual diff contents
sed -e 's/^/+/' "$workspacePath"
echo
done
}
doIt
I just worked around this issue and got my added files included in a Fisheye pre-commit review.
What I did was copy the edited files' diff hunk descriptor header. This includes one line which lists the depot and local paths - pretty straightforward - and another line with the range information, formatted as described here.
So, I added each appended each file's contents to the diff, each preceded by
==== //path/to/depot/file#1 - /path/to/workspace/file ====
## -1,1 +1,LEN ##
where LEN is the number of lines in the added file.
This worked for me; Your Mileage May Vary.
I just got this to work, branching off Aaron's answer. Instead of
==== //path/to/depot/file#1 - /path/to/workspace/file ====
I used
--- //path/to/file [TIMESTAMP GENERATED BY NORMAL DIFF]
+++ //path/to/file [TIMESTAMP GENERATED BY NORMAL DIFF]
## -1,1 +1,LEN ##
Then make sure to have a + at the beginning of each added line.
Just p4 print the added files (I know, that's not great) - but its definitely one way to go.