chiark / gitweb /
tg export: Support --quilt for exporting to quilt series
authorPetr Baudis <pasky@suse.cz>
Mon, 11 Aug 2008 22:05:43 +0000 (00:05 +0200)
committerPetr Baudis <pasky@suse.cz>
Mon, 11 Aug 2008 22:05:43 +0000 (00:05 +0200)
README
tg-export.sh

diff --git a/README b/README
index 5aedbba045bef77834d0db52312e9dc046ddfc2f..b58a1b43e8f7383ed53b60464886d6efaf08de1a 100644 (file)
--- a/README
+++ b/README
@@ -263,13 +263,16 @@ tg summary
 
 tg export
 ~~~~~~~~~
-       Create a new branch containing tidied-up history
-       of the current topic branch and its dependencies,
-       suitable for pull by upstream - each topic branch
-       corresponds to a single commit in the cleaned up history
-       (corresponding basically exactly to `tg patch` output
-       for the topic branch).
+       Export a tidied-up history of the current topic branch
+       and its dependencies, suitable for feeding upstream.
+       Each topic branch corresponds to a single commit or patch
+       in the cleaned up history (corresponding basically exactly
+       to `tg patch` output for the topic branch).
 
+       The command has two posible outputs now - either a Git branch
+       with the collapsed history, or a quilt series in new directory.
+
+       In case of producing collapsed history in new branch,
        You can use this collapsed structure either for providing
        a pull source for upstream, or further linearization e.g.
        for creation of a quilt series using git log:
@@ -293,17 +296,39 @@ tg export
                     `- t/bar/good <,-------------------'/
                     `- t/baz      ---------------------'
 
+       In case of the quilt mode,
+
+       master$ tg export --quilt for-linus
+
+       would create this directory for-linus:
+
+       for-linus/t/foo/blue.diff
+       for-linus/t/foo/red.diff
+       for-linus/t/bar/good.diff
+       for-linus/t/baz.diff
+       for-linus/series:
+               t/foo/blue.diff -p1
+               t/bar/good.diff -p1
+               t/foo/red.diff -p1
+               t/baz.diff -p1
+
        The command works on the current topic branch
-       and requires one mandatory argument: the name of the branch
+       and can be called either without a parameter
+       (in that case, '--collapse' is assumed)
+       and with one mandatory argument: the name of the branch
        where the exported result shall be stored.
        The branch will be silently overwritten if it exists already!
        Use git reflog to recover in case of mistake.
 
-       Usage: tg export BRANCH
+       Alternatively, call it with the '--quilt' parameter
+       and an argument specifying the directory
+       where the quilt series should be saved.
+
+       Usage: tg export ([--collapse] BRANCH | --quilt DIR)
 
        TODO: Make stripping of non-essential headers configurable
        TODO: Make stripping of [PATCH] and other prefixes configurable
-       TODO: --quilt and --mbox options for other modes of operation
+       TODO: --mbox option for other mode of operation
 
 tg update
 ~~~~~~~~~
index db491691e6b17923b78b20389a0af59414ec20a1..4ce54cd1e96a903a72781eb90af0e63c9ff831cf 100644 (file)
@@ -5,6 +5,7 @@
 
 name=
 output=
+driver=collapse
 
 
 ## Parse options
@@ -12,11 +13,15 @@ output=
 while [ -n "$1" ]; do
        arg="$1"; shift
        case "$arg" in
+       --quilt)
+               driver=quilt;;
+       --collapse)
+               driver=collapse;;
        -*)
-               echo "Usage: tg export NEWBRANCH" >&2
+               echo "Usage: tg export ([--collapse] NEWBRANCH | --quilt DIRECTORY)" >&2
                exit 1;;
        *)
-               [ -z "$output" ] || die "new branch already specified ($output)"
+               [ -z "$output" ] || die "output already specified ($output)"
                output="$arg";;
        esac
 done
