Prevent change propagation for single files - perforce

I work with Perforce streams, following the suggested mainline model (release, mainline and development streams). In addition, we use a odd/even release version numbering (similar to linux kernel) with odd minor version numbers for development versions, even minor numbers for release versions.
After fixing a bug in a release stream, I need to update several files with version information to create a new release version/installer. These version changes must not be merged to mainline (only the bugfix itself), because the version of the mainline has been already increased to the next development version.
Now, when merging from the release stream to main, I get conflicts for all files containing version information. Currently, I need to manually resolve all conflicts, undoing the version number change (keeping the development version).
Example:
Release stream started with version 2.4.0 (stable/release version number)
Increase mainline version to 2.5 (next development version)
Fix bug in release stream, increase version number to 2.4.1
Merge changes to mainline: accept bugfix, manually undo conflicts in version files
Is there a way to exclude single files / a set of files from integration so that I don't have to go through this tedious (and potentially error-prone) manual process? (NB: The version information is separate from the code.)

Three possible options:
1) Specify these files as "isolate" in the stream spec so that changes to them are isolated, i.e. not included in copy/merge operations.
2) Merge the version changes but use "resolve -ay" (ignore) to specify that these changes are to be ignored.
3) Revert these files after opening them for a merge operation so that you will not need to resolve or submit them.

Related

Is this version a minor or major change?

