diff for patching without renaming target file - diff

how do i create a standard patch using diff -u without using a different name for the "new" file?
when i submitted a patch for an Apache project, the committer advised that i don't need to rename the file when submitting patches. i can somewhat understand how this breaks patching since the name of the "new" file should somehow match the name of the patch target - however they can't be in the same directory with the same name.
is it okay (for ease of patching) to rename the "old" file, such that i should have used:
diff -u Source-old.java Source.java
instead of:
diff -u Source.java Source-new.java
?

Given an existing project 'a', copy whole project to 'b', make changes in 'b'. Generate diff between original directory and your copied directory.
E.g., checkout or download project to directory 'a', copy to 'b':
$ tree a
a
`-- dir
|-- Bar.java
`-- Foo.java
$ cp -r a b
$ tree b
b
`-- dir
|-- Bar.java
`-- Foo.java
Make changes to 'b' (and only 'b'):
$ diff -r -s a b
Files a/dir/Bar.java and b/dir/Bar.java are identical
Files a/dir/Foo.java and b/dir/Foo.java are identical
$ sed -i 's/Foo.*$/& \/* Change...*\//' b/dir/Foo.java
$ diff -ruN a b | tee a.patch
diff -ruN a/dir/Foo.java b/dir/Foo.java
--- a/dir/Foo.java 2012-08-02 18:41:39.444720785 -0700
+++ b/dir/Foo.java 2012-08-02 18:46:45.319932802 -0700
## -1,2 +1,2 ##
package dir;
-public class Foo {}
+public class Foo {} /* Change...*/
$ gzip a.patch
Another alternative is to store the original source in a temporary, local git repository, then use git's built-in diff to generate the patch. Or, better, if the original source is using git, then just clone the repo and work directly in the source tree itself, and (still) using git to generate the patch.

Related

GitHub - Remove a indexed file from "Languages" on first page

