Note: For wont of a better word I call the fluff at the start of source files --
/* #(#) $Id: file.c,v 1.9 2011/01/05 11:55:00 user Exp $
**************************************************************************
* COPYRIGHT, 2005-2011 *
...
*/
-- Keyword Substitution comments, although I do not know if this is just a subversion term.
Anyway, now to the question: We have a 3rd party supplier that we get source code from. These c source all have these keyword subst comments, and every time we get a new version from the supplier, all (1000+) files are changed because they update these comments for every release they send us, even if no source code changes whatsover are made in these files, so the only change is the comments. Now, before we compile and use these sources, we would be interested in doing a cursory code review to see the areas that have been changed. (Never trust the release history). However, this is rather difficult, as doing a simple folder diff will obviously list all files.
What I'm looking for now is whether there already exist any simple tools to strip these special multi line comments from the source files. Maybe anyone has a link to a grep or sed script that will scratch that stuff from the files?
Something like:
perl -ne 'if(m+/\*.*\$Id: +) $c = 1; print unless $c; if($c && m+\*/+) $c = 0;'
Note that this will work only if
such comments are delimited with /*...*/
on the first line there is $Id:
there is nothing after the */
there is no */ before the /*
And that it will strip all lines that are between start of comment and end of comment.
I have not tested it!
First, I would try to convince them to review either their version control system (looks as if they use RCS, still?) or if that is not possible to have them hook up to a svn or git server for submitting their changes. But perhaps you already did?
If nothing in that sense is possible, I would try to set up a git repository to hold the versions that they supply to you. Git allows you to have filters when you are importing or exporting and also has support for ignoring such tags for deltas between versions.
Related
I am working with a tool which auto-generates a large amount of C code. The tool generates code for a batch of .c and .h files at each run. For some reason, the tool isn't smart enough to recognize when the files have no substantial changes, so in many cases it simply updates a timestamp in the comments at the top of each file. Otherwise, the file remains unaltered.
When I run git status in that scenario, I sometimes see dozens or hundreds of files changed. But as I review the changes to the individual files, most of them have no real changes - just an update to the timestamp. I have to go through each file one-by-one to determine if there are any actual changes to be committed.
Is there a way to configure Git so that it can ignore inconsequential changes such as the timestamp in the header comments? Or how might I otherwise deal with this situation?
Thanks for your help.
Is there a way to configure Git so that it can ignore inconsequential changes such as the timestamp in the header comments? Or how might I otherwise deal with this situation?
Yes; this is the purpose of a filter.
You might be familiar with git's notion of "clean" and "smudge" filters already, that's how it handles line ending conversion. When you are on a Windows computer and have Windows-style line endings in your working directory, you might set a .gitattribute like * text=auto indicating that you want files checked into the repository with "normalized" Unix-style line endings. In this case, the files will have the "clean" filter applied to convert \r\n line endings to \n style line endings. Similarly, the files will be "smudged" on checkout to convert from \n to \r\n on-disk.
You can create your own clean and smudge filters to remove (or add) data when translating between the working directory and the repository. For these files you can add an attribute:
*.c filter=autogen
And then you can configure your autogen filter, with commands to run in the "clean" (into the repository) and "smudge" (into the working directory) directions.
git config --global filter.autogen.clean remove_metadata
git config --global filter.autogen.smudge cat
(Using cat is a "noop" as far as filters are concerned).
The Pro Git book has more detailed examples of creating your own filters.
I discovered a way to address the problem of trivial changes using Beyond Compare. I will describe the process as it pertains to ignoring timestamp updates in auto-generated C files, but it can be easily adapted to other situations and languages:
Configure Beyond Compare as the Git difftool. See here for specific details about how to do this.
(Optional but helpful) Add a Git alias for the git difftool --dir-diff --no-symlinks command (for example, dtd).
Make some changes (e.g. auto-generate your files), and run git dtd to do a directory diff. Beyond Compare will open and show you a before/after Folder Comparison of your changes.
Open a Text Compare session window for one of your changed files. Open the Tools menu and select File Formats.
Open the Grammar tab, delete the "Comments" grammar element.
Add a new grammar element and give it a meaningful name such as "Generation Time Comment".
For Category, select the "Delimited" grammar element. In the "Text from" box, enter the text you would like to ignore. For example, if the timestamp in your auto-generated code starts with the string * Generation Time:, enter it into the "Text from" box. Check the "Stop at end of line" checkbox.
Click the "Save" button and go back to your Text Compare session window.
Open the Session menu and select Session Settings. Open the Importance tab.
Look for your new grammar element (e.g. "Generation Time Comment") and uncheck it. This will tell Beyond Compare to treat it as an unimportant change.
Open the Comparison tab, select Rule-Based Comparison.
Change the dropdown at the bottom of the dialog to Update session defaults.
Close Beyond Compare, and then reopen it again by running the git dtd command.
All of the files in the Folder Compare session which contain nothing but an update to the timestamp will be shown with unimportant differences. If you want to completely hide files with unimportant differences, toggle off Ignore Unimportant Differences in the View menu.
Reference: https://www.scootersoftware.com/support.php?zz=kb_unimportantv3
I have a file of about 19500+ lines of code. I am doing work on this, and also my friend. We are not using SVN, Git or else.. Now i had done my changes.. How i merge my friends file in my file using Diff (or you suggest me) on some selected highlighted points. I want to ignore some changes from friend.
You can use KDiff3 to do the merge operation. By default it will accept the changes done by both of your, but you can interactively select which version you want. If the common base you both have been working with is named original.c, your version your.c and your friend's friend.c, then the command
kdiff3 -o out.c original.c your.c friend.c
will start an interactive merge where you can select which of the changes you want to have or not.
There are some files we want ignored, not tracked, by git, and we are having trouble figuring out how to do that.
We have some third-party C library which is unpacked and we have it in Git. But when you configure && make it, it produces many new files. How to write .gitignore to track source files and not the new stuff. (it's not like forbidding *.o)
Edit: There are at least 12 file-types. So we would like NOT to enumerate, which type we want and which not.
Use ! to include all the types of files you need. Something like in the following example"
*
!*.c
!*.h
Explicitly specifying which files should be tracked and ignoring all others might be a solution. * says ignore everything and subsequent lines specify files and directories which should not be ignored. Wildcards are allowed.
*
!filename
!*.extension
!directory/
!/file_in_root_directory
!/directory_in_root_directory
Remember that the order matters. Putting * at the end makes all previous lines ineffective.
Take a look at man gitignore(5) and search for !. It says
Patterns have the following format:
(...)
An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again. If a negated pattern matches, this will override lower precedence patterns sources.
I'm not sure why you say "it's not like forbidding *.o", but I think you mean that there aren't any good patterns you can identify that apply to the generated files but not to the source files? If it's just a few things that appear (like individual built executables that often don't have any extension on Linux), you can name them explicitly in .gitignore, so they aren't a problem.
If there really are lots and lots of files that get generated by the build process that share extensions and other patterns with the source files, then just use patterns that do include your source files. You can even put * in .gitignore if it's really that bad. This will mean that no new files show up when you type git status, or get added when you use git add ., but it doesn't harm any files that are already added to the repository; git will still tell you about changes to them fine, and pick them up when you use git add .. It just puts a bit more burden on you to explicitly start tracking files that you do care about.
I would make sure the repo is clean (no changes, no untracked files), run configure && make and then put the newly untracked filed into the ignore file. Something like git status --porcelain | fgrep '??' | cut -c4- will pull them out automatically, but it would be worth some eyeball time to make sure that is correct...
I need a shell script which will allow me to typeset Lilypond files from TextWrangler (A Mac App).
So far I have come up with this:
#!/bin/sh
/Applications/LilyPond.app/Contents/Resources/bin/lilypond -o $1
which, of course, doesn't work. (That's why I'm at Stack Overflow.)
When I run that script from the shebang menu in TextWrangler, I get this output:
/Applications/LilyPond.app/Contents/Resources/bin/lilypond: option faultpaper,
--output'' requires an argument
What gives?
I'm running Snow Leopard, TextWrangler, and Lilypond.
Help appreciated.
EDIT: Found a way to get the document path in a Unix Script launched by TextWrangler, so I've rewritten this.
There are multiple ways to work with scripts in TextWrangler through the #! menu, and I'm not sure which one you're trying to use. It looks, though, like you're trying to create a Unix Script to convert your LilyPond document.
As your error hints, Unix Scripts unfortunately aren't given any arguments at all, so $1 will be empty. However, it turns out that recent versions of BBEdit/TextWrangler do set some environment variables before running your script (see BBEdit 9.3 Release Notes and scroll down to Changes). In particular, you can use the following environment variable:
BB_DOC_PATH path of the document (not set if doc is unsaved)
So, save this script to ~/Library/Application Support/TextWrangler/Unix Support/Unix Scripts and you should be good to go.
Other ways you might be trying to do this that don't work well:
Using a Unix Filter: to do this you would have to select all of your LilyPond code in the document, and it would be saved into a temporary file, which is passed as an argument to your script. OK, so that gets you an input filename, at the cost of some hassle. But then the output of that script (i.e. the LiiyPond compiler output) by default replaces whatever you just selected, which is probably not what you want. Wrong tool for the job.
Using #! → Run on a LilyPond file: This involves putting a #! line at the top of your file and having TextWrangler attempt to execute your file as a script, using the #! as a guide to selecting the script interpreter. Unfortunately, the #! line only works with certain scripting languages, and LilyPond (not quite a scripting language) isn't one of them. This is what Peter Hilton is trying to do, and as he notes, you will get LilyPond syntax errors if you try to add a #! line to the top of a LilyPond file. (If you're curious, there is technically a way to get #! → Run to work, which is to embed your LilyPond code inside an executable shell or perl script, using here-document syntax. But this is a gross hack that will quickly become unwieldly.)
There are a few limitations to the script linked above:
It doesn't check to see whether you saved your document before running LilyPond. It would be nice to have TextWrangler automatically save before running LilyPond.
It can't take snippets of text or unsaved documents as input, only saved documents.
You can make more sophisticated solutions that would address these by turning to AppleScript. Two ways of doing this:
Create a script that's specific to TextWrangler and drop it in ~/Library/Application Support/TextWrangler/Scripts. It then shows up in the AppleScript menu (the weird scrolly S), or you can get at it by bringing up Window → Palettes → Scripts. I believe two folks out there have gone down this path and shared their results:
Henk van Voorthuijsen (Lilypond.applescript extracted from MacOS 10.5 Applescript for TextWrangler thread on lilypond-devel, 21-Jul-2008)
Dr Nicola Vitacolonna (LilyPond in TextWrangler – uses TeXShop).
Create a Mac OS Service, which would potentially be a method that would be reusable across just about any text editor. This was how we used to compile Common Music files way back in the NeXT days, so I can testify to its elegance. I don't have a good up-to-date example of this, unfortunately.
Good question. It actually runs Lilypond on my system if you do this:
#!/Applications/LilyPond.app/Contents/Resources/bin/lilypond -o $1
… but fails because # is not a line-comment character so Lilypond tries to parse the line.
Surrounding it with a block comment fails because TextWrangler cannot find the ‘shebang’ line.
%{
#!/Applications/LilyPond.app/Contents/Resources/bin/lilypond -o $1
%}
An alternative is to use Smultron 3, which lets you define commands that you can run with a keyboard shortcut.
I have a big named branch with a lot of changes. Some of these changes are non-destructive so I want to pick these specific files out first, and merge them with default as soon as possible. (Then later, the destructive changes are merged as well.)
In Git I would create another branch and squash all changesets outside of the index, then I would add the specific files to the index and commit. After that, I could merge this temporary branch with master so master has a clean commit with only the non-destructive change. I don't know how to do this with Mercurial.
You can use hg cat to grab the contents of a file as it exists on any particular branch, and replace the working copy version with that.
This isn't technically a merge, but since you're replacing whole files you shouldn't have too much of a bad time merging things later:
for example, to grab myfile.c form branch somefeature, and replace the working copy version, do:
hg cat path/to/myfile.c -r somefeature > path/to/myfile.c
note that this completely replaces the working copy file so make sure you have no outstanding changes first
I think mercurialqueues is what you want. With mq you can turn any changeset into a patch and any patch into a changeset. So taking a changeset converting it to a patch deleting the chunks out of the patch that you don't want and then applying it to whatever branch you want. This is a fairly complex operation though and requires a certain amount of discipline on your part. So I would try to nail down your workflow on a test repo before trying it on code you care about.
As far as I know, Mercurial doesnt any have tools to split changesets. If youre lucky, all the changes you want are in separate changesets and then you can use the TransplantExtension. I think it can be compared to Git's cherry-pick but I havent used git much.
You can also use hg diff to manually commit the changes to a certain file to a new branch. Use the rev range to mark your entire source branch:
hg diff myfile -r startrevision:endrevision
The output can be treated as a patch. Do this for each file you want and commit them and then merge. Skipping the destructive changes. You can also, of course, do this multiple times of a destructive change is in the middle of a revision range.
Having said that what youre trying to do isnt something mercurial was built for. That hardcore history editing is more Git's area (note that its just my opinion). Keep your stable changes and destructive changes in separate changesets (and maybe even in separate branches). I use transplant, rebase and strip to move changes around. When its all done, they are merged and properly pushed.
Oh, and check MercurialQueues. I havent used it myself but Ive seen it do some crazy stuff. Maybe its capable of doing something along the lines of what you want.