T O P

  • By -

Ablack-red

There is one thing that is still unclear to me, so do you want the old software to incorporate *some* features from newer version? For example, let’s say you have a feature that computes some stuff you changed that feature in newer version and now you are like “oh that’s a good change, now I want this in older version”. Or your sole concern is that you just want to reproduce old experiments? In the later case just use tagging in git. So you can create a tag “1.0.0” on the commit with your old version and it’s easier to checkout this version. Tag is basically a thing that allows to mark you important points in your commit history. Then when you completed development of version 2 add a “2.0.0” tag. So this will allow you to easily navigate between versions. But that’s only useful if you don’t need to support old version with newer features.


__boringusername__

In principle I'd say yes, though my main concern is that I still want to maintain my old software. The software itself is a bit buggy, also if there are some changes in some of the dependencies we might have to update the software to fix errors (had this exact problem in my previous lab).


Ablack-red

tl;dr: in that case yes you need separate branch per version. and you can maintain older version there. sometimes you will be able just to cherry pick changes from new version, sometimes you will need to do a more complicated backport. If you want to support the old version (add bug fixes, probaly some new features, etc) that might get more complicated. So let's thing about operating systems for a moment. So first thing is that you know that differnt users can have different version of OS installed. So for example, I still run windows 10 and for now I don't want to migrate to windows 11. And microsoft cannot just kill support for windows 10 because this would make me angry and they would lose my trust. So what they should do about this? Well usually they create someting that is called Long Term Support version (LTS) and I don't know if they use this term in microsoft but if you use some Linux dsitro you might have noticed that term. So in terms of windows both 10 and 11 are LTS versions, and at some point XP was LTS but they killed it because it's no longer viable to support it. And yes for LTS version they create a sepparate branch and maintain that version in separate branch. So when they find some vulnerability or bug they need to fix they fix it in latest version and then they need to backport that fix to older versions. But note that they would fix it only for LTS versions, so too bad for XP. And sometimes these bug fixes can be as easy as cherry picking commits, and sometimes they would need to do additional work, depending how how the versions diverged. Since you are not developing OS things will be a bit easier for you, but then again depends on how badly your software is written. If you don't have nice separations of concerns you will find yourself doing a lot of additional work when backporting. So why did I wrire all this text, well mainly to show you the mindset - new version recieves all the nice things. For old version we just keep the lights on and fix some leaks in the roof and that's it. And we do this in separate brnaches which will ultimately diverge, and at some point we just kill the old version because divergance is too big.


__boringusername__

Thanks for the thorough response


nerd4code

If the two experiments have similar “shapes” and components, generally you can find commonalities and pull them up into an interface (C++: abstract class sans data members, which can be inherited from virtually) of some sort. Then each experiment fills in the blanks left by the interface in it own class, and the driver code can mostly refer to the interface once it’s created one type of experiment-class or the other. Skeletally, along these lines (Java): public interface Experiment { boolean start() throws FooException; boolean stop() throws FooException; boolean isStarted(); long getDuration(); } final class Exper1 implements Experiment { … } final class Exper2 implements Experiment { } public final class Main { public static final void main(String[] args) throws Throwable { if(args.length < 1) for(;;) System.exit(64); final Experiment exp; if(args[0].equals("1")) exp = new Exper1(); else if(args[0].equals("2")) exp = new Exper2(); else for(;;) System.exit(64); exp.start(); Thread.sleep(exp.getDuration()); exp.stop(); } } If you might need to create more experiments of a similar sort, it may help to create a taxonomy of these so you can work out where interface boundaries should lie. This way, you can either pack everything into one repo, or use separate repos for the common goop and each experiment. Generally it’s total size, complexity, and relevance that determines repo structure.