Suppose, not entirely hypothetically, that you've made local changes to an Ubuntu package on one Ubuntu release, such as 22.04 ('jammy'), and now you want to move to another Ubuntu release such as 24.04 ('noble'). If you're working with straight 'apt-get source' Ubuntu source packages, this is done by tediously copying all of your patches over (hopefully the package uses quilt ) to duplicate and recreate your 22.04 work.
If you're using dgit , this is much easier. Partly this is because dgit is based on Git, but partly this is because dgit has an extremely convenient feature where it can have several different releases in the same Git repository. So here's what we want to do, assuming you have a dgit repository for your package already .
(For safety you may want to do this in a copy of your repository. I make rsync'd copies of Git repositories all the time for stuff like this.)
Our first step is to fetch the new 24.04 ('noble') version of the package into our dgit repository as a new dgit branch, and then check out the branch:
dgit fetch -d ubuntu noble,-security,-updatesdgit checkout noble,-security,-updates
We could do this in one operation but I'd rather do it in two, in case there are problems with the fetch.
The Git operation we want to do now is to cherry-pick ( also ) our changes to the 22.04 version of the package onto the 24.04 version of the package. If this goes well the changes will apply cleanly and we're done. However, there is a complication. If we've followed the usual process for making dgit-based local changes , the last commit on our 22.04 version is an update to debian/changelog. We don't want that change, because we need to do our own 'gbp dch' on the 24.04 version after we've moved our own changes over to make our own 24.04 change to debian/changelog (among other things, the 22.04 changelog change has the wrong version number for the 24.04 package).
In general, cherry-picking all our local changes is 'git cherry-pick old-upstream..old-local'. To get all but the last change, we want 'old-local~' instead. Dgit has long and somewhat obscure branch names; its upstream for our 22.04 changes is 'dgit/dgit/jammy,-security,-updates' (ie, the full 'suite' name we had to use with 'dgit clone' and 'dgit fetch'), while our local branch is 'dgit/jammy,-security,-updates'. So our full command, with a 'git log' beforehand to be sure we're getting what we want, is:
git log dgit/dgit/jammy,-security,-updates..dgit/jammy,-security,-updates~git cherry-pick dgit/dgit/jammy,-security,-updates..dgit/jammy,-security,-updates~
(We've seen this dgit/dgit/... stuff before when doing 'gbp dch'.)
Then we need to make our debian/changelog update. Here, as an important safety tip, don't blindly copy the command you used while building the 22.04 package, using 'jammy,...' in the --since argument, because that will try to create a very confused changelog of everything between the 22.04 version of the package and the 24.04 version. Instead, you obviously need to update it to your new 'noble' 24.04 upstream, making it:
gbp dch --since dgit/dgit/noble,-security,-updates --local .cslab. --ignore-branch --commit
('git reset --hard HEAD~' may be useful if you make a mistake here. As they say, ask me how I know.)
If the cherry-pick doesn't apply cleanly, you'll have to resolve that yourself. If the cherry-pick applies cleanly but the result doesn't build or perhaps doesn't work because the code has changed too much, you'll be using various ways to modify and update your changes . But at least this is a bunch easier than trying to sort out and update a quilt-based patch series.
Appendix: Dealing with Ubuntu package updates
Based on this conversation , if Ubuntu releases a new version of the package, what I think I need to do is to use 'dgit fetch' and then explicitly rebase:
dgit fetch -d ubuntu
You have to use '-d ubuntu' here or 'dgit fetch' gets confused and fails. There may be ways to fix this with git config settings, but setting them all is exhausting and if you miss one it explodes, so I'm going to have to use '-d ubuntu' all the time (unless dgit fixes this someday).
Dgit repositories don't have an explicit Git upstream set, so I don't think we can use plain rebase . Instead I think we need the more complicated form:
git rebase dgit/dgit/jammy,-security,-updates dgit/jammy,-security,-updates
(Until I do it for real, these arguments are speculative. I believe they should work if I understand 'git rebase' correctly, but I'm not completely sure. I might need the full three argument form and to make the 'upstream' a commit hash.)
Then, as above, we need to drop our debian/changelog change and redo it:
git reset --hard HEAD~gbp dch --since dgit/dgit/jammy,-security,-updates --local .cslab. --ignore-branch --commit
(There may be a clever way to tell 'git rebase' to skip the last change, or you can do an interactive rebase (with '-i') instead of a non-interactive one and delete it yourself.)