Change in osmo-dev[master]: replace src/* git scripts with a single src/gits

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Thu Nov 8 14:03:45 UTC 2018


Neels Hofmeyr has submitted this change and it was merged. ( https://gerrit.osmocom.org/11560 )

Change subject: replace src/* git scripts with a single src/gits
......................................................................

replace src/* git scripts with a single src/gits

I keep re-using this functionality in completely unrelated realms, and decided
to unify the oddly named scripts in a single 'gits' meta-repos tool, so I can
just symlink this script into my ~/bin and use it everywhere.

Change-Id: I579e7af26d76d5c5d83b2349695456bc7b54f5a2
---
M src/README
D src/e
D src/g
D src/git_branch_summary.py
A src/gits
D src/s
D src/st
7 files changed, 397 insertions(+), 298 deletions(-)

Approvals:
  osmith: Looks good to me, but someone else must approve; Verified
  Neels Hofmeyr: Looks good to me, approved



diff --git a/src/README b/src/README
index a2fbe81..f066561 100644
--- a/src/README
+++ b/src/README
@@ -11,12 +11,11 @@
 	Pass a patch number seen on gerrit to fetch the latest patch set into
 	your git clone. See top comment in the script.
 
- ./g   run a git command in each source tree
- ./e   run an arbitrary shell command in each source tree
- ./st  show a brief branch and local mods status for each source tree
- ./s   walk through each source tree and use gitk as well as user interaction
-       to quickly fast-forward / reset changes coming in from upstream. (This
-       is potentially dangerous, but safe if you only hit enter every time.)
+ gits   Conveniently manage several git clones:
+        - run a git or shell command in each source tree
+	- show a brief branch and local mods status for each source tree
+	- merge / rebase / fast-forward each source tree interactively
+	See ./gits help
 
 Examples:
 
@@ -54,7 +53,7 @@
 
 -----------------------------------------------------------------------------
 
-./g fetch    # run 'git fetch' in each clone = fetch all from upstream
+./gits fetch    # run 'git fetch' in each clone = fetch all from upstream
 
 ===== libasn1c =====
 remote: Counting objects: 29, done
@@ -90,7 +89,7 @@
 
 -----------------------------------------------------------------------------
 
-./st         # any modifications / updates? (e.g. useful after './g fetch')
+./gits st    # any modifications / updates? (e.g. useful after './g fetch')
              # (checks only 'master' and the current checked-out branch)
 
      libasn1c master
@@ -116,13 +115,13 @@
 
 -----------------------------------------------------------------------------
 
-./e rm .version  # in each source tree, remove the local .version file
+./gits sh rm .version  # in each source tree, remove the local .version file
 
 -----------------------------------------------------------------------------
 
-./s         # interactively try to fast-forward to upstream and/or save
-            # local modifications.
-            # If you just hit Enter all the time, nothing will be changed.
+./gits rebase  # interactively try to fast-forward to upstream and/or save
+               # local modifications.
+               # If you just hit Enter all the time, nothing dangerous will happen.
 
 
 libosmocore
diff --git a/src/e b/src/e
deleted file mode 100755
index 4d32bf1..0000000
--- a/src/e
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python3
-import os
-import os.path
-import sys
-import subprocess
-
-base_dir = os.getcwd()
-
-for p in list(os.listdir('.')):
-	subdir = os.path.join(base_dir, p)
-	if not os.path.isdir(os.path.join(subdir, '.git')):
-		continue
-	print("\n===== %s =====" % p)
-	os.chdir(subdir)
-	subprocess.call(sys.argv[1:])
diff --git a/src/g b/src/g
deleted file mode 100755
index bb9b693..0000000
--- a/src/g
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import os
-import subprocess
-
-git_subdirs = []
-
-for subdir in os.listdir():
-  if not os.path.isdir(os.path.join(subdir, '.git')):
-    continue
-
-  print('\n===== %s =====' % subdir)
-  sys.stdout.flush()
-  subprocess.call(['git', '-C', subdir] + sys.argv[1:])
-  sys.stdout.flush()
-  sys.stderr.flush()
diff --git a/src/git_branch_summary.py b/src/git_branch_summary.py
deleted file mode 100755
index 9d81f8b..0000000
--- a/src/git_branch_summary.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-
-import sys, subprocess, re
-
-if len(sys.argv) < 2:
-  print("Usage: %s <git_dir> [...]\nThis is mostly here for helping the 'st' script." % sys.argv[0])
-  exit(1)
-
-interesting_branch_names = [ 'master', 'sysmocom/iu', 'sysmocom/sccp', 'aper-prefix-onto-upstream' ]
-
-re_branch_name = re.compile('^..([^ ]+) .*')
-re_ahead = re.compile('ahead [0-9]+|behind [0-9]+')
-
-def branch_name(line):
-  m = re_branch_name.match(line)
-  return m.group(1)
-
-interesting = []
-
-def do_one_git(git_dir):
-  global interesting
-  branch_strs = subprocess.check_output(('git', '-C', git_dir, 'branch', '-vv')).decode('utf-8').splitlines()
-  interesting_branches = []
-
-  for line in branch_strs:
-    name = branch_name(line)
-    current_branch = False
-    if line.startswith('*'):
-      current_branch = True
-    elif name not in interesting_branch_names:
-      continue
-    ahead = re_ahead.findall(line)
-    if not ahead and not current_branch:
-      continue
-    ahead = [x.replace('ahead ', '+').replace('behind ', '-') for x in ahead]
-    br = (current_branch, name, ahead)
-    if current_branch:
-      interesting_branches.insert(0, br)
-    else:
-      interesting_branches.append(br)
-
-  status = subprocess.check_output(('git', '-C', git_dir, 'status')).decode()
-  has_mods = 'modified:' in status
-
-  interesting.append((git_dir, has_mods, interesting_branches))
-
-
-for git_dir in sys.argv[1:]:
-  do_one_git(git_dir)
-
-
-first_col = max([len(git_dir) for git_dir, _, _ in interesting])
-first_col_fmt = '%' + str(first_col) + 's'
-
-for git_dir, has_mods, interesting_branches in interesting:
-  strs = [first_col_fmt % git_dir,]
-  if has_mods:
-    strs.append('MODS')
-  for current_branch, name, ahead in interesting_branches:
-    br = []
-    br.append(name)
-    if ahead:
-      br.append('[%s]' % '|'.join(ahead))
-    strs.append(''.join(br))
-
-  print(' '.join(strs))
-
-# vim: shiftwidth=2 expandtab tabstop=2
diff --git a/src/gits b/src/gits
new file mode 100755
index 0000000..81083f1
--- /dev/null
+++ b/src/gits
@@ -0,0 +1,386 @@
+#!/usr/bin/env python3
+#
+# (C) 2018 by Neels Hofmeyr <neels at hofmeyr.de>
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import subprocess
+import re
+import argparse
+import os
+import shlex
+
+doc = '''gits: conveniently manage several git subdirectories.
+Instead of doing the 'cd foo; git status; cd ../bar; git status' dance, this
+helps to save your time with: status, fetch, rebase, ...
+'''
+
+re_status_mods = re.compile('^\t(modified|deleted):.*')
+re_status_branch_name = re.compile('On branch ([^ ]*)')
+re_branch_name = re.compile('^..([^ ]+) .*')
+re_ahead_behind = re.compile('ahead [0-9]+|behind [0-9]+')
+
+
+def error(*msgs):
+    sys.stderr.write(''.join(msgs))
+    sys.stderr.write('\n')
+    exit(1)
+
+
+def cmd_to_str(cmd):
+    return ' '.join(shlex.quote(c) for c in cmd)
+
+
+def git(git_dir, *args, may_fail=False, section_marker=False, show_cmd=True):
+    sys.stdout.flush()
+    sys.stderr.flush()
+
+    if section_marker:
+        print('\n===== %s =====' % git_dir)
+        sys.stdout.flush()
+
+    cmd = ['git', '-C', git_dir] + list(args)
+    if show_cmd:
+        print('+ %s' % cmd_to_str(cmd))
+        sys.stdout.flush()
+
+    rc = subprocess.call(cmd)
+    if rc and not may_fail:
+        error('git returned error! command: git -C %r %s' %
+              (git_dir, ' '.join(repr(arg) for arg in args)))
+
+
+def git_output(git_dir, *args):
+    return subprocess.check_output(['git', '-C', git_dir, ] + list(args)).decode('utf-8')
+
+
+def git_branch(git_dir):
+    status = git_output(git_dir, 'status', '--long')
+    m = re_status_branch_name.find(status)
+    if not m:
+        error('No current branch in %r' % git_dir)
+    return m.group(1)
+
+
+def git_status(git_dir, verbose=False):
+    status_lines = git_output(git_dir, 'status').splitlines()
+    if verbose and len(status_lines):
+        print(status_lines[0])
+
+    on_branch = None
+    branch_status_str = None
+    local_mods = False
+
+    ON_BRANCH = 'On branch '
+    STATUS = 'Your branch'
+
+    for l in status_lines:
+        if l.startswith(ON_BRANCH):
+            if on_branch:
+                error('cannot parse status, more than one branch?')
+            on_branch = l[len(ON_BRANCH):]
+        elif l.startswith(STATUS):
+            if 'Your branch is up to date' in l:
+                branch_status_str = l
+            elif 'Your branch is up-to-date' in l:
+                branch_status_str = l
+            elif 'Your branch is ahead' in l:
+                branch_status_str = 'ahead: ' + l
+            elif 'Your branch is behind' in l:
+                branch_status_str = 'behind: ' + l
+            elif 'have diverged' in l:
+                branch_status_str = 'diverged: ' + l
+            else:
+                error('unknown status str: %r' % l)
+        else:
+            m = re_status_mods.match(l)
+            if m:
+                local_mods = True
+
+    if verbose:
+        print('%s%s' % (branch_status_str, '\nLOCAL MODS' if local_mods else ''))
+    return (on_branch, branch_status_str, local_mods)
+
+
+def git_branch_summary(git_dir):
+    '''return a list of strings: [git_dir, branch-info0, branch-info1,...]
+    infos are are arbitrary strings like "master[-1]"'''
+
+    interesting_branch_names = ('master',)
+
+    strs = [git_dir, ]
+
+    on_branch, branch_status_str, has_mods = git_status(git_dir)
+
+    if has_mods:
+        strs.append('MODS')
+
+    branch_strs = git_output(git_dir, 'branch', '-vv').splitlines()
+
+    for line in branch_strs:
+        m = re_branch_name.match(line)
+        name = m.group(1)
+
+        current_branch = False
+        if line.startswith('*'):
+            current_branch = True
+        elif name not in interesting_branch_names:
+            continue
+        ahead_behind = re_ahead_behind.findall(line)
+        if not ahead_behind and not current_branch:
+            # skip branches that are "not interesting"
+            continue
+        ahead_behind = [
+            x.replace('ahead ', '+').replace('behind ', '-') for x in ahead_behind]
+
+        branch_info = name
+        if ahead_behind:
+            branch_info = branch_info + ('[%s]' % '|'.join(ahead_behind))
+
+        strs.append(''.join(branch_info))
+
+    return strs
+
+
+def format_summaries(summaries, sep0=' ', sep1=' '):
+    first_col = max([len(row[0]) for row in summaries])
+    first_col_fmt = '%' + str(first_col) + 's'
+
+    lines = []
+    for row in summaries:
+        lines.append('%s%s%s' % (first_col_fmt %
+                                 row[0], sep0, sep1.join(row[1:])))
+
+    return '\n'.join(lines)
+
+
+def git_dirs():
+    dirs = []
+    for sub in os.listdir():
+        git_path = os.path.join(sub, '.git')
+        if not os.path.isdir(git_path):
+            continue
+        dirs.append(sub)
+
+    if not dirs:
+        error('No subdirectories found that are git clones')
+
+    return list(sorted(dirs))
+
+
+def print_status():
+    infos = [git_branch_summary(git_dir) for git_dir in git_dirs()]
+    print(format_summaries(infos))
+
+
+def cmd_do(argv):
+    for git_dir in git_dirs():
+        git(git_dir, *argv, may_fail=True, section_marker=True)
+
+
+def cmd_sh(cmd):
+    if not cmd:
+        error('which command do you want to run?')
+    for git_dir in git_dirs():
+        print('\n===== %s =====' % git_dir)
+        print('+ %s' % cmd_to_str(cmd))
+        sys.stdout.flush()
+        subprocess.call(cmd, cwd=git_dir)
+        sys.stdout.flush()
+        sys.stderr.flush()
+
+
+class SkipThisRepo(Exception):
+    pass
+
+
+def ask(git_dir, *question, valid_answers=('*',)):
+    while True:
+        print('\n' + '\n  '.join(question))
+        print('  ' + '\n  '.join((
+            's  skip this repo',
+            't  show in tig',
+            'g  show in gitk',
+        )))
+
+        answer = sys.stdin.readline().strip()
+        if answer == 's':
+            raise SkipThisRepo()
+        if answer == 't':
+            subprocess.call(('tig', '--all'), cwd=git_dir)
+            continue
+        if answer == 'g':
+            subprocess.call(('gitk', '--all'), cwd=git_dir)
+            continue
+
+        for v in valid_answers:
+            if v == answer:
+                return answer
+            if v == '*':
+                return answer
+            if v == '+' and len(answer):
+                return answer
+
+
+def rebase(git_dir):
+    orig_branch, branch_status_str, local_mods = git_status(
+        git_dir, verbose=True)
+
+    if orig_branch is None:
+        print('Not on a branch: %s' % git_dir)
+        raise SkipThisRepo()
+
+    if local_mods:
+        do_commit = ask(git_dir, 'Local mods.',
+                        'c  commit to this branch',
+                        '<name>  commit to new branch',
+                        '<empty> skip')
+
+        if not do_commit:
+            raise SkipThisRepo()
+
+        if do_commit == 'c':
+            git(git_dir, 'commit', '-am', 'wip', may_fail=True)
+        else:
+            git(git_dir, 'checkout', '-b', do_commit)
+            git(git_dir, 'commit', '-am', 'wip', may_fail=True)
+            git(git_dir, 'checkout', orig_branch)
+
+        _, _, local_mods = git_status(git_dir)
+
+        if local_mods:
+            print('There still are local modifications')
+            raise SkipThisRepo()
+
+    if branch_status_str is None:
+        print('there is no upstream branch for %r' % orig_branch)
+
+    elif branch_status_str.startswith('behind'):
+        if 'and can be fast-forwarded' in branch_status_str:
+            print('fast-forwarding...')
+            git(git_dir, 'merge')
+        else:
+            do_merge = ask(git_dir, 'Behind. git merge?',
+                           "<empty>  don't merge",
+                           'ok  git merge',
+                           valid_answers=('', 'ok')
+                           )
+
+            if do_merge == 'ok':
+                git(git_dir, 'merge')
+
+    elif branch_status_str.startswith('ahead'):
+        do_commit = ask(git_dir, 'Ahead. commit to new branch?',
+                        '<empty>  no',
+                        '<name>   create new branch',
+                        )
+        if do_commit:
+            git(git_dir, 'checkout', '-b', do_commit)
+            git(git_dir, 'commit', '-am', 'wip', may_fail=True)
+            git(git_dir, 'checkout', orig_branch)
+
+        do_reset = ask(git_dir, '%s: git reset --hard origin/%s?' % (orig_branch, orig_branch),
+                       '<empty>  no',
+                       'OK  yes (write OK in caps!)',
+                       valid_answers=('', 'OK'))
+
+        if do_reset == 'OK':
+            git(git_dir, 'reset', '--hard', 'origin/%s' % orig_branch)
+
+    elif branch_status_str.startswith('diverged'):
+        do_reset = ask(git_dir, 'Diverged.',
+                       '%s: git reset --hard origin/%s?' % (
+                           orig_branch, orig_branch),
+                       '<empty>  no',
+                       'OK  yes (write OK in caps!)',
+                       valid_answers=('', 'OK'))
+
+        if do_reset == 'OK':
+            git(git_dir, 'reset', '--hard', 'origin/%s' % orig_branch)
+
+    return orig_branch
+
+
+def cmd_rebase():
+    skipped = []
+    for git_dir in git_dirs():
+        try:
+            print('\n\n===== %s =====' % git_dir)
+            sys.stdout.flush()
+
+            branch = rebase(git_dir)
+            if branch != 'master':
+                git(git_dir, 'checkout', 'master')
+                rebase(git_dir)
+                git(git_dir, 'checkout', branch)
+
+        except SkipThisRepo:
+            print('\nSkipping %r' % git_dir)
+            skipped.append(git_dir)
+
+    print('\n\n==========\nrebase done.\n')
+    print_status()
+    if skipped:
+        print('\nskipped: %s' % ' '.join(skipped))
+
+
+def parse_args():
+    parser = argparse.ArgumentParser(description=doc)
+    sub = parser.add_subparsers(title='action', dest='action')
+    sub.required = True
+
+    # status
+    sub.add_parser('status', aliases=['st', 's'],
+                   help='show a branch summary and indicate modifications')
+
+    # fetch
+    fetch = sub.add_parser('fetch', aliases=['f'],
+                           help="run 'git fetch' in each clone (use before rebase)")
+    fetch.add_argument('remainder', nargs=argparse.REMAINDER,
+                       help='additional arguments to be passed to git fetch')
+
+    # rebase
+    sub.add_parser('rebase', aliases=['r', 're'],
+                   help='interactively ff-merge master, rebase current branches')
+
+    # sh
+    sh = sub.add_parser('sh',
+                        help='run shell command in each clone (`gits sh echo hi`)')
+    sh.add_argument('remainder', nargs=argparse.REMAINDER,
+                    help='command to run in each clone')
+
+    # do
+    do = sub.add_parser('do',
+                        help='run git command in each clone (`gits do clean -dxf`)')
+    do.add_argument('remainder', nargs=argparse.REMAINDER,
+                    help='git command to run in each clone')
+    return parser.parse_args()
+
+
+if __name__ == '__main__':
+    args = parse_args()
+    if args.action in ['status', 's', 'st']:
+        print_status()
+    elif args.action in ['fetch', 'f']:
+        cmd_do(['fetch'] + args.remainder)
+    elif args.action in ['rebase', 'r']:
+        cmd_rebase()
+    elif args.action == 'sh':
+        cmd_sh(args.remainder)
+    elif args.action == 'do':
+        cmd_do(args.remainder)
+
+# vim: shiftwidth=4 expandtab tabstop=4
diff --git a/src/s b/src/s
deleted file mode 100755
index f897bc1..0000000
--- a/src/s
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/usr/bin/env bash
-fastforwards=""
-
-Git() {
-  echo "git $@"
-  git $@
-  if [ "$?" != "0" ]; then
-    echo "GIT RETURNED ERROR!"
-    exit 1
-  fi
-}
-
-Git_may_fail() {
-  git $@
-}
-
-Git_branch() {
-  echo "$(Git -C "$dir" status)" | grep 'On branch' | sed 's/On branch //'
-}
-
-
-gitk_start() {
-  if [ -n "$DISPLAY" ]; then
-    gitk --all &
-    gitk_started="1"
-  fi
-}
-
-status() {
-  st="$(Git status)"
-  mods="$(echo "$st" | grep 'modified:')"
-
-  stline="$(echo "$st" | grep '\(behind\|ahead\|up-to-date\|diverged\)')"
-
-  echo "$br"
-  echo "$stline"
-}
-
-dance() {
-  echo
-  echo
-  br="$(Git_branch)"
-
-  echo "$dir"
-  cd "$dir"
-
-  status
-
-  if [ -z "$mods" -a -n "$(echo "$stline" | grep up-to-date)" ]; then
-    return 0
-  fi
-
-  gitk_start
-
-  if [ -n "$mods" ]; then
-    echo "Local mods"
-    echo "$mods"
-    echo
-    echo "commit to new branch? (enter name, empty = no)"
-    read wipbranch
-    if [ -n "$wipbranch" ]; then
-      Git checkout -b "$wipbranch"
-      Git_may_fail commit -am wip
-      #Git push --set-upstream origin "$wipbranch"
-      Git checkout "$br"
-    else
-      echo "commit to this branch $br ?  (empty = no, 'ok' = yes)"
-      read ok
-      if [ "x$ok" = xok ]; then
-        Git commit -am wip
-        #Git push
-      fi
-    fi
-
-    status
-
-    if [ -n "$mods" ]; then
-      return 0
-    fi
-  fi
-
-  if [ -n "$(echo "$stline" | grep behind)" ]; then
-    if [ -n "$(echo "$stline" | grep "and can be fast-forwarded")" ]; then
-      echo "fast forwarding..."
-      fastforwards="${fastforwards} $dir/$br:$(Git_may_fail rev-parse --short HEAD)"
-      ok="ok"
-    else
-      echo "Behind. git merge?  (empty = no, 'ok' = yes)"
-      read ok
-    fi
-    if [ "x$ok" = xok ]; then
-      Git merge
-    fi
-  elif [ -n "$(echo "$stline" | grep ahead)" ]; then
-    echo "Ahead. commit to new branch? (enter name, empty = no)"
-    read wipbranch
-    if [ -n "$wipbranch" ]; then
-      Git checkout -b "$wipbranch"
-      Git_may_fail commit -am wip
-      #Git push --set-upstream origin "$wipbranch"
-      Git checkout "$br"
-    fi
-    echo "$br: git reset --hard origin/$br ?  (empty = no, 'OK' IN CAPS = yes)"
-    read ok
-    if [ "x$ok" = xOK ]; then
-      Git reset --hard "origin/$br"
-    fi
-    return 0
-  elif [ -n "$(echo "$stline" | grep diverged)" ]; then
-    echo "Diverged. git reset --hard origin/$br ?  (empty = no, 'OK' IN CAPS = yes)"
-    read ok
-    if [ "x$ok" = xOK ]; then
-      wipbranch="neels/wip_$(date +%Y%m%d_%H%M)"
-      Git checkout -b "$wipbranch"
-      Git_may_fail commit -am wip
-      Git checkout "$br"
-      Git reset --hard "origin/$br"
-    fi
-  elif [ -z "$(echo "$stline" | grep up-to-date)" ]; then
-    echo "Nothing to do."
-    echo "$st"
-  fi
-
-}
-
-kill_gitk() {
-  if [ "$gitk_started" = "1" ]; then
-    kill %1
-    gitk_started="0"
-  fi
-}
-
-
-basedir="$(pwd)"
-gitk_started="0"
-for gitdir in */.git ; do
-  cd "$basedir"
-  dir="$(dirname "$gitdir")"
-
-  orig_branch="$(Git_branch)"
-
-  kill_gitk
-  dance
-  cd "$basedir"
-
-  if [ "$orig_branch" != master ]; then
-	kill_gitk
-	git -C "$dir" checkout master || continue
-	dance
-	cd "$basedir"
-	pwd
-	git -C "$dir" checkout "$orig_branch"
-  fi
-
-#  if [ "$dir" = "openbsc" ]; then
-#    kill_gitk
-#    Git checkout "sysmocom/iu"
-#    dance
-#  fi
-
-  sleep .1
-
-done
-
-kill_gitk
-
-echo
-echo
-./st
-
-if [ -n "$fastforwards" ]; then
-  echo
-  echo "FAST-FORWARDED: $fastforwards"
-fi
-
-# vim: shiftwidth=2 expandtab
diff --git a/src/st b/src/st
deleted file mode 100755
index a47de6b..0000000
--- a/src/st
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-git_dirs() {
-  for gitdir in */.git ; do
-    echo "$(dirname "$gitdir")"
-  done
-}
-
-./git_branch_summary.py $(git_dirs)
-# vim: shiftwidth=2 expandtab

-- 
To view, visit https://gerrit.osmocom.org/11560
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-dev
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I579e7af26d76d5c5d83b2349695456bc7b54f5a2
Gerrit-Change-Number: 11560
Gerrit-PatchSet: 11
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: osmith <osmith at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20181108/fba70449/attachment.html>


More information about the gerrit-log mailing list