Which means distributing a modified program as patches? - patch

I've read articles from the GNU project about open-source and other licenses. Some licenses allow you to post your changes as patches, not complete source code (for example Q Public License or gnuplot license). What does it mean? What do such patches look like? Can you get an example?
I do not want to focus on the legal situation, but on the programming - general definition, etc.

A patch is the result of a diff between a reference source tree (typically the original version of a project) and your modified version.
It's typically obtained with the POSIX diff command. But nowadays, with the ubiquitous use of versioning tools like SVN, Mercurial or git, the patch is generally generated with these tools (svn diff, hg diff, git diff, etc.)
On the receiver end, the patch is typically applied with the POSIX patch command.
Here is an example. Let's suppose you are working on a project (the orig_version directory below). Before making any change, you wisely create a copy of it (the my_version directory below) and modify a file from the copy:
cp -a orig_version my_version
# Change "This is the original version"
# ... to "This is my modified version"
$ vi my_version/README.txt
Let's see the differences:
$ diff -ruN orig_version my_version
diff -ruN orig_version/README.txt my_version/README.txt
--- orig_version/README.txt 2021-02-16 10:53:05.303423169 +0100
+++ my_version/README.txt 2021-02-16 10:53:00.243495007 +0100
## -1 +1 ##
-This is the original version
+This is my modified version
# Rredirect this output so as to
# create a patch file we can send
$ diff -ruN orig_version my_version > /tmp/my.patch
The output above shows the difference between the two directory trees. We have put that difference in a file that we can later send (e.g. by mail) to someone else who will then be able to take a look at the changes and apply them with patch:
# First we create a copy of our project
$ cp -a orig_version test_version
$ cd test_version
$ cat README.txt
This is the original version
# Then we apply the patch
$ patch -p1 < /tmp/my.patch
patching file README.txt
# Let's see the result
$ cat README.txt
This is my modified version
Note: since we are in the test_version directory, we used the -p1 option so that patch ignores the first element of the file paths found in the output of diff (--- orig_version/README.txt becomes --- README.txt, same for the +++ line).
25 years ago, people used to send and receive patches by mail and apply them like I just shown. Today, with the advent of distributed version control systems and of websites like Bitbucket and Github, people clone repositories, use their tool to pull the last changes, to get a diff, to push their changes and they send pull requests instead of sending patches by mail.

Related

Prompt theme with Git support marking a number after a questionmark

I'm using Ubuntu on WSL2, having installed powerlevel10k on oh-my-zsh.
What is that weird question-mark-number next to the git branch name, what does it mean?
You have 1 untracked file in your repo. Do git status --short and you'll see the same symbol.
Most of the other symbols used by P10k, however, are unfortunately different from the ones used by git status (or other prompts; see below). See the P10k documentation for an overview. As you can see, it uses a lot of Unicode symbols, whereas git status restricts itself to ASCII symbols.
The majority other Git prompt themes out there, however, use yet an another, entirely different set of symbols, based on those defined in git-prompt.sh, which is distributed with git itself. These, too, are restricted to ASCII symbols. Here’s an overview of them:
Symbol
Meaning
*
unstaged
+
staged
$
stash
%
untracked files
<
behind
>
ahead
<>
diverged
=
no difference
|
operation in progress
?
sparse checkout
In any case, when in doubt, check your prompt theme's documentation.

Do not re-create repositories after updating

