I've tried it
(I know that's not quite the Greenspun quote)
Really, Git has a solution to this. If you insist that it doesn't without looking, you'll just keep re-inventing the wheel badly.
mercurial has a patch queue extension that married it and quilt, which was very easy to use
E.g.,
c0=$(git log --oneline ${base_ref0}..${deb_ref0} |
grep "^[^ ] The subject in question" |
cut -d' ' -f1)
c1=$(git log --oneline ${base_ref1}..${deb_ref1} |
grep "^[^ ] The subject in question" |
cut -d' ' -f1)
if [[ -z $c0 || -z $c1 ]]; then
echo "Error: commits not found"
else
diff -ubw <(git show $c0) <(git show c1)
fi
See also the above commentary about Gerrit and commit IDs.(Honestly I don't need commit IDs. What happens if I eventually split a commit in a patch series into two? Which one, if either, gets the old commit ID? So I just don't bother.)
People keep saying “just use Git commits” without understanding the advantages of the Quilt approach. There are tools to keep patches as Git commits that solve this, but “just Git commits” do not.
I rather suspect that "commit messages on changes to patches" is what Debian ended up with and back-justifies it.
Of course, I am not a Debian maintainer, so it's entirely possible I'm just missing the experience of it that would make me want "commit messages on changes to patches".
I’m not arguing against replacing Quilt, but it should be more than just Git. I haven’t done Debian packaging in a long time but apparently there are some Git-based tools now?
At Mozilla some developers used quilt for local development back when the Mozilla Suite source code was kept in a CVS repository. CVS had terrible support for branches. Creating a branch required writing to each individual ,v file on the server (and there was one for every file that had existed in the repository, plus more for the ones that had been deleted). It was so slow that it basically prevented anyone from committing anything for hours while it happened (because otherwise the branch wouldn’t necessarily get a consistent set of versions across the commit), so feature branches were effectively impossible. Instead, some developers used quilt to make stacks of patches that they shared amongst their group when they were working on larger features.
Personally I didn’t really see the benefit back then. I was only just starting my career, fresh out of university, and hadn’t actually worked on any features large enough to require months of work, multiple rounds of review, or even multiple smaller commits that you would rebase and apply fixups to. All I could see back then were the hoops that those guys were jumping through. The hoops were real, but so were the benefits.
So it's clearly a way better solution and it's disappointing that they still haven't switched to it after 20 years? I dunno what else to say...
I'd say that `quilt` the utility is pretty much abandoned at this point. The name `quilt` remains in the format name, but otherwise is not relevant.
Nowadays people that maintain patches do it via `gbp-pq` (the "patch queue" subcommand of the badly named `git-buildpackage` software). `gbp-pq switch` reads the patches stored in `debian/patches/`, creates an ephemeral branch on top of the HEAD, and replays them there. Any change done to this branch (new commits, removed comments, amended commits) are transformed by `gbp-pq export` into a valid set of patches that replaces `debian/patches/`.
This mechanism introduces two extra commands (one to "enter" and one to "exit" the patch-applied view) but it allows Debian to easily maintain a mergeable Git repo with floating patches on top of the upstream sources. That's impossible to do with plain Git and needs extra tools or special workflows even outside of Debian.
Rebase.
If you insist you can add Merge commits to bracket fast-forward pushes, but arguably there is no need, and especially so for something like Debian packages where the convention would be that Debian's patches are "always on top", so you can see them by doing `git log ${base}..${debian_release_branch}` for any release. (And what's the base? Whatever upstream branch/tag the Debian release is based on, but you can add more tags with a Debian naming convention to denote the bases.)
If your patches never touch the same files as others, I think it doesn't matter. But, IIRC, if patch A and patch B both touch file F, and the changes in patch A are in context for diffs of patch B, it always fails if patch A changes patch B's context, but since merging incorporates all changes at once, these separate context changes don't apply.
It's been a while, but it might be only when you need to manually resolve patch A, then you also have to manually resolve patch B even if you wouldn't have had to touch it in a merge scenario.
You're referring to having to do conflict resolution for each commit in the rebase series, as opposed to all at once for a merge. Either way if the upstream has added thousands of commits since the last time, you're in for no fun.
This is a case where Git could be better, but as I responded to u/gioele there exist tools that greatly help with the conflict resolution issue, such as this one that I wrote myself:
https://gist.github.com/nicowilliams/ea2fa2b445c2db50d2ee650...
which basically bisects to find the upstream commit that introduces a conflict with each commit in the rebase series.
This has one major advantage over merge workflow conflict resolution: you get the most post possible context for each manual conflict resolution you have to do! And you still get to have clean, linear history when you're done.
[0] https://gist.github.com/nicowilliams/ea2fa2b445c2db50d2ee650...
Merges would avoid those problems, but are harder to do if there are lots of conflicts, as you can't fix conflicts patch by patch.
Perhaps a workflow based on merges-of-rebases or rebase-and-overwrite-merge would work, but I don't think it's fair to say "oh just rebase".
Cherry picks preserve that Commit-Id. And so do rebases; because they're just text in a commit message.
So you can track history of patches that way, if you needed to. Which you won't.
(PS some team at google didn't understand git or their true requirements, so they wasted SWE-decades at that point on some rebasing bullshit; I was at least able to help them make it slightly less bad and prevent other teams from copying it)
> Which you won't.
Why not? Doesn't it make sense to be able to track the history of what patches have been applied for a debian package?
> Doesn't it make sense to be able to track the history of what patches have been applied for a debian package?
... no. Each patch has a purpose, which will be described in the commit message. Hopefully it does what it says it does, which you can compare with its current diff.
If it was upstreamed with minimal changes, then the diff is near-empty. Drop it.
If it was upstreamed with significant changes, then the diff will be highly redundant. Drop it.
If the diff appears to do what the commit message says it does, then it probably does what it says.
If the diff is empty, either it was upstreamed or you fucked up rebasing. Don't be negligent when rebasing.
Let's say you have these version tags upstream: foo-1.0.1, foo-1.1.0, foo-1.3.0, and corresponding Debian releases 1.0.1-0, 1.1.0-0, 1.1.0-1, 1.3.0-0, 1.3.0-1, and 1.3.0-2, and the same 3 patches in all cases, except slightly different in each case. Then to see the several different versions of these patches you'd just `git log --oneline foo-${version}..debian-${version}-${deb_version}`.
For example, it's trivial from a web browser with a couple of clicks to go and find out all the downstream changes to a package. For example to see how glibc is currently customized in debian testing/unstable you can just navigate this webpage:
https://sources.debian.org/src/glibc/2.42-6/debian/patches
If everything gets merged in the same git tree it's way harder. Harder but doable with a rebase+force push workflow, which makes collaboration way harder. Just impossible with a merge workflow.
As an upstream maintainer of several project, being able to tell at a glance and with a few clicks how one of my projects is patched in a distribution is immensely useful when bug reports are opened.
In a past job it also literally saved a ton of money because we could show legal how various upstreams were customized by providing the content of a few .debian.tar.gz tarballs with a few small, detached patches that could be analyzed, instead of massive upstream trees that would take orders of magnitude more time to go through.
How is this not also true for Git? Just put all the Debian commits "on top" and use an appropriate naming convention for your branches and tags.
> If everything gets merged in the same git tree it's way harder.
Yes, so don't merge, just rebase.
> Harder but doable with a rebase+force push workflow, which makes collaboration way harder.
No force pushes, just use new branch/tag names for new releases.
> Just impossible with a merge workflow.
Not impossible but dumb. Don't use merge workflows!
> As an upstream maintainer of several project, being able to tell at a glance and with a few clicks how one of my projects is patched in a distribution is immensely useful when bug reports are opened.
Git with a suitable web front-end gives you exactly that.
> In a past job it also literally saved a ton of money because we could show legal how various upstreams were customized by providing the content of a few .debian.tar.gz tarballs with a few small, detached patches that could be analyzed, instead of massive upstream trees that would take orders of magnitude more time to go through.
`git format-patch` and related can do the moral equivalent.
Please, please, stop the nonsense with the patch quilting -- it's really cumbersome, it adds unnecessary cognitive load, it raises the bar to contributions, it makes maintenance harder, and it adds _zero value_. Patch quilting is a lose-lose proposition.