@@ -26,16 +31,13 @@ name="$(git symbolic-ref HEAD | sed 's#^refs/heads/##')"
 base_rev="$(git rev-parse --short --verify "refs/top-bases/$name" 2>/dev/null)" ||
        die "not on a TopGit-controlled branch"
 
-[ -n "$output" ] ||
-       die "no target branch specified"
-
-! git rev-parse --verify "$output" >/dev/null 2>&1 ||
-       die "target branch '$output' already exists; first run: git branch -D $output"
-
 
 playground="$(mktemp -d)"
 trap 'rm -rf "$playground"' EXIT
 
+
+## Collapse driver
+
 # Trusty Cogito code:
 load_author()
 {
@@ -105,15 +107,11 @@ collapsed_commit()
        echo "$name" >>"$playground/^ticker"
 }
 
-# collapse_one
+# collapse
 # This will collapse a single branch, using information about
 # previously collapsed branches stored in $playground.
-collapse_one()
+collapse()
 {
-       branch_needs_update >/dev/null
-       [ "$_ret" -eq 0 ] ||
-               die "cancelling $_ret export of $_dep (-> $_name): branch not up-to-date"
-
        if [ -s "$playground/$_dep" ]; then
                # We've already seen this dep
                commit="$(cat "$playground/$_dep")"
@@ -136,12 +134,69 @@ collapse_one()
        echo "$commit   $_dep" >>"$playground/$_name^parents"
 }
 
-# Collapse all the branches - this way, collapse_one will be
-# called in topological order.
-recurse_deps collapse_one "$name"
-(_ret=0; _dep="$name"; _name=""; _dep_is_tgish=1; collapse_one)
 
-git update-ref "refs/heads/$output" "$(cat "$playground/$name")"
+## Quilt driver
+
+quilt()
+{
+       if [ -z "$_dep_is_tgish" ]; then
+               # This dep is not for rewrite
+               return
+       fi
+
+       filename="$output/$_dep.diff"
+       if [ -e "$filename" ]; then
+               # We've already seen this dep
+               return
+       fi
+
+       mkdir -p "$(dirname "$filename")"
+       tg patch "$_dep" >"$filename"
+       echo "$_dep.diff -p1" >>"$output/series"
+       echo "Exported $_dep"
+}
+
+
+## Machinery
+
+if [ "$driver" = "collapse" ]; then
+       [ -n "$output" ] ||
+               die "no target branch specified"
+       ! git rev-parse --verify "$output" >/dev/null 2>&1 ||
+               die "target branch '$output' already exists; first run: git branch -D $output"
+
+elif [ "$driver" = "quilt" ]; then
+       [ -n "$output" ] ||
+               die "no target directory specified"
+       [ ! -e "$output" ] ||
+               die "target directory already exists: $output"
+
+       mkdir -p "$output"
+fi
+
+
+driver()
+{
+       branch_needs_update >/dev/null
+       [ "$_ret" -eq 0 ] ||
+               die "cancelling export of $_dep (-> $_name): branch not up-to-date"
+
+       $driver
+}
+
+# Call driver on all the branches - this will happen
+# in topological order.
+recurse_deps driver "$name"
+(_ret=0; _dep="$name"; _name=""; _dep_is_tgish=1; driver)
+
+
+if [ "$driver" = "collapse" ]; then
+       git update-ref "refs/heads/$output" "$(cat "$playground/$name")"
+
+       depcount="$(cat "$playground/^ticker" | wc -l)"
+       echo "Exported topic branch $name (total $depcount topics) to branch $output"
 
-depcount="$(cat "$playground/^ticker" | wc -l)"
-echo "Exported topic branch $name (total $depcount topics) to branch $output"
+elif [ "$driver" = "quilt" ]; then
+       depcount="$(cat "$output/series" | wc -l)"
+       echo "Exported topic branch $name (total $depcount topics) to directory $output"
+fi