Statistics
| Branch: | Tag: | Revision:

root / devel / review @ 42c067b7

History | View | Annotate | Download (3.5 kB)

1 42c067b7 Michael Hanselmann
#!/bin/bash
2 42c067b7 Michael Hanselmann
3 42c067b7 Michael Hanselmann
# Copyright (C) 2009 Google Inc.
4 42c067b7 Michael Hanselmann
#
5 42c067b7 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
6 42c067b7 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
7 42c067b7 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
8 42c067b7 Michael Hanselmann
# (at your option) any later version.
9 42c067b7 Michael Hanselmann
#
10 42c067b7 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
11 42c067b7 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
12 42c067b7 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 42c067b7 Michael Hanselmann
# General Public License for more details.
14 42c067b7 Michael Hanselmann
#
15 42c067b7 Michael Hanselmann
# You should have received a copy of the GNU General Public License
16 42c067b7 Michael Hanselmann
# along with this program; if not, write to the Free Software
17 42c067b7 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 42c067b7 Michael Hanselmann
# 02110-1301, USA.
19 42c067b7 Michael Hanselmann
20 42c067b7 Michael Hanselmann
# To set user mappings, use this command:
21 42c067b7 Michael Hanselmann
#   git config gnt-review.johndoe 'John Doe <johndoe@domain.tld>'
22 42c067b7 Michael Hanselmann
23 42c067b7 Michael Hanselmann
set -e
24 42c067b7 Michael Hanselmann
25 42c067b7 Michael Hanselmann
# Get absolute path to myself
26 42c067b7 Michael Hanselmann
me_plain="$0"
27 42c067b7 Michael Hanselmann
me=$(readlink -f "$me_plain")
28 42c067b7 Michael Hanselmann
29 42c067b7 Michael Hanselmann
add_reviewed_by() {
30 42c067b7 Michael Hanselmann
  local msgfile="$1"
31 42c067b7 Michael Hanselmann
32 42c067b7 Michael Hanselmann
  grep -q '^Reviewed-by: ' "$msgfile" && return
33 42c067b7 Michael Hanselmann
34 42c067b7 Michael Hanselmann
  perl -i -e '
35 42c067b7 Michael Hanselmann
  my $sob = 0;
36 42c067b7 Michael Hanselmann
  while (<>) {
37 42c067b7 Michael Hanselmann
    if ($sob == 0 and m/^Signed-off-by:/) {
38 42c067b7 Michael Hanselmann
      $sob = 1;
39 42c067b7 Michael Hanselmann
40 42c067b7 Michael Hanselmann
    } elsif ($sob == 1 and not m/^Signed-off-by:/) {
41 42c067b7 Michael Hanselmann
      print "Reviewed-by: \n";
42 42c067b7 Michael Hanselmann
      $sob = -1;
43 42c067b7 Michael Hanselmann
    }
44 42c067b7 Michael Hanselmann
45 42c067b7 Michael Hanselmann
    print;
46 42c067b7 Michael Hanselmann
  }
47 42c067b7 Michael Hanselmann
48 42c067b7 Michael Hanselmann
  if ($sob == 1) {
49 42c067b7 Michael Hanselmann
    print "Reviewed-by: \n";
50 42c067b7 Michael Hanselmann
  }
51 42c067b7 Michael Hanselmann
  ' "$msgfile"
52 42c067b7 Michael Hanselmann
}
53 42c067b7 Michael Hanselmann
54 42c067b7 Michael Hanselmann
replace_users() {
55 42c067b7 Michael Hanselmann
  local msgfile="$1"
56 42c067b7 Michael Hanselmann
57 42c067b7 Michael Hanselmann
  perl -i -e '
58 42c067b7 Michael Hanselmann
  sub map_username {
59 42c067b7 Michael Hanselmann
    my ($name) = @_;
60 42c067b7 Michael Hanselmann
61 42c067b7 Michael Hanselmann
    return $name unless $name;
62 42c067b7 Michael Hanselmann
63 42c067b7 Michael Hanselmann
    my @cmd = ("git", "config", "--get", "gnt-review.$name");
64 42c067b7 Michael Hanselmann
65 42c067b7 Michael Hanselmann
    open(my $fh, "-|", @cmd) or die "Command \"@cmd\" failed: $!";
66 42c067b7 Michael Hanselmann
    my $output = do { local $/ = undef; <$fh> };
67 42c067b7 Michael Hanselmann
    close($fh);
68 42c067b7 Michael Hanselmann
69 42c067b7 Michael Hanselmann
    if ($? == 0) {
70 42c067b7 Michael Hanselmann
      chomp $output;
71 42c067b7 Michael Hanselmann
      $output =~ s/\s+/ /;
72 42c067b7 Michael Hanselmann
      return $output;
73 42c067b7 Michael Hanselmann
    }
74 42c067b7 Michael Hanselmann
75 42c067b7 Michael Hanselmann
    return $name;
76 42c067b7 Michael Hanselmann
  }
77 42c067b7 Michael Hanselmann
78 42c067b7 Michael Hanselmann
  while (<>) {
79 42c067b7 Michael Hanselmann
    if (m/^Reviewed-by:(.*)$/) {
80 42c067b7 Michael Hanselmann
      my @names = grep {
81 42c067b7 Michael Hanselmann
        # Ignore empty entries
82 42c067b7 Michael Hanselmann
        !/^$/
83 42c067b7 Michael Hanselmann
      } map {
84 42c067b7 Michael Hanselmann
        # Normalize whitespace
85 42c067b7 Michael Hanselmann
        $_ =~ s/(^\s+|\s+$)//g;
86 42c067b7 Michael Hanselmann
        $_ =~ s/\s+/ /g;
87 42c067b7 Michael Hanselmann
88 42c067b7 Michael Hanselmann
        # Map names
89 42c067b7 Michael Hanselmann
        $_ = map_username($_);
90 42c067b7 Michael Hanselmann
91 42c067b7 Michael Hanselmann
        $_;
92 42c067b7 Michael Hanselmann
      } split(m/,/, $1);
93 42c067b7 Michael Hanselmann
94 42c067b7 Michael Hanselmann
      foreach (sort @names) {
95 42c067b7 Michael Hanselmann
        print "Reviewed-by: $_\n";
96 42c067b7 Michael Hanselmann
      }
97 42c067b7 Michael Hanselmann
    } else {
98 42c067b7 Michael Hanselmann
      print;
99 42c067b7 Michael Hanselmann
    }
100 42c067b7 Michael Hanselmann
  }
101 42c067b7 Michael Hanselmann
  ' "$msgfile"
102 42c067b7 Michael Hanselmann
103 42c067b7 Michael Hanselmann
  if ! grep -q '^Reviewed-by: ' "$msgfile"
104 42c067b7 Michael Hanselmann
  then
105 42c067b7 Michael Hanselmann
    echo 'Missing Reviewed-by: line' >&2
106 42c067b7 Michael Hanselmann
    sleep 1
107 42c067b7 Michael Hanselmann
    return 1
108 42c067b7 Michael Hanselmann
  fi
109 42c067b7 Michael Hanselmann
110 42c067b7 Michael Hanselmann
  return 0
111 42c067b7 Michael Hanselmann
}
112 42c067b7 Michael Hanselmann
113 42c067b7 Michael Hanselmann
run_editor() {
114 42c067b7 Michael Hanselmann
  local filename="$1"
115 42c067b7 Michael Hanselmann
  local editor=${EDITOR:-vi}
116 42c067b7 Michael Hanselmann
  local args
117 42c067b7 Michael Hanselmann
118 42c067b7 Michael Hanselmann
  case "$(basename "$editor")" in
119 42c067b7 Michael Hanselmann
    vi* | *vim)
