On Mon, 05 Mar 2012 22:10:48 -0400, David Bremner <[email protected]> wrote:
>
> One thing I think I got wrong in round 1 is the blanket use of
> --ancestor-path. Consider the following branch structure, where
> upstream has been merged into master several times.
Here is a revised version. Let's pretend there were all kinds of useful
discussions in some other medium that led to this.
No use of ancestor-path in this one, instead we just use git-log
(with 'git debpatch log') for a status command.
Tagging and untagging is now only for a single commit.
I'm not 100% convinced about the order of parameters for fields with
values, but
git debpatch +export $sha1
git debpatch -export $sha1
seems quite natural, and
git debpatch +forwarded $sha1 $urlorwhatever
is probably a less common usecase.
Thinking back to earlier discussions about configurability, I can see
this might be a bit _too_ flexible, it would be easy to typo
git debpatch +expert $sha1
And then wonder why the patch isn't exported. Perhaps I should put back
"mark" and "unmark" as aliases for "+export" and "-export"
One thing this version doesn't do is export the metadata in the patch;
that could be useful, but needs a bit more hackery afaict.
>From 1e1029b0e7f78e43c56bc330606884a687bdc1e8 Mon Sep 17 00:00:00 2001
From: David Bremner <[email protected]>
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 | 108 +++++++++++++++++++++++++++++++++++
git-debpatch.1 | 68 ++++++++++++++++++++++
gitpkg.1 | 3 +-
hooks/quilt-patches-deb-export-hook | 3 +
4 files changed, 181 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..945ee13
--- /dev/null
+++ b/git-debpatch
@@ -0,0 +1,108 @@
+#!/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 2>/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 insist_commits() {
+ if [ $(git rev-parse $1 | wc -l) != $2 ]; then
+ echo "$1 does not expand to exactly $2 commits";
+ exit 1;
+
+ fi;
+}
+
+function add_tag() {
+ insist_commits $1 1
+ field=${2^}
+ value=${3-true}
+ set_field $ref $field $value
+}
+
+function remove_tag() {
+ insist_commits $1 1
+ field=${2^}
+ value=${3-true}
+ remove_field $1 $field
+}
+
+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;
+ ;;
+ +*)
+ ref=${2-HEAD}
+ add_tag $ref ${1#+} $3
+ ;;
+ -*)
+ ref=${2-HEAD}
+ remove_tag $ref ${1#-} $3
+ ;;
+ toquilt)
+ ref=${2-HEAD}
+ git rev-list --reverse $ref | \
+ while read hash ; do
+ if is_exportable $hash; then
+ export_one_patch $hash
+ fi
+ done
+ ;;
+
+ *)
+ GIT_NOTES_REF=refs/notes/debpatch exec git $*
+esac
diff --git a/git-debpatch.1 b/git-debpatch.1
new file mode 100644
index 0000000..3cf51ee
--- /dev/null
+++ b/git-debpatch.1
@@ -0,0 +1,68 @@
+.\" 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 ]
+.RI [ 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 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
+.RI + field " [" commitish "] [" value ]
+Add the given field to the notes for commitish, with a default value
+of "true". The most useful example is "+export"
+
+.TP
+.RI - field " [" commitish ]
+Remove the given field from commitish
+
+.TP
+.BR toquilt " ref-or-range"
+Export the any "+export" patches in the range to debian/patches. If
+debian/patches/series exists, new patches are appended.
+
+.RE
+Other commands are passed though to git with an appropriate set of
+GIT_NOTES_REF. Useful examples are "git debpatch log" and
+"git debpatch show".
+
+.SH SEE ALSO
+.BR gitpkg (1),
+.BR git (1)
+.SH AUTHOR
+git-debpatch was written by David Bremner <[email protected]>.
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