From nobody Mon Sep 17 00:00:00 2001 From: Sir Raorn Date: Tue, 20 Jun 2006 20:56:41 +0400 Subject: [PATCH] diff[.gz|.bz2] command. diff: path_to_dir name=name_of_patch base=dir_in_branch branch=branch_with_sources Calls git-diff-tree -r --patch-with-stat on $base in $branch and dir in current branch. This helps keep unmodified upstream sources in different branch and make diff against current working branch for apllying later in specfile. Signed-off-by: Sir Raorn --- gear | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 141 insertions(+), 1 deletions(-) 13059c9958af7969bda3cfa5c231ecb7a2e23ea2 diff --git a/gear b/gear index 063e152..99ed79b 100755 --- a/gear +++ b/gear @@ -32,6 +32,7 @@ # (copy|gzip|bzip2): glob_pattern.. # (copy|gzip|bzip2)?: glob_pattern.. # exclude: glob_pattern.. # tar(|.gz|.bz2): path_to_directory [options] +# diff(|.gz|.bz2): path_to_directory [options] # # Valid tar options are: # name=archive_name - tar archive name, may reference to keywords; @@ -43,6 +44,16 @@ # Valid tar keywords are: # @dir@ - basename(path_to_directory); # @name@, @version@, @release@. # Default tar archive name is @dir@-@version@. +# +# Valid diff options are: +# name=diff_name - patch name, may reference to keywords; +# base=path_to_directory - directory in branch_name, first argunemt +# to git-diff-tree; +# spec=path_to_file - path to specfile which defines keywords; +# branch=branch_name - branch name with "original" source tree; +# Valid diff keywords are the save as tar. +# Default patch name is @dir@-@version@-@release@. +# Default base is ".". PROG=gear @@ -333,7 +344,7 @@ get_tar_name() tar_tree="$tree_id" - local opt quoted spec= spec_name= spec_version= spec_release= + local opt spec= spec_name= spec_version= spec_release= for opt; do case "$opt" in @@ -368,6 +379,48 @@ get_tar_name() subst_keywords tar_tree "$dir" "$spec_name" "$spec_version" "$spec_release" } +get_diff_name() +{ + local dir="$1" + shift + diff_name='@name@-@version@-@release@' + diff_base='.' + diff_tree="$tree_id" + + local opt spec= spec_name= spec_version= spec_release= + + for opt; do + case "$opt" in + spec=*) spec="${opt#spec=}" + check_path specfile "$spec" + ;; + name=*) diff_name="${opt#name=}" + ;; + base=*) diff_base="${opt#base=}" + ;; + branch=*) + diff_tree="${opt#branch=}" + ;; + *) rules_error "Unrecognized option: $opt" + ;; + esac + done + + if [ -n "$spec" ]; then + cat_blob "$tree_id" "$spec" >"$workdir/spec" + spec_name="$(sed '/^name:[[:space:]]*/I!d;s///;q' "$workdir/spec")" + spec_version="$(sed '/^version:[[:space:]]*/I!d;s///;q' "$workdir/spec")" + spec_release="$(sed '/^release:[[:space:]]*/I!d;s///;q' "$workdir/spec")" + fi + [ -n "$spec_name" ] || spec_name="$pkg_name" + [ -n "$spec_version" ] || spec_version="$pkg_version" + [ -n "$spec_release" ] || spec_release="$pkg_release" + + subst_keywords diff_name "$dir" "$spec_name" "$spec_version" "$spec_release" + subst_keywords diff_base "$dir" "$spec_name" "$spec_version" "$spec_release" + subst_keywords diff_tree "$dir" "$spec_name" "$spec_version" "$spec_release" +} + make_tar() { local cmd dir name @@ -423,6 +476,76 @@ make_tar() esac } +make_diff() +{ + local cmd dir name + cmd="$1" + shift + dir="$1" + shift + name="$1" + shift + diff_base="$1" + shift + diff_tree="$1" + shift + + local tree_id_1 tree_id_2 + + if [ "$diff_base" = . ]; then + tree_id_1="$diff_tree" + else + local dir_name base_name quoted + dir_name="$(dirname -- "$diff_base")" + base_name="$(basename -- "$diff_base")" + # modifies $tree + traverse_tree "$diff_tree" "$dir_name" || + return 0 + quoted="$(quote_sed_regexp "$base_name")" + tree_id_1="$(git-ls-tree "$tree" "$base_name" | + sed -ne 's/^[^[:space:]]\+[[:space:]]\+tree[[:space:]]\+\([^[:space:]]\+\)[[:space:]]\+'"$quoted"'$/\1/p')" + if [ -z "$tree_id_1" ]; then + if [ "$optional" = 1 ]; then + return 0 + else + rules_error "tree $diff_base not found in $tree" + fi + fi + fi + + if [ "$dir" = . ]; then + tree_id_2="$tree_id" + else + local dir_name base_name quoted + dir_name="$(dirname -- "$dir")" + base_name="$(basename -- "$dir")" + # modifies $tree + traverse_tree "$tree_id" "$dir_name" || + return 0 + quoted="$(quote_sed_regexp "$base_name")" + tree_id_2="$(git-ls-tree "$tree" "$base_name" | + sed -ne 's/^[^[:space:]]\+[[:space:]]\+tree[[:space:]]\+\([^[:space:]]\+\)[[:space:]]\+'"$quoted"'$/\1/p')" + if [ -z "$tree_id_2" ]; then + if [ "$optional" = 1 ]; then + return 0 + else + rules_error "tree $dir not found in $tree" + fi + fi + fi + + git-diff-tree -r --patch-with-stat "$tree_id_1" "$tree_id_2" >"$outdir/$name.patch" + verbose "Extracted \"$name.patch\" diff." + case "$cmd" in + diff.gz) + gzip -9 "$outdir/$name.patch" + ;; + diff.bz2) + bzip2 -9 "$outdir/$name.patch" + ;; + esac +} + make_archive() { # format: "cmd dirname options.." @@ -436,6 +559,19 @@ make_archive() make_tar "$cmd" "$dir_name" "$tar_name" "$tar_base" "$tar_tree" } +make_patch() +{ + # format: "cmd dirname options.." + local cmd="$1" dir_name="$2" + [ -n "$dir_name" ] || + rules_error "No dirname specified" + shift 2 + check_path dirname "$dir_name" + + get_diff_name "$(basename -- "$dir_name")" "$@" + make_diff "$cmd" "$dir_name" "$diff_name" "$diff_base" "$diff_tree" +} + copy_by_pattern() { # format: "cmd pattern.." @@ -542,6 +678,10 @@ parse_rules() make_archive "$cmd" $options || rules_error "Failed to make archive" ;; + diff|diff.gz|diff.bz2) + make_patch "$cmd" $options || + rules_error "Failed to make patch" + ;; copy|gzip|bzip2) copy_by_pattern "$cmd" $options || rules_error "Failed to copy by pattern" -- 1.3.3