120 42c067b7 Michael Hanselmann
      # Start edit mode at Reviewed-by: line
121 42c067b7 Michael Hanselmann
      args='+/^Reviewed-by: +nohlsearch +startinsert!'
122 42c067b7 Michael Hanselmann
    ;;
123 42c067b7 Michael Hanselmann
    *)
124 42c067b7 Michael Hanselmann
      args=
125 42c067b7 Michael Hanselmann
    ;;
126 42c067b7 Michael Hanselmann
  esac
127 42c067b7 Michael Hanselmann
128 42c067b7 Michael Hanselmann
  $editor $args "$filename"
129 42c067b7 Michael Hanselmann
}
130 42c067b7 Michael Hanselmann
131 42c067b7 Michael Hanselmann
commit_editor() {
132 42c067b7 Michael Hanselmann
  local msgfile="$1"
133 42c067b7 Michael Hanselmann
134 42c067b7 Michael Hanselmann
  local tmpf=$(mktemp)
135 42c067b7 Michael Hanselmann
  trap "rm -f $tmpf" EXIT
136 42c067b7 Michael Hanselmann
137 42c067b7 Michael Hanselmann
  cp "$msgfile" "$tmpf"
138 42c067b7 Michael Hanselmann
139 42c067b7 Michael Hanselmann
  while :
140 42c067b7 Michael Hanselmann
  do
141 42c067b7 Michael Hanselmann
    add_reviewed_by "$tmpf"
142 42c067b7 Michael Hanselmann
143 42c067b7 Michael Hanselmann
    run_editor "$tmpf"
144 42c067b7 Michael Hanselmann
145 42c067b7 Michael Hanselmann
    replace_users "$tmpf" && break
146 42c067b7 Michael Hanselmann
  done
147 42c067b7 Michael Hanselmann
148 42c067b7 Michael Hanselmann
  cp "$tmpf" "$msgfile"
149 42c067b7 Michael Hanselmann
}
150 42c067b7 Michael Hanselmann
151 42c067b7 Michael Hanselmann
copy_commit() {
152 42c067b7 Michael Hanselmann
  local rev="$1" target_branch="$2"
153 42c067b7 Michael Hanselmann
154 42c067b7 Michael Hanselmann
  echo "Copying commit $rev ..."
155 42c067b7 Michael Hanselmann
156 42c067b7 Michael Hanselmann
  git cherry-pick -n "$rev"
157 42c067b7 Michael Hanselmann
  GIT_EDITOR="$me --commit-editor \"\$@\"" git commit -c "$rev" -s
158 42c067b7 Michael Hanselmann
}
159 42c067b7 Michael Hanselmann
160 42c067b7 Michael Hanselmann
main() {
161 42c067b7 Michael Hanselmann
  local range="$1" target_branch="$2"
162 42c067b7 Michael Hanselmann
163 42c067b7 Michael Hanselmann
  if [[ -z "$target_branch" || "$range" != *..* ]]
164 42c067b7 Michael Hanselmann
  then
165 42c067b7 Michael Hanselmann
    echo "Usage: $me_plain <from..to> <target-branch>" >&2
166 42c067b7 Michael Hanselmann
    exit 1
167 42c067b7 Michael Hanselmann
  fi
168 42c067b7 Michael Hanselmann
169 42c067b7 Michael Hanselmann
  git checkout "$target_branch"
170 42c067b7 Michael Hanselmann
  local old_head=$(git rev-parse HEAD)
171 42c067b7 Michael Hanselmann
172 42c067b7 Michael Hanselmann
  for rev in $(git rev-list --reverse "$range")
173 42c067b7 Michael Hanselmann
  do
174 42c067b7 Michael Hanselmann
    copy_commit "$rev"
175 42c067b7 Michael Hanselmann
  done
176 42c067b7 Michael Hanselmann
177 42c067b7 Michael Hanselmann
  git log "$old_head..$target_branch"
178 42c067b7 Michael Hanselmann
}
179 42c067b7 Michael Hanselmann
180 42c067b7 Michael Hanselmann
if [[ "$1" == --commit-editor ]]
181 42c067b7 Michael Hanselmann
then
182 42c067b7 Michael Hanselmann
  shift
183 42c067b7 Michael Hanselmann
  commit_editor "$@"
184 42c067b7 Michael Hanselmann
else
185 42c067b7 Michael Hanselmann
  main "$@"
186 42c067b7 Michael Hanselmann
fi