I had new changes to my code. These changes use new Node 14 features, such as Optional Chaining. This has caused problems for clients running version 12 of Node.
Should this new version be major or not?
TL;DR: you almost certainly should have released that as a major version, yes.
As I see it, there are three possibilities, depending on the package's declared Node version support (usually included as $.engines.node in package.json):
You explicitly supported Node 12, and are now dropping that support.
This requires a major version change, your changes are not backwards-compatible. Steps to mitigate, assuming the current version is x.y.z:
Re-release the new version that uses incompatible syntax as (x+1).0.0;
Release a new version x.y.(z+1), reverting the changes to restore Node 12 compatibility, to get folks' builds passing again; and
Consider releasing x.(y+1).0, implementing the new functionality with backwards-compatible syntax (as Node 12 is still in LTS, see #3).
You explicitly didn't support Node 12.
This doesn't require a major version change. Nobody should have been using it with Node 12 to begin with and it's not really your fault they're now having problems.
That said, given that people apparently were using it with Node 12 (which is still in LTS, see #3), you may choose to support them by doing the steps in #1 anyway.
There was no/unclear explicit Node version support.
In the absence of an explicit support declaration, I would go back to Node's own support - Node 12 is still in LTS until the end of April 2022. Therefore I'd expect any actively maintained package that didn't specify otherwise to continue to support Node 12 usage too. You should therefore follow the mitigation steps in #1.
I would also consider being more explicit about what is required/supported, by adding the information mentioned above to the package file in all of the new releases (e.g. for the optional chaining in (x+1).0.0, per node.green, ">=14.0.0").
Finally I would note that you can use the latest syntax in your source code but still support older Node versions through transpilation, publishing code generated by e.g. Babel rather than the source code itself.

What is the fastest way to keep a subversion repository in sync for migrating to a new environment?

I'm attempting to migrate large subversion repositories from a system with subversion 1.6 to one with subversion 1.7. When I make the final sync, I can take downtime and simply use rsync, but I didn't choose this because I wanted the new repositories to be created/upgraded with version 1.7.
So I chose to use svnsync because it can pick up where it left off and because the repositories are not mounted on the same device. The only problem is for large repositories svnsync copy-revprops takes FOREVER, as it goes through every revision over again.
So my question is can I do one of:
Reduce the time it takes to do svnsync copy-revprops
Skip copy-revprops entirely
Use a faster method of incrementally syncing repositories from one version of subversion to another.
?
According to http://svnbook.red-bean.com/en/1.7/svn.ref.svnsync.c.copy-revprops.html:
Because Subversion revision properties can be changed at any time,
it's possible that the properties for some revision might be changed
after that revision has already been synchronized to another
repository. Because the svnsync synchronize command operates only on
the range of revisions that have not yet been synchronized, it won't
notice a revision property change outside that range. Left as is, this
causes a deviation in the values of that revision's properties between
the source and mirror repositories. svnsync copy-revprops is the
answer to this problem. Use it to resynchronize the revision
properties for a particular revision or range of revisions.
This means that you can choose to skip copy-revprops if the revision properties have not been changing. Even if you're not sure, there is no point in doing copy-revprops multiple times--once at the very end of all sync's will suffice.

What does the number following 'linux-2.6.38.' in the file names like linux-2.6.38.1.tar.xz and linux-2.6.38.2.tar.xz mean?

I wanted to download Linux kernel 2.6.38 source files from https://www.kernel.org/pub/linux/kernel/v2.6/
but the webpage listed linux-2.6.38.1.tar.xz, linux-2.6.38.2.tar.xz etc, as well as linux-2.6.38.tar.xz.
What's the relationship between them? Which file should I choose?
These number represents the kernel version/releases, and give us information about its stability. From here :
The first number denotes the kernel version. It is changed least
frequently, and only when truly major changes in the concept and the
code of the kernel occur. In fact, it has been changed only twice in
the history of the kernel: in 1994 with version 1.0 and in 1996 with
version 2.0.
The second number denotes the major revision of the kernel version. It
was formerly the case that even numbers indicated a stable release,
that is, one that was deemed fit for production use (i.e., use in a
non-experimental environment), such as 1.2, 2.4 or 2.6. Likewise, odd
numbers, such as 1.1 or 2.5, have historically represented development
releases. They were for testing new features and device drivers until
they became sufficiently stable to be included in a stable release.
However, this has changed starting with the Linux 2.6.x series, and
new feature development now takes place in the same revision number.
The third number indicates the minor revision of the kernel. It is
only changed when new features or new drivers are added.
The fourth number represents corrections, such as security patches and
bug (i.e., error) fixes.

Fast kernel recompile

I'm trying to automate the process of recompile a upgraded kernel. (I mean version upgrade)
What I do:
Backup the object files (*.o) with rsync
Remove the directory and make mrproper
Extract new source and patch
Restore object files with rsync
But I found it doesn't make sense. Since skip compiled things need to get a hash, this should removed it.
Question: What file do I need to keep? or it doesn't exists?
BTW: I already know ccache but it broke with a little config change.
You're doing it wrong™ :-)
Keep the kernel tree as-is and simply patch it using the appropriate incremental patch. For example, for 3.x, you find these patches here:
https://www.kernel.org/pub/linux/kernel/v3.x/incr/
If you currently have 3.18.11 built and want to upgrade to 3.18.12, download the 3.18.11-12 patch:
https://www.kernel.org/pub/linux/kernel/v3.x/incr/patch-3.18.11-12.xz
(or the .gz file, if you don't have the xz utilities installed.)
and apply it. Then "make oldconfig" and "make". Whatever needs to be rebuilt will be rebuilt.
However, it's actually best to not rely on the object file dependency mechanism. Who knows if something might end up not being rebuilt even though it should due to a bug. So I'd recommend starting clean every time with a "make clean" before applying the patch, even though it will rebuild everything.
Are you really in such a big need to save build time? If yes, it might be a better idea to configure the kernel ("make menuconfig") and disable all functionality you don't need (like device drivers for hardware you don't have, file systems you don't care about, networking features you will not use, etc.) Such a kernel that's optimized for my needs only takes about 3 or 4 minutes to build (normally, the full kernel with everything enabled would need over half an hour; or even more these days, it's been a very long time since I've built non-optimized kernels.)
Some more info on kernel patches:
https://www.kernel.org/doc/Documentation/applying-patches.txt
The incremental patch is a good way since it updates time stamps properly.
(GNU) Make use time stamps to identify rebuild so just keep the time stamps to avoid rebuild.
If we need rsync, we should use it with -t option.
Also for a patch doesn't have incremental patches, we can make it manually by comparing patched files.

Git/Linux: What is a good strategy for maintaining a Linux kernel with patches from multiple Git repositories?

I am maintaining a custom Linux kernel which is comprised of merged changes from a variety of sources. This is for an embedded system.
The chip vendor we are working with releases a board support package as a changes against a mainline kernel (2.6.31). I have since made changes to support our custom hardware, and also merged with the stable (2.6.31.y) kernel releases. I've also merged in bug fixes for a specific file system driver that we use, sometimes before the changes make it to the mainline kernel.
I haven't been very systematic about how I have managed the various contributing sources and my own changes. If the change was large I tended to merge; if it was small I tended to rebase the third party changeset on to my own. Generally speaking merge conflicts are rare, since most of my work affects drivers that are not in the mainline kernel anyway.
I'm wondering if there is a better way to manage all of this. One concern is that my changes are mixed in with merges. The history might look something like:
2.6.31 + board support package + my changes (1) + 2.6.31.12 changes + my changes (2) + file system driver update + my changes (3) + 2.6.31.14 changes + my changes(4) + ....
It worries me a bit that my changes are mixed in, sometimes on the other side of merges. Is there a better way to do this? In particular, is there a way to do this that will make life easier when I switch to a newer kernel?
I don't think it will be easy to clean up your current set-up, unless your history is reasonably short, but I would suggest this:
Set up a Master repository which has remotes set up for each of the other places that your code comes from -- the mainline kernel, patches, ...
Keep a separate branch specifically for the updates from your driver supplier.
When you fetch, the updates will not mess with your branches.
When you are ready to merge, merge into some kind of "release" branch. The idea is to keep each source separate from the others, except when it needs to be merged in. Base your changes off of this branch, merging/rebasing as necessary.
Here's a quick diagram which I hope is helpful:
mainline-\----------\-------------------------------\
\ \ /you---\---/-/ \
\release----\-/---/----/-/--------\-/ / --\-----
patches-----------------/---/ / /
/ /
driver-------------------------/--------------/
With so many branches, it is difficult to diagram effectively, but I hope that gives you an idea of what I mean. release holds the official code for your system, you holds your own modifications, driver holds patches from the driver supplier, patches holds patches from some other repo, and mainline is the mainline kernel. Everything gets merged into release, and you base your changes off of release but only interact by merging in each direction, not making changes directly to release.
I think the generally accepted best policy is
(a) patch sets
(b) topic branches
Topic branches are essentially the same but are regularly rebased onto mainline. Topgit is a known tool that makes handling topic branches 'easier' if you have a lot of them. Otherwise: plan ahead and limit the number of branches

Resources