Package: gitpkg Version: 0.21 Severity: wishlist Hi Ron;
Here is the script we discussed on IRC to allow selective export of git commits as quilt patches, either interactively or as part of a git hook. The advantage over the existing scheme is that this supports patches that are already merged into to the packaging/integration branch. Probably it is a bit rough around the edges (e.g. the man page is a bit user-hostile), but hopefully we can use this bug to track discussion and whip it into shape. David -- System Information: Debian Release: wheezy/sid APT prefers testing APT policy: (900, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.2.0-1-amd64 (SMP w/8 CPU cores) Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages gitpkg depends on: ii dpkg-dev 1.16.1.2 ii git 1:1.7.9.1-1 gitpkg recommends no packages. Versions of packages gitpkg suggests: ii devscripts 2.11.4 -- no debconf information
>From 78ed58fee095218ed7683ac121177c66ae9c0a57 Mon Sep 17 00:00:00 2001 From: David Bremner <brem...@debian.org> Date: Mon, 5 Mar 2012 12:17:46 -0400 Subject: [PATCH] git-debpatch: select commits to be exported as quilt patches This script allows the user to mark commits for export as quilt-patches in debian/patches. gitpkg support is provided via hooks/quilt-patches-deb-export-hook. --- git-debpatch | 127 +++++++++++++++++++++++++++++++++++ git-debpatch.1 | 83 +++++++++++++++++++++++ gitpkg.1 | 3 +- hooks/quilt-patches-deb-export-hook | 3 + 4 files changed, 215 insertions(+), 1 deletions(-) create mode 100755 git-debpatch create mode 100644 git-debpatch.1 diff --git a/git-debpatch b/git-debpatch new file mode 100755 index 0000000..6a20fc1 --- /dev/null +++ b/git-debpatch @@ -0,0 +1,127 @@ +#!/bin/bash + +GN="git notes --ref debpatch" +patch_dir=debian/patches + +# get_field ref Field +# +function get_field() { + ${GN} show $1 2>/dev/null | sed -n "s/^$2: \(.*\)$/\1/p" +} + +# set_field ref Field Val +function set_field() { + other_fields=$(${GN} show $1 2>/dev/null | grep -v "^$2: ") + printf "$2: $3\n$other_fields" | ${GN} add -f -F- $1 2>/dev/null +} + +# remove_field ref Field +function remove_field() { + other_fields=$(${GN} show $1 2>/dev/null | grep -v "^$2: ") + if [ -n "$other_fields" ] ; then + printf "$other_fields" | ${GN} add -f -F- 1>/dev/null + else + $GN remove $1 2>/dev/null + fi +} + +function is_exportable() { + [ $(get_field $1 Export)x = "truex" ] +} + +function export_one_patch() { + if [ -f $patch_dir/series ]; then + count=$(wc -l "$patch_dir/series" | cut -f1 -d' ') + else + mkdir -p "$patch_dir" || exit 1 + echo "# exported from git by git-debpatch" > "$patch_dir/series" + count=1 + fi + + name=$(git format-patch --start-number $count -1 -o "$patch_dir" $1) + echo "$name" | sed -e "s,$patch_dir/,,g" -e 's, ,\n,g' >> "$patch_dir/series" +} + +function print_status() { + if is_exportable $1; then + printf "E\t" + else + printf "\t" + fi + printf "%7.7s\t" $1 + printf "%0.30s" "$(git --no-pager log --format="%s" -1 $1)" + printf "\t%s\n" $(get_field $1 Forwarded) +} + +function do_one_commit() { + case $1 in + export) + set_field $2 Export true + ;; + noexport) + remove_field $2 Export + ;; + forwarded) + set_field $2 Forwarded $3 + ;; + noforwarded) + remove_field $2 Forwarded + ;; + status) + print_status $2 + ;; + toquilt) + if is_exportable $2; then + export_one_patch $2 + fi + ;; + *) + echo "Unknown operation $1" + exit 1; + esac +} + + +case $1 in + fetch) + remote=${2-origin} + git fetch $remote refs/notes/debpatch:refs/notes/remotes/$remote/debpatch + exit 0; + ;; + merge) + remote=${2-origin} + ${GN} merge --strategy=cat_sort_uniq refs/notes/remotes/$remote/debpatch + exit 0; + ;; + pull) + git debpatch fetch $2 && git debpatch merge $2 + exit $? + ;; + push) + remote=${2-origin} + git push $remote refs/notes/debpatch:refs/notes/debpatch + exit 0; + ;; + status|export|noexport|toquilt|forwarded) + if [ -z $2 ]; then + echo "$1 needs a ref or a range" + exit 1 + fi + ;; + *) + echo "Unknown operation $1" + exit 1; +esac + +case $(git rev-parse $2 | wc -l) in + 1) + do_one_commit $1 $2 $3 + ;; + 2) + git rev-list --ancestry-path --reverse $2 | \ + while read hash ; do do_one_commit $1 $hash $3; done + ;; + *) + echo "Internal error." + exit 1; +esac diff --git a/git-debpatch.1 b/git-debpatch.1 new file mode 100644 index 0000000..5af4af3 --- /dev/null +++ b/git-debpatch.1 @@ -0,0 +1,83 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH GIT-DEBPATCH 1 "March 5, 2012" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +git\-debpatch \- annotate and optionally export commits +.SH SYNOPSIS +.B git\-debpatch +.RI [ command ] " ref-or-range " [ params ] + +.SH DESCRIPTION +This program uses the \fBgit-notes\fP(1) facility to track certain +metadata about git commits, and optionally export them as quilt patches. + +.SH COMMIT SYNTAX + +In the following, remote is a git remote, and ref-or-range refers to +either to a single git ref (hash, branch, tag), or ref1..ref2 In the +latter case, this refers to all commits on the "ancestor path" from +ref2 to ref1, not including ref1. See the \-\-ancestor-path option, +\fBgit-rev-list\fP(1). + +.SH COMMANDS + + +The following commands are available: + +.TP +.BR fetch " [remote]" +Fetch debpatch specific notes from remote (default origin) + +.TP +.BR merge " [remote]" +Merge debpatch specific notes from remote (default origin). +m +.TP +.BR pull " [remote]" +Fetch and then merge. + +.TP +.BR export " ref-or-range" +Mark the given commit or range of commits to be exported. + +.TP +.BR noexport " ref-or-range" +Mark the given commit or range of commits \fBnot\fP to be exported. + +.TP +.BR forwarded " ref-or-range " dest +Mark the given commit or range of commits as forwarded to dest + +.TP +.BR noforwarded " ref-or-range" +Remove any forwarding annotation + +.TP +.BR toquilt " ref-or-range" +Export the any marked patches in the range to debian/patches. If +debian/patches/series exists, new patches are appended. + +.TP +.BR status " ref-or-range" +Print out a one line summary for each commit, showing export-status, +hash, subject, forwarded status, separated by tabs + +.SH SEE ALSO +.BR gitpkg (1), +.BR git (1) +.SH AUTHOR +git-debpatch was written by David Bremner <brem...@debian.org>. diff --git a/gitpkg.1 b/gitpkg.1 index 1ba10e1..6e0b7cd 100644 --- a/gitpkg.1 +++ b/gitpkg.1 @@ -515,7 +515,8 @@ most cases. For example: .fi .hy - +If the range of commits is prefixed with :debpatch:, then it will be passed to +\fBgit-debpatch\fP(1) for export, rather than \fBgit-format-patch\fP. .SS Hook Library Helpers These are even more trivial snippets, for operations which may be shared by diff --git a/hooks/quilt-patches-deb-export-hook b/hooks/quilt-patches-deb-export-hook index 98b2aa7..b158779 100644 --- a/hooks/quilt-patches-deb-export-hook +++ b/hooks/quilt-patches-deb-export-hook @@ -64,6 +64,9 @@ do_patches (){ case $line in \#*) ;; + :debpatch:*) + GIT_DIR=$REPO_DIR/.git git debpatch toquilt ${line//:debpatch:/} + ;; *) count=$(wc -l "$patch_dir/series" | cut -f1 -d' ') if PATCHES="$(git --git-dir "$REPO_DIR/.git" format-patch --start-number $count -N -o "$patch_dir" "$line")"; then -- 1.7.9.1