How can I remove this indexed HTML page, that are a documentation to one of the external librarys I use on my GitHub blob?
I have tried alot of diffrent commands, but don't find a way to remove this file from the GitHub Linguist indexer...
Here are the "Languages" that are indexed on the startpage:
[image] Languages on the startpage
The file that I want to exclude:
[image] HTML file that needs to be excluded
TestProject/wwwroot/lib/bootstrap-icons/docs/index.html
Code that I've tried to get it removed via ".attributes"-file in root-folder (the vendored, works... But not getting rid of this HTML-file... from the GitHub-Languages) :
### vendored:
TestProject/wwwroot/lib/* linguist-vendored
### documentations:
TestProject/wwwroot/lib/bootstrap-icons/* linguist-documentation
and tried:
TestProject/wwwroot/lib/bootstrap-icons/* -linguist-documentation
and this:
TestProject/wwwroot/lib/bootstrap-icons/docs/* linguist-documentation
and this:
TestProject/wwwroot/lib/bootstrap-icons/docs/* -linguist-documentation
and this:
TestProject/wwwroot/lib/* linguist-documentation
and this:
TestProject/wwwroot/lib/* -linguist-documentation
But I can't figure it out how to remove this file:
TestProject/wwwroot/lib/bootstrap-icons/docs/index.html
Please help me with the correct syntax to remove the file from being indexed as a Language in my GitHub repository, main branch. 🙂
You've got the right idea and the right Linguist overrides (either will do the trick). The problem is your path matching isn't quite right.
From the .gitattributes docs
The rules by which the pattern matches paths are the same as in .gitignore files (see gitignore[5]), with a few exceptions:
[...]
If we look in the .gitignore docs (emphasis is mine):
An asterisk "*" matches anything except a slash. The character "?" matches any one character except "/". The range notation, e.g. [a-zA-Z], can be used to match one of the characters in a range. See fnmatch(3) and the FNM_PATHNAME flag for a more detailed description.
Two consecutive asterisks ("**") in patterns matched against full pathname may have special meaning:
[...]
A trailing "/**" matches everything inside. For example, "abc/**" matches all files inside directory "abc", relative to the location of the .gitignore file, with infinite depth.
The files you're trying to ignore are in sub-directories of the paths you've specified so you need to either:
use TestProject/wwwroot/lib/** linguist-vendored to recurse, or
use TestProject/wwwroot/lib/bootstrap-icons/docs/* linguist-vendored to limit to this directory.
We can demonstrate this without even using Linguist thanks to git check-attr:
$ # Create a repo with just the one file
$ git init -q Test-Project
$ cd Test-Project
$ mkdir -p TestProject/wwwroot/lib/bootstrap-icons/docs/
$ echo "<html>" > TestProject/wwwroot/lib/bootstrap-icons/docs/index.html
$ git add -A
$ git commit -m 'Add file'
[main (root-commit) bed71b5] Add file
1 file changed, 1 insertion(+)
create mode 100644 TestProject/wwwroot/lib/bootstrap-icons/docs/index.html
$
$ # Add your initial override
$ git add -A && git commit -m 'attribs'
[main 7d0a0cf] attribs
1 file changed, 1 insertion(+)
create mode 100644 .gitattributes
$
$ # Check the attributes
$ git check-attr linguist-vendored TestProject/wwwroot/lib/bootstrap-icons/docs/index.html
TestProject/wwwroot/lib/bootstrap-icons/docs/index.html: linguist-vendored: unspecified
$ # So it doesn't have any effect.
$ # Now lets recurse
$ echo "TestProject/wwwroot/lib/** linguist-vendored" > .gitattributes
$ git add -A && git commit -m 'attribs'
[main 9007c34] attribs
1 file changed, 1 insertion(+), 1 deletion(-)
$ git check-attr linguist-vendored TestProject/wwwroot/lib/bootstrap-icons/docs/index.html
TestProject/wwwroot/lib/bootstrap-icons/docs/index.html: linguist-vendored: set
$ # Woohoo!!! It's work.
$ # Lets be specific to the docs dir
$ echo "TestProject/wwwroot/lib/bootstrap-icons/docs/* linguist-vendored" > .gitattributes
$ git add -A && git commit -m 'attribs'
[main a46f416] attribs
1 file changed, 1 insertion(+), 1 deletion(-)
$ git check-attr linguist-vendored TestProject/wwwroot/lib/bootstrap-icons/docs/index.html
TestProject/wwwroot/lib/bootstrap-icons/docs/index.html: linguist-vendored: set
$ # Woohoo!!! It's worked too
Some good troubleshooting from #lildude, shown that:
All the files was ignored correctly.
I had alot of CSHTML-files under my repository that was grouped as HTML+Razor (see this post on GitHub: GitHub linguist discussion ) .
When I clicked the "HTML"-link on startpage under language, it took me to: https://github.com/pownas/Test-Project/search?l=html
But the startpage under language was telling me that I had around 40% html from the HTML+Razor search: https://github.com/pownas/Test-Project/search?l=HTML%2BRazor

how to print the progress of the files being copied in bash [duplicate]

I suppose I could compare the number of files in the source directory to the number of files in the target directory as cp progresses, or perhaps do it with folder size instead? I tried to find examples, but all bash progress bars seem to be written for copying single files. I want to copy a bunch of files (or a directory, if the former is not possible).
You can also use rsync instead of cp like this:
rsync -Pa source destination
Which will give you a progress bar and estimated time of completion. Very handy.
To show a progress bar while doing a recursive copy of files & folders & subfolders (including links and file attributes), you can use gcp (easily installed in Ubuntu and Debian by running "sudo apt-get install gcp"):
gcp -rf SRC DEST
Here is the typical output while copying a large folder of files:
Copying 1.33 GiB 73% |##################### | 230.19 M/s ETA: 00:00:07
Notice that it shows just one progress bar for the whole operation, whereas if you want a single progress bar per file, you can use rsync:
rsync -ah --progress SRC DEST
You may have a look at the tool vcp. Thats a simple copy tool with two progress bars: One for the current file, and one for overall.
EDIT
Here is the link to the sources: http://members.iinet.net.au/~lynx/vcp/
Manpage can be found here: http://linux.die.net/man/1/vcp
Most distributions have a package for it.
Here another solution: Use the tool bar
You could invoke it like this:
#!/bin/bash
filesize=$(du -sb ${1} | awk '{ print $1 }')
tar -cf - -C ${1} ./ | bar --size ${filesize} | tar -xf - -C ${2}
You have to go the way over tar, and it will be inaccurate on small files. Also you must take care that the target directory exists. But it is a way.
My preferred option is Advanced Copy, as it uses the original cp source files.
$ wget http://ftp.gnu.org/gnu/coreutils/coreutils-8.21.tar.xz
$ tar xvJf coreutils-8.21.tar.xz
$ cd coreutils-8.21/
$ wget --no-check-certificate wget https://raw.githubusercontent.com/jarun/advcpmv/master/advcpmv-0.8-8.32.patch
$ patch -p1 -i advcpmv-0.8-8.32.patch
$ ./configure
$ make
The new programs are now located in src/cp and src/mv. You may choose to replace your existing commands:
$ sudo cp src/cp /usr/local/bin/cp
$ sudo cp src/mv /usr/local/bin/mv
Then you can use cp as usual, or specify -g to show the progress bar:
$ cp -g src dest
A simple unix way is to go to the destination directory and do watch -n 5 du -s . Perhaps make it more pretty by showing as a bar . This can help in environments where you have just the standard unix utils and no scope of installing additional files . du-sh is the key , watch is to just do every 5 seconds.
Pros : Works on any unix system Cons : No Progress Bar
To add another option, you can use cpv. It uses pv to imitate the usage of cp.
It works like pv but you can use it to recursively copy directories
You can get it here
There's a tool pv to do this exact thing: http://www.ivarch.com/programs/pv.shtml
There's a ubuntu version in apt
How about something like
find . -type f | pv -s $(find . -type f | wc -c) | xargs -i cp {} --parents /DEST/$(dirname {})
It finds all the files in the current directory, pipes that through PV while giving PV an estimated size so the progress meter works and then piping that to a CP command with the --parents flag so the DEST path matches the SRC path.
One problem I have yet to overcome is that if you issue this command
find /home/user/test -type f | pv -s $(find . -type f | wc -c) | xargs -i cp {} --parents /www/test/$(dirname {})
the destination path becomes /www/test/home/user/test/....FILES... and I am unsure how to tell the command to get rid of the '/home/user/test' part. That why I have to run it from inside the SRC directory.
Check the source code for progress_bar in the below git repository of mine
https://github.com/Kiran-Bose/supreme
Also try custom bash script package supreme to verify how progress bar work with cp and mv comands
Functionality overview
(1)Open Apps
----Firefox
----Calculator
----Settings
(2)Manage Files
----Search
----Navigate
----Quick access
|----Select File(s)
|----Inverse Selection
|----Make directory
|----Make file
|----Open
|----Copy
|----Move
|----Delete
|----Rename
|----Send to Device
|----Properties
(3)Manage Phone
----Move/Copy from phone
----Move/Copy to phone
----Sync folders
(4)Manage USB
----Move/Copy from USB
----Move/Copy to USB
There is command progress, https://github.com/Xfennec/progress, coreutils progress viewer.
Just run progress in another terminal to see the copy/move progress. For continuous monitoring use -M flag.

Is there a command to diff all the kept files in accurev?

I am new to accurev, used to use SVN earlier. I want to a get diff file consisting of all the changes in kept files in a given directory. I know ac diff -b <file>
gives diff in a file, but if I have many files and I want the diff of all the kept files in a given directory, is there a straight forward command to do this like svn diff?
You are going to need to create a script if you only want to diff kept files in a given directory. Basically you will run an 'accurev stat -k' -> parse output for given directory -> 'accurev diff -b'
On a *NIX machine the commands below work nicely.
The -k option to AccuRev's stat command says find the file with "(kept)" status. Using the -fal options to stat provides just the Depot relative pathway to the file. No addition filtering needed. So the command line would be:
accurev stat -k -fal | xargs accurev diff -b
Produces output like:
accurev stat -k -fal | xargs accurev diff -b
diffing element /./COPYING
341a342
> Tue Mar 18 08:38:39 EDT 2014
> Change for demo purposes.
diffing element /./INSTALL
3a4,7
> New Change
>
> Another Change
>
Dave

Mercurial: Converting existing folders into sub-repos

I have a Mercurial repository that looks like this:
SWClients/
SWCommon
SWB
SWNS
...where SWCommon is a a library common to the other two projects. Now, I want to convert SWCommon into a sub-repository of SWClients, so I followed the instructions here and here. However, in contrast to the example in the first link I want my sub-repository to have the same name as the folder had at the beginning. In detail, this is what I have done:
Create a file map.txt as follows
include SWCommon
rename SWCommon .
Create a file .hgsub as follows
SWCommon = SWCommon
Then run
$ hg --config extensions.hgext.convert= convert --filemap map.txt . SWCommon-temp
...lots of stuff happens...
Then
$ cd SWCommon-temp
$ hg update
101 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd ..
$ mv SWCommon SWCommon-old
$ mv SWCommon-temp SWCommon
$ hg status
abort: path 'SWCommon/SWCommon.xcodeproj/xcuserdata/malte.xcuserdatad/xcschemes/SWCommon.xcscheme' is inside nested repo 'SWCommon'
...which is indeed the case, but why is that a reason to abort? The other strange thing is that if I do not do that last 'mv' above and I execute an 'hg status' then, I end up with lots of 'missing' files in SWCommon as you would expect. The example in the link never makes it this far and basically stops on the hg update above? How do you make it work in practice?
Not currently possible. You could create a new repo converting the original one like:
$ hg --filemap excludemap.txt SWClients SWClients-without-SWCommon
With a excludemap.txt like:
exclude "SWCommon"
And then add the subrepo there.
$ hg --filemap map.txt SWCommon SWClients-without-SWCommon/SWCommon
$ cd SWClients-without-SWCommon
$ hg add SWCommon
$ hg ci -m "Created subrepo"
See the mailing list thread that discusses this problem.

How do I revert a big change in CVS?

One of my colleagues has totally messed up the contents of a directory in our main CVS repository. I need to just revert the whole module to the state it was in at the end of last year. What's the CVS command to do this please?
He has added and removed hundreds of files, so a simple "copy over files from old checkout and commit" isn't enough.
I have RTFM and STFW, and I tried this:
cvs co modulename # Note no -P option
cvs up -jHEAD -jMAIN:2008-12-30 modulename
But that doesn't work - the new files he created get removed, but the old files and directories don't get resurrected. (I didn't commit it).
I can probably write a shell script for this, but surely this functionality must be in CVS already?
Update: Some clarifications:
I can get a local checkout of the module at a specific date. The question is how to get that back into CVS.
I do have backups, but the point using of a revision control system like CVS is that it's supposed to be easy to get any historical state. Next time something like this happens I may not be lucky enough to have backups (e.g. backups are daily, so I may lose up to a day's work).
I know that CVS is old, and we should move to something newer. But in a large team with a large number of CVS-based tools (checkout & build scripts, nightly build server, etc) the time cost of such a move is considerable. (Evaluation, updating scripts, testing, migration, training, lost developer time, maintaining both systems in parallel as CVS would still be needed for old branches). Hence this has to be planned & scheduled by management.
Update #2: I'm going to start a bounty on this. To qualify for the bounty you have to explain how to revert using normal CVS commands, not with a hacky shell script.
Update #3: The server is CVS 1.12.13. Access is via pserver. I can use the same version of CVS on a Linux PC, or the CVSNT 2.0.51d client on Windows.
Actually your initial approach was very close to the solution. The problem is, that joining date-based does not handle removed files and directories correctly. You need to set a tag to the code base you want to join first:
mkdir code_base1 && cd code_base1
cvs co -D "2008-12-30" modulename
cvs tag code_base_2008_12_30
Now do the join tag-based, subtracting all changes between now and 2008-12-30:
cd .. && mkdir code_base2 && cd code_base2
cvs co modulename
cvs update -d -j HEAD -j code_base_2008_12_30 # use -d to resurrect deleted directories
Compare the contents of code_base1 and code_base2. They should be identical except for the CVS meta information. Finally commit the code as it was on 2008-12-30 as new HEAD:
cvs commit -m "Revert all changes this year"
Note that tagging the code you wish to join like this will not work, because rtag also does not handle removed files and directories correctly, when using -D:
cvs rtag -D "2008-12-30" code_base_2008_12_30 modulename
There are several problems with CVS and you're hitting them with such a problem.
CVS is file-oriented, no concept of a changeset or snasphot. That means that changes such as the one you want to revert are a bit difficult to handle. Commits are atomic within a given directory, not outside.
Directories are not versioned. That means that empty directories will be deleted (if you update with -P) and that you have to specify -d to create them on checkout/update.
So, to answer your question, dates are probably the only way to deal with because you didn't use tags to create some poor man's version of changeset.
My comment about backups is that it may be easier to recover the whole repo from backups than try to correct things that CVS is not really good at.
I would encourage you -- but that is another subject -- to change version control as soon as you can. Trust me, I've been dealing with CVS for a long time within the FreeBSD project and learn very quickly how hateful CVS is... See here for some of my views on version control software.
I believe your second command should also be a checkout, rather than an update. I can't justify this with logic, since there is no logic in the world of CVS, but it has worked for me. Try this:
cvs co -P modulename
cvs co -P -jHEAD -jMAIN:2008-12-30 modulename
If you're reverting a branch other than HEAD, e.g. X, pass the -rX argument in both commands:
cvs co -P -rX modulename
cvs co -P -rX -jHEAD -jMAIN:2008-12-30 modulename
I'm still interested to know if there's an easier way. (There must surely be an easier way). What I ended up doing was, on a Linux PC using bash:
# Get woking copy we're going to change
cd ~/work
rm -rf modulename
cvs up -dP modulename
cd modulename
# Remove all files
find . -name CVS -prune -o -type f -print | xargs cvs rm -f
# Get the old revision
cd ~
mkdir scratch
cd scratch
cvs -q co -D 2008-12-31 modulename
cd modulename
# Copy everything to the working dir and do "cvs add" on it
find . -name CVS -prune -o -type f -print | \
xargs tar c | \
(cd ~/work/modulename && tar xv | \
xargs cvs add)
# Check everything is OK before we commit
cd ~/work/modulename
cvs -nq up
# it gave me an error on readme.txt because I'd deleted and then added it, so:
mv readme.txt x # save good rev
cvs add readme.txt # resurrect the bad rev
mv x readme.txt # clobber file with good rev
# Commit it
cvs commit -m "Revert all changes this year"
# Delete now-empty directories
cvs -q up -dP
# Double-check everything is back how it was
diff -ur -xCVS ~/scratch/modulename ~/work/modulename
Then I discovered that there were still differences - my colleague had added filenames containing spaces, which weren't deleted by the above process. I had to delete those separately. (I should have used find ... -print0 rather than -print, and passed the -0 argument to xargs. I just didn't realise there were files with spaces.)
You could look into cvsps. Google it.
Also, with quilt (or Andrew Morton's patchscripts, which is what quilt started out as) and cvsps, a very close approximation of changesets can be had.
see http://geocities.com/smcameron/cvs_changesets.html
Have you tried using the -d option? (build subdirectories)
As far as I can remember, it's implied for cvs co, but not for cvs up.
According to http://www.astro.ku.dk/~aake/MHD/docs/CVS.html, the following is what you need:
cvs update -D "30 Dec 2008 23:59"
Big problem, don't have full answer, just a tip on your scripting to deal with spaces in file names.
Instead of
find ... | xargs tar c - | ...
try putting
find ... | perl -e '#names = <>;' -e 'chomp #names;' -e 'system( "tar", "c", "-", #names);' | ...
that way, your archive creation (or similar operations) won't suffer from spaces in the names, the shell argv parsing gets skipped before tar is called.
One more thing, on the off chance it actually works: if there is a CVS to SVN utility, use it (I am assuming such a utility would pull deleted files from the "CVS attic"), and if it saves each moment in time as a project level checkpoint (since SVN does that, unlike CVS), use SVN to fetch the right moment in time. Lot of ifs...
If you or a colleague are comfortable with git, you could use git cvsimport to create a git repository mirroring the CVS repository. Reverting a commit/changeset in git is trivial (using git revert). You could then use git cvsexportcommit to send the revert commit to CVS.
This might all sound overly complicated, but in my experience git cvsimport and git cvsexportcommit work really well once you've got everything set up. You end up with all the power of git personally even though the project is still using CVS.
If you have a backup of your repository (the actual RCS files on the server, e.g. on tape) you could just restore that folder on the CVS server to the state it was before. Don't forget to stop the CVS server before doing this (and restart it afterwards).