We manage systems and thus manage repositories. We remove repositories which we do not use, present in /etc/yum.repos.d/<file>
Our problem is: after an update/upgrade of the system, CentOS automatically re-creates the repositories which were removed, which is an issue for us.
Question: Is there a command / method to ensure repositories are not re-created after an upgrade on CentOS 7 systems.
Those repositories are created by someone, the OS doesn't recreate them.
Either they are restored by an update of a RPM package such as centos-release or by an automatic script you setup/run (ansible?).
I'm not aware of an automatic method to delete a repo; I see a couple of solutions:
Exclude centos-release from the upgradable packages, by adding
exclude=centos-release
to /etc/yum.conf (space separated list), but this could break some updates;
Disable them with:
# yum-config-manager --disable base,updates,extras,centosplus,epel,whatever
(this can be easily scripted and put in a cron or in your ansible playbook)
Write a small script and place it in /etc/cron.hourly/, e.g. /etc/cron.hourly/wipe_repos, containing:
#!/usr/bin/env bash
rm -f /etc/yum.repos.d/CentOS-Base.repo
or, better:
#!/usr/bin/env bash
yum-config-manager --disable base,updates,extras,centosplus,epel,whatever
I would suggest to use solution 2, since the repo files aren't overwritten by updates, but the new versions are placed along the old in .rpmnew files.
This is guaranteed by the flag %config(noreplace) in the source rpm of centos-release, applied to all files in /etc/yum.repos.d/.
You can check this by downloading the .src.rpm and opening the centos-release.spec file.
$ mkdir test && cd test
$ yumdownloader --source centos-release
$ rpm2cpio centos-release*.rpm | cpio -idmv
$ cat centos-release.spec
(or search for the package online and download the src.rpm)
Then scroll down to section %files and you'll notice:
%config(noreplace) /etc/yum.repos.d/*
%config(noreplace) means that all those files are not replaced with new files from an update, but the files from the new rpm are saved with the extension .rpmnew, so you'll have:
$ ls /etc/yum.repos.d/
CentOS-Base.repo <-- here you set them as disabled
CentOS-Base.repo.rpmnew <-- this comes from the update, but yum will ignore it
For reference, see http://people.ds.cam.ac.uk/jw35/docs/rpm_config.html or https://serverfault.com/a/48819/.
As I already said in the comments below the question, the reason why those repositories keep reappearing after an update is quite simple: the files defining the system repositories are owned by the package centos-release and whenever this package gets updated or reinstalled, the repositories reappear.
The package centos-release is a very basic package, it provides the capabilities redhat-release and system-release, and a number of other basic packages depend on it.
[local ~]$ rpm -q --provides centos-release
centos-release = 7-6.1810.2.el7.centos
centos-release(upstream) = 7.6
centos-release(x86-64) = 7-6.1810.2.el7.centos
config(centos-release) = 7-6.1810.2.el7.centos
redhat-release = 7.6-1
system-release = 7.6-1
system-release(releasever) = 7
[local ~]$ rpm -q --whatrequires system-release
setup-2.8.71-10.el7.noarch
grubby-8.28-25.el7.x86_64
[local ~]$ rpm -q --whatrequires redhat-release
initscripts-9.49.46-1.el7.x86_64
systemd-219-62.el7_6.5.x86_64
There is no easy way out of this.
But one possible solution might be to create a customized RPM package to replace centos-release. It should contain the pointers to your own repositories and of course needs to provide the capabilities redhat-release and system-release.
Please be aware that I have no idea if this is actually going to work, it's just something that came to my mind while thinking about the problem. It might save you the work of creating a full custom distribution derived from CentOS, which is the only other way I can think of to achieve what you seem to want.
My solution doesn't exactly solve the problem you request ("how do I delete default repository config files forever?"), but it does stabilize your config changes. If you zero out the files instead of deleting them, then system updates will leave your 'edited' versions unchanged.
I do feel that this is a 'hack', leaving named ghost files, but it's one I can live with. No need to disable or customize redhat-release or system-release.
My problem was slightly different than yours - I maintained different configs for the same repositories for different situations, indicated by filename. On updates the original files would return, leaving me with redundant and incorrect definitions. Now they don't.

SVN Getting The Count Of Revisions Of A Repository

I am curently working on a Qt c++ project that is basically printing all the commit log messages between a specific SVN Repository's 2 specific revision's (User enters the repo and the revisions).
I need to get the count of revisions in a repo URL.
I want to do this on Windows 10 so I guess a batch command could be pretty useful.
I am using Visual SVN Server and Tortoise SVN.
(My Qt version is 5.11.1 if it would be necessary)
I have a batch script that does print all the logs between 2 specific revisions to a .txt file.
It is like this:
#ECHO OFF
REM This Script Takes all the logs between a given repository's 2 specific revision.
REM Below, we store the first parameter which is the URL of the Repository that is wanted.
SET urlOfRepository=%1
REM Below, we store the second parameter which is the first revision that is wanted.
SET firstRevision=%2
REM Below, we store the third parameter which is the second revision that is wanted.
SET secondRevision=%3
REM Below is the command for getting all the log messages between the first and the second revision that is wanted in the wanted repository and printing to a .txt file.
svn log -r %firstRevision%:%secondRevision% --limit %secondRevision% %urlOfRepository% > svnLog.txt
EXIT /B 0
I would be glad if someone can help me.
I can clarify the question more if it is needed so please do not hesitate to contact me via comments.
Thanks in advance.
Thanks to Kostix the answer is:
svn info -r HEAD --show-item revision %URL%
And I have written a script to solve my problem. Here it is:
#ECHO OFF
REM This Script writes the revision count of a specific SVN repository
REM Below, we store the first parameter which is the URL of the Repository that is wanted.
SET urlOfRepository=%1
REM Below, is the command that returns the count of revisions in the specifically given SVN repository and writes to a .txt file
svn info -r HEAD --show-item revision %urlOfRepository% > svnCountOfRepoRevisions.txt
EXIT /B 0
There's no need to do it that complicated—a mere
svn log -r HEAD:1 %URL%
should work.
The special HEAD revision is automatically the last one in the repository, and the revision 1 is the first one (obviously).
Subversion is smart enough to skip revisions in which the URL does not
exist, so, say, if it was added in revision 42, svn log won't complain there is no URL in the revision range [41…1].
You can obtain more info by running
svn help log
in your console window.

How to re-order dependent changes in darcs?

In darcs, what if I want to re-order to the top (or just throw away) a patch which other patches depend on (i.e., change the same file)?
In git, I'd simply do a git rebase -i <UNTOUCHED-REVISION> and reorder or throw away some changes; then git would in a dumb fashion try to apply the old changes to the new variant of the tree one by one, and ask me to resolve the arising conflicts.
In darcs, I see no way to force it to ignore the dependencies between patches. If I obliterate or suspend (or unrecord) a patch which other patches depend on, darcs refuses to do it. (Because it wants to behave in a clever manner.)
I had the following plan to do this:
suspend the dependent patches (those which depend on the patch
which I want to re-order or throw away).
somehow unrecord the patch to re-order and save it somewhere else
(perhaps in another "darcs branch", i.e., a copy of the repo) and revert
the changes to the working directory so that the working directory is
clean.
after that, unsuspend the suspended patches up to the state
where I want to insert the re-ordered patch. (Resolving all arising conflicts.)
apply the saved patch (perhaps, by pulling from the saved "branch",
i.e., the copy of the darcs repo which I have saved on step 2).
unsuspend all remaining patches. (Resolving all arising conflicts.)
Here are some notes on how all this has proceeded.
1. suspend the dependent patches
If among the patches dependent on the patch you want to re-order there
is a single "minimal" one (according to the graph of dependencies),
then you simply give the command to suspend it (and after that there
will be no "active" patches which would depend on the re-ordered
patch):
darcs suspend -h <MINIMAL-DEPENDENT-HASH>
(and confirm the suspension of all other dependent patches).
Of course, if there are several minimal dependent patches, you have to
suspend each (each's subgraph will be asked for suspension).
2. save and revert the unwanted changes
Preparation
First, I look at the changes I'm going to work with:
darcs diff -h 61fbb4aeac9e69cf30d232eda274c18194d7a8d9 --diff-command='emacs -f ediff-directories-with-ancestor-command %1 %2'
(The change was logically simple, but diff showed it in a
complicated way, so, here, I launched Emacs's ediff via a special
function I had written for this purpose.)
I saw that the change included some cleanup and the addition of a new
feature. So, the plan is now to split it: unrecord the patch, and record two
patches instead.
darcs unrec -h 61fbb4aeac9e69cf30d232eda274c18194d7a8d9
Now, I can view and (perhaps, work) with the changes with ediff, too.
darcs diff --diff-command='emacs -f ediff-directories-with-ancestor-command %1 %2'
First, I record the cleanup patch (selecting and editing only the
relevant hunks). Then, the added action:
darcs rec -m 'examples/Process.hs: code cleanup (present as a sequence of actions and error handling)'
darcs rec -m 'examples/Process.hs: print the C program (from the AST) after the check (as gcc -E does)'
Saving as a patch (a variant)
One could use darcs obliterate -o or -O to save the obliterated
change, and then restore it with darcs apply (according to that advice).
But I proceeded differently:
Saving as a branch (a variant)
Cloning didn't work for a repo with suspended patches:
~/TOOLS/prog/language-c $ darcs clone . ../language-c_printAST
darcs failed: Can't clone a repository with a rebase in progress
~/TOOLS/prog/language-c $
So, let's make a copy (and check whether we would be allowed to pull
from it):
~/TOOLS/prog/language-c $ cp -a ../language-c ../language-c_printAST
~/TOOLS/prog/language-c $ darcs pull ../language-c_printAST
darcs failed: Incompatibility with repository /home/imz/TOOLS/prog/language-c_printAST:
Cannot transfer patches from a repository where a rebase is in progress
~/TOOLS/prog/language-c $ cd ../language-c_printAST/
~/TOOLS/prog/language-c_printAST $ darcs rebase obliterate
<...>
Really obliterate all undecided patches? y
Rebase finished!
~/TOOLS/prog/language-c_printAST $ cd ../language-c
~/TOOLS/prog/language-c $ darcs pull ../language-c_printAST
HINT: if you want to change the default remote repository to
/home/imz/TOOLS/prog/language-c_printAST,
quit now and issue the same command with the --set-default flag.
No remote patches to pull in!
~/TOOLS/prog/language-c $
Ok, good, so we will pull from that repo later.
Revert the changes
Throw away the unwanted (or re-ordered) patch:
darcs obliterate
3. Unsuspend the patches that should come before it
It's a good idea to make a backup copy of the repo at this point, because you
might screw something up during the unsuspending and resolving conflicts.
Unsuspend the patches that should come before it. (Unfortunately,
external merge tool is not supported in unsuspend.) It's better to
unsuspend them one by one as you'll have to resolve the conflicts
caused by each one and amend the patch:
darcs rebase unsuspend
# resolve conflicts
darcs amend
# repeat for the remaining patches you want to have
4. Apply the saved patch
darcs pull ../../language-c_printAST
# resolve conflicts
darcs amend
5. Unsuspend all remaining patches.
(Again, it's better to do this one by one.)
darcs rebase unsuspend
# resolve conflicts
darcs amend
# repeat for the remaining patches you want to have
(For some reason, on the first attempt, I lost a hunk in the last
unsuspended patch. But I repeated everything in a copy of the backup
copy, and there I reached the wished final state.)

How to create MacOS/Linux link for reading data file?

I have a huge raw data file which I do not intend to change or copy. And I have two projects in RStudio and both need to be able to access it.
I originally created the alias (in MacOS) in the following way
right click the file ~/A/data.csv in finder, and click "make alias". Then copy the alias to ~/B/ and rename it ~/B/data.csv
I also tried the following command later
ln -s ~/A/data.csv ~/B
For project A, I put the actual data file in A/data/data.csv.
For project B, I created an alias under B/data/.
But when I try fread('B/data/data.csv'), it complains:
sh: ./data/data.csv: Too many levels of symbolic links
Error in fread("./data/data.csv") :
File is empty: /var/folders/4h/2jg64xk52mv3fyq4sb7s371w0000gn/T//Rtmp7cWNN3/filebf3013ad9194
I think I can use a hard link to solve this issue, but just want to see if I can use alias to make it work.
=====
I don't think it matters, but for completeness, see the following for my OS and R version:
platform x86_64-apple-darwin10.8.0
arch x86_64
os darwin10.8.0
system x86_64, darwin10.8.0
status
major 3
minor 1.0
year 2014
month 04
day 10
svn rev 65387
language R
version.string R version 3.1.0 (2014-04-10)
nickname Spring Dance
I'm not entirely sure why using aliases in this specific case:
note that for small files (e.g. < 1 MB), the alias can have a way bigger memory footprint. For example, for a simple text file containing "test" (echo "test" > test.txt) the alias will be 274k times bigger:
test.txt: 5 bytes
test.txt alias: 1372636 bytes
since RStudio is good at using absolute paths, why not directly link to ~/A/data.csv directly rather than linking to it's alias?
Two alternative solutions (not directly answering question) could be to (1) copy the file or (2) create a kind of symbolic link.
Copying the file
#!/bin/bash
mkdir ~/B/data/
cp ~/A/data.csv ~/B/data/
Or in R, using system (on Mac):
system("mkdir ~/B/data/")
system("cp ~/A/data.csv ~/B/data/")
Creating a symbolic link
This can be done by simply saving the path of the file ~/A/data.csv in ~/B/data/.
In shell:
#!/bin/bash
mkdir ~/B/data/
echo "~/A/data.csv" > ~/B/data/data.csv
(this part can be also done in R using system() as above)
And then, in R:
## Reading path in B/data/
PATH <- scan(file = "~/B/data/data.csv", what = character())
## Opening the file (~/A/data/data.csv)
my_csv <- read.csv(PATH)

Resources