<p>Neels Hofmeyr has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/11560">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">replace src/* git scripts with a single src/gits<br><br>I keep re-using this functionality in completely unrelated realms, and decided<br>to unify the oddly named scripts in a single 'gits' meta-repos tool, so I can<br>just symlink this script into my ~/bin and use it everywhere.<br><br>Change-Id: I579e7af26d76d5c5d83b2349695456bc7b54f5a2<br>---<br>M src/README<br>D src/e<br>D src/g<br>D src/git_branch_summary.py<br>A src/gits<br>D src/s<br>D src/st<br>7 files changed, 353 insertions(+), 298 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-dev refs/changes/60/11560/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/README b/src/README</span><br><span>index a2fbe81..f066561 100644</span><br><span>--- a/src/README</span><br><span>+++ b/src/README</span><br><span>@@ -11,12 +11,11 @@</span><br><span>       Pass a patch number seen on gerrit to fetch the latest patch set into</span><br><span>        your git clone. See top comment in the script.</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- ./g   run a git command in each source tree</span><br><span style="color: hsl(0, 100%, 40%);">- ./e   run an arbitrary shell command in each source tree</span><br><span style="color: hsl(0, 100%, 40%);">- ./st  show a brief branch and local mods status for each source tree</span><br><span style="color: hsl(0, 100%, 40%);">- ./s   walk through each source tree and use gitk as well as user interaction</span><br><span style="color: hsl(0, 100%, 40%);">-       to quickly fast-forward / reset changes coming in from upstream. (This</span><br><span style="color: hsl(0, 100%, 40%);">-       is potentially dangerous, but safe if you only hit enter every time.)</span><br><span style="color: hsl(120, 100%, 40%);">+ gits   Conveniently manage several git clones:</span><br><span style="color: hsl(120, 100%, 40%);">+        - run a git or shell command in each source tree</span><br><span style="color: hsl(120, 100%, 40%);">+ - show a brief branch and local mods status for each source tree</span><br><span style="color: hsl(120, 100%, 40%);">+      - merge / rebase / fast-forward each source tree interactively</span><br><span style="color: hsl(120, 100%, 40%);">+        See ./gits help</span><br><span> </span><br><span> Examples:</span><br><span> </span><br><span>@@ -54,7 +53,7 @@</span><br><span> </span><br><span> -----------------------------------------------------------------------------</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-./g fetch    # run 'git fetch' in each clone = fetch all from upstream</span><br><span style="color: hsl(120, 100%, 40%);">+./gits fetch    # run 'git fetch' in each clone = fetch all from upstream</span><br><span> </span><br><span> ===== libasn1c =====</span><br><span> remote: Counting objects: 29, done</span><br><span>@@ -90,7 +89,7 @@</span><br><span> </span><br><span> -----------------------------------------------------------------------------</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-./st         # any modifications / updates? (e.g. useful after './g fetch')</span><br><span style="color: hsl(120, 100%, 40%);">+./gits st    # any modifications / updates? (e.g. useful after './g fetch')</span><br><span>              # (checks only 'master' and the current checked-out branch)</span><br><span> </span><br><span>      libasn1c master</span><br><span>@@ -116,13 +115,13 @@</span><br><span> </span><br><span> -----------------------------------------------------------------------------</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-./e rm .version  # in each source tree, remove the local .version file</span><br><span style="color: hsl(120, 100%, 40%);">+./gits sh rm .version  # in each source tree, remove the local .version file</span><br><span> </span><br><span> -----------------------------------------------------------------------------</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-./s         # interactively try to fast-forward to upstream and/or save</span><br><span style="color: hsl(0, 100%, 40%);">-            # local modifications.</span><br><span style="color: hsl(0, 100%, 40%);">-            # If you just hit Enter all the time, nothing will be changed.</span><br><span style="color: hsl(120, 100%, 40%);">+./gits rebase  # interactively try to fast-forward to upstream and/or save</span><br><span style="color: hsl(120, 100%, 40%);">+               # local modifications.</span><br><span style="color: hsl(120, 100%, 40%);">+               # If you just hit Enter all the time, nothing dangerous will happen.</span><br><span> </span><br><span> </span><br><span> libosmocore</span><br><span>diff --git a/src/e b/src/e</span><br><span>deleted file mode 100755</span><br><span>index 4d32bf1..0000000</span><br><span>--- a/src/e</span><br><span>+++ /dev/null</span><br><span>@@ -1,15 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-#!/usr/bin/env python3</span><br><span style="color: hsl(0, 100%, 40%);">-import os</span><br><span style="color: hsl(0, 100%, 40%);">-import os.path</span><br><span style="color: hsl(0, 100%, 40%);">-import sys</span><br><span style="color: hsl(0, 100%, 40%);">-import subprocess</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-base_dir = os.getcwd()</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-for p in list(os.listdir('.')):</span><br><span style="color: hsl(0, 100%, 40%);">-        subdir = os.path.join(base_dir, p)</span><br><span style="color: hsl(0, 100%, 40%);">-      if not os.path.isdir(os.path.join(subdir, '.git')):</span><br><span style="color: hsl(0, 100%, 40%);">-             continue</span><br><span style="color: hsl(0, 100%, 40%);">-        print("\n===== %s =====" % p)</span><br><span style="color: hsl(0, 100%, 40%);">- os.chdir(subdir)</span><br><span style="color: hsl(0, 100%, 40%);">-        subprocess.call(sys.argv[1:])</span><br><span>diff --git a/src/g b/src/g</span><br><span>deleted file mode 100755</span><br><span>index bb9b693..0000000</span><br><span>--- a/src/g</span><br><span>+++ /dev/null</span><br><span>@@ -1,17 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-#!/usr/bin/env python3</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-import sys</span><br><span style="color: hsl(0, 100%, 40%);">-import os</span><br><span style="color: hsl(0, 100%, 40%);">-import subprocess</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-git_subdirs = []</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-for subdir in os.listdir():</span><br><span style="color: hsl(0, 100%, 40%);">-  if not os.path.isdir(os.path.join(subdir, '.git')):</span><br><span style="color: hsl(0, 100%, 40%);">-    continue</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  print('\n===== %s =====' % subdir)</span><br><span style="color: hsl(0, 100%, 40%);">-  sys.stdout.flush()</span><br><span style="color: hsl(0, 100%, 40%);">-  subprocess.call(['git', '-C', subdir] + sys.argv[1:])</span><br><span style="color: hsl(0, 100%, 40%);">-  sys.stdout.flush()</span><br><span style="color: hsl(0, 100%, 40%);">-  sys.stderr.flush()</span><br><span>diff --git a/src/git_branch_summary.py b/src/git_branch_summary.py</span><br><span>deleted file mode 100755</span><br><span>index 9d81f8b..0000000</span><br><span>--- a/src/git_branch_summary.py</span><br><span>+++ /dev/null</span><br><span>@@ -1,68 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-#!/usr/bin/env python</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-import sys, subprocess, re</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-if len(sys.argv) < 2:</span><br><span style="color: hsl(0, 100%, 40%);">-  print("Usage: %s <git_dir> [...]\nThis is mostly here for helping the 'st' script." % sys.argv[0])</span><br><span style="color: hsl(0, 100%, 40%);">-  exit(1)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-interesting_branch_names = [ 'master', 'sysmocom/iu', 'sysmocom/sccp', 'aper-prefix-onto-upstream' ]</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-re_branch_name = re.compile('^..([^ ]+) .*')</span><br><span style="color: hsl(0, 100%, 40%);">-re_ahead = re.compile('ahead [0-9]+|behind [0-9]+')</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-def branch_name(line):</span><br><span style="color: hsl(0, 100%, 40%);">-  m = re_branch_name.match(line)</span><br><span style="color: hsl(0, 100%, 40%);">-  return m.group(1)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-interesting = []</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-def do_one_git(git_dir):</span><br><span style="color: hsl(0, 100%, 40%);">-  global interesting</span><br><span style="color: hsl(0, 100%, 40%);">-  branch_strs = subprocess.check_output(('git', '-C', git_dir, 'branch', '-vv')).decode('utf-8').splitlines()</span><br><span style="color: hsl(0, 100%, 40%);">-  interesting_branches = []</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  for line in branch_strs:</span><br><span style="color: hsl(0, 100%, 40%);">-    name = branch_name(line)</span><br><span style="color: hsl(0, 100%, 40%);">-    current_branch = False</span><br><span style="color: hsl(0, 100%, 40%);">-    if line.startswith('*'):</span><br><span style="color: hsl(0, 100%, 40%);">-      current_branch = True</span><br><span style="color: hsl(0, 100%, 40%);">-    elif name not in interesting_branch_names:</span><br><span style="color: hsl(0, 100%, 40%);">-      continue</span><br><span style="color: hsl(0, 100%, 40%);">-    ahead = re_ahead.findall(line)</span><br><span style="color: hsl(0, 100%, 40%);">-    if not ahead and not current_branch:</span><br><span style="color: hsl(0, 100%, 40%);">-      continue</span><br><span style="color: hsl(0, 100%, 40%);">-    ahead = [x.replace('ahead ', '+').replace('behind ', '-') for x in ahead]</span><br><span style="color: hsl(0, 100%, 40%);">-    br = (current_branch, name, ahead)</span><br><span style="color: hsl(0, 100%, 40%);">-    if current_branch:</span><br><span style="color: hsl(0, 100%, 40%);">-      interesting_branches.insert(0, br)</span><br><span style="color: hsl(0, 100%, 40%);">-    else:</span><br><span style="color: hsl(0, 100%, 40%);">-      interesting_branches.append(br)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  status = subprocess.check_output(('git', '-C', git_dir, 'status')).decode()</span><br><span style="color: hsl(0, 100%, 40%);">-  has_mods = 'modified:' in status</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  interesting.append((git_dir, has_mods, interesting_branches))</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-for git_dir in sys.argv[1:]:</span><br><span style="color: hsl(0, 100%, 40%);">-  do_one_git(git_dir)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-first_col = max([len(git_dir) for git_dir, _, _ in interesting])</span><br><span style="color: hsl(0, 100%, 40%);">-first_col_fmt = '%' + str(first_col) + 's'</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-for git_dir, has_mods, interesting_branches in interesting:</span><br><span style="color: hsl(0, 100%, 40%);">-  strs = [first_col_fmt % git_dir,]</span><br><span style="color: hsl(0, 100%, 40%);">-  if has_mods:</span><br><span style="color: hsl(0, 100%, 40%);">-    strs.append('MODS')</span><br><span style="color: hsl(0, 100%, 40%);">-  for current_branch, name, ahead in interesting_branches:</span><br><span style="color: hsl(0, 100%, 40%);">-    br = []</span><br><span style="color: hsl(0, 100%, 40%);">-    br.append(name)</span><br><span style="color: hsl(0, 100%, 40%);">-    if ahead:</span><br><span style="color: hsl(0, 100%, 40%);">-      br.append('[%s]' % '|'.join(ahead))</span><br><span style="color: hsl(0, 100%, 40%);">-    strs.append(''.join(br))</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  print(' '.join(strs))</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-# vim: shiftwidth=2 expandtab tabstop=2</span><br><span>diff --git a/src/gits b/src/gits</span><br><span>new file mode 100755</span><br><span>index 0000000..7d7f253</span><br><span>--- /dev/null</span><br><span>+++ b/src/gits</span><br><span>@@ -0,0 +1,342 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#!/usr/bin/env python3</span><br><span style="color: hsl(120, 100%, 40%);">+import sys, subprocess, re, argparse, os</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+doc = '''gits: conveniently manage several git subdirectories.</span><br><span style="color: hsl(120, 100%, 40%);">+Instead of doing the 'cd foo; git status; cd ../bar; git status' dance, this</span><br><span style="color: hsl(120, 100%, 40%);">+helps to save your time with: status, fetch, rebase, ...</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+See 'gits help'</span><br><span style="color: hsl(120, 100%, 40%);">+'''</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+re_status_mods = re.compile('^\t(modified|deleted):.*')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def error(*msgs):</span><br><span style="color: hsl(120, 100%, 40%);">+  sys.stderr.write(''.join(msgs))</span><br><span style="color: hsl(120, 100%, 40%);">+  sys.stderr.write('\n')</span><br><span style="color: hsl(120, 100%, 40%);">+  exit(1)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def usage(*msgs):</span><br><span style="color: hsl(120, 100%, 40%);">+  global doc</span><br><span style="color: hsl(120, 100%, 40%);">+  error(doc, '\n\n', *msgs)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def git(git_dir, *args, may_fail=False, section_marker=False, show_cmd=True):</span><br><span style="color: hsl(120, 100%, 40%);">+  if section_marker:</span><br><span style="color: hsl(120, 100%, 40%);">+    print('\n===== %s =====' % git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+    sys.stdout.flush()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  cmd = ['git', '-C', git_dir] + list(args)</span><br><span style="color: hsl(120, 100%, 40%);">+  if show_cmd:</span><br><span style="color: hsl(120, 100%, 40%);">+    print(' '.join(cmd))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = subprocess.call(cmd)</span><br><span style="color: hsl(120, 100%, 40%);">+  if rc and not may_fail:</span><br><span style="color: hsl(120, 100%, 40%);">+    error('git returned error! command: git -C %r %s' % (git_dir, ' '.join(repr(arg) for arg in args)))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if section_marker:</span><br><span style="color: hsl(120, 100%, 40%);">+    sys.stdout.flush()</span><br><span style="color: hsl(120, 100%, 40%);">+    sys.stderr.flush()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def git_output(git_dir, *args):</span><br><span style="color: hsl(120, 100%, 40%);">+  return subprocess.check_output(['git', '-C', git_dir,] + list(args)).decode('utf-8')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def git_branch(git_dir):</span><br><span style="color: hsl(120, 100%, 40%);">+  re_branch_name = re.compile('On branch ([^ ]*)')</span><br><span style="color: hsl(120, 100%, 40%);">+  status = git_output(git_dir, 'status')</span><br><span style="color: hsl(120, 100%, 40%);">+  m = re_branch_name.find(status)</span><br><span style="color: hsl(120, 100%, 40%);">+  if not m:</span><br><span style="color: hsl(120, 100%, 40%);">+    error('No current branch in %r' % git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+  return m.group(1)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def git_status(git_dir):</span><br><span style="color: hsl(120, 100%, 40%);">+  status_lines = git_output(git_dir, 'status').splitlines()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  on_branch = None</span><br><span style="color: hsl(120, 100%, 40%);">+  branch_status_str = None</span><br><span style="color: hsl(120, 100%, 40%);">+  local_mods = False</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ON_BRANCH = 'On branch '</span><br><span style="color: hsl(120, 100%, 40%);">+  STATUS = 'Your branch'</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  for l in status_lines:</span><br><span style="color: hsl(120, 100%, 40%);">+    if l.startswith(ON_BRANCH):</span><br><span style="color: hsl(120, 100%, 40%);">+      if on_branch:</span><br><span style="color: hsl(120, 100%, 40%);">+        error('cannot parse status, more than one branch?')</span><br><span style="color: hsl(120, 100%, 40%);">+      on_branch = l[len(ON_BRANCH):]</span><br><span style="color: hsl(120, 100%, 40%);">+    elif l.startswith(STATUS):</span><br><span style="color: hsl(120, 100%, 40%);">+      if 'Your branch is up to date' in l:</span><br><span style="color: hsl(120, 100%, 40%);">+        branch_status_str = l</span><br><span style="color: hsl(120, 100%, 40%);">+      elif 'Your branch is ahead' in l:</span><br><span style="color: hsl(120, 100%, 40%);">+        branch_status_str = 'ahead: ' + l</span><br><span style="color: hsl(120, 100%, 40%);">+      elif 'Your branch is behind' in l:</span><br><span style="color: hsl(120, 100%, 40%);">+        branch_status_str = 'behind: ' + l</span><br><span style="color: hsl(120, 100%, 40%);">+      elif 'have diverged' in l:</span><br><span style="color: hsl(120, 100%, 40%);">+        branch_status_str = 'diverged: ' + l</span><br><span style="color: hsl(120, 100%, 40%);">+      else:</span><br><span style="color: hsl(120, 100%, 40%);">+        error('unknown status str: %r' % l)</span><br><span style="color: hsl(120, 100%, 40%);">+    else:</span><br><span style="color: hsl(120, 100%, 40%);">+      m = re_status_mods.match(l)</span><br><span style="color: hsl(120, 100%, 40%);">+      if m:</span><br><span style="color: hsl(120, 100%, 40%);">+        local_mods = True</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  print('branch: %s\n%r%s' % (on_branch, branch_status_str, '\nLOCAL MODS' if local_mods else ''))</span><br><span style="color: hsl(120, 100%, 40%);">+  return (on_branch, branch_status_str, local_mods)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def git_branch_summary(git_dir):</span><br><span style="color: hsl(120, 100%, 40%);">+  '''return a list of strings: [branchname, info0, info1,...]'''</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  interesting_branch_names = [ 'master' ]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  strs = [git_dir,]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  on_branch, branch_status_str, has_mods = git_status(git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if has_mods:</span><br><span style="color: hsl(120, 100%, 40%);">+    strs.append('MODS')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  branch_strs = git_output(git_dir, 'branch', '-vv').splitlines()</span><br><span style="color: hsl(120, 100%, 40%);">+  re_branch_name = re.compile('^..([^ ]+) .*')</span><br><span style="color: hsl(120, 100%, 40%);">+  re_ahead = re.compile('ahead [0-9]+|behind [0-9]+')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  for line in branch_strs:</span><br><span style="color: hsl(120, 100%, 40%);">+    m = re_branch_name.match(line)</span><br><span style="color: hsl(120, 100%, 40%);">+    name = m.group(1)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    current_branch = False</span><br><span style="color: hsl(120, 100%, 40%);">+    if line.startswith('*'):</span><br><span style="color: hsl(120, 100%, 40%);">+      current_branch = True</span><br><span style="color: hsl(120, 100%, 40%);">+    elif name not in interesting_branch_names:</span><br><span style="color: hsl(120, 100%, 40%);">+      continue</span><br><span style="color: hsl(120, 100%, 40%);">+    ahead = re_ahead.findall(line)</span><br><span style="color: hsl(120, 100%, 40%);">+    if not ahead and not current_branch:</span><br><span style="color: hsl(120, 100%, 40%);">+      continue</span><br><span style="color: hsl(120, 100%, 40%);">+    ahead = [x.replace('ahead ', '+').replace('behind ', '-') for x in ahead]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    branch_info = [name]</span><br><span style="color: hsl(120, 100%, 40%);">+    if ahead:</span><br><span style="color: hsl(120, 100%, 40%);">+      branch_info.append('[%s]' % '|'.join(ahead))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    strs.append(''.join(branch_info))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return strs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def format_summaries(summaries, sep0=' ', sep1=' '):</span><br><span style="color: hsl(120, 100%, 40%);">+  first_col = max([len(row[0]) for row in summaries])</span><br><span style="color: hsl(120, 100%, 40%);">+  first_col_fmt = '%' + str(first_col) + 's'</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  lines = []</span><br><span style="color: hsl(120, 100%, 40%);">+  for row in summaries:</span><br><span style="color: hsl(120, 100%, 40%);">+    lines.append('%s%s%s' % (first_col_fmt % row[0], sep0, sep1.join(row[1:])))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return '\n'.join(lines)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def git_dirs():</span><br><span style="color: hsl(120, 100%, 40%);">+  dirs = []</span><br><span style="color: hsl(120, 100%, 40%);">+  for sub in os.listdir():</span><br><span style="color: hsl(120, 100%, 40%);">+    git_path = os.path.join(sub, '.git')</span><br><span style="color: hsl(120, 100%, 40%);">+    if not os.path.isdir(git_path):</span><br><span style="color: hsl(120, 100%, 40%);">+      continue</span><br><span style="color: hsl(120, 100%, 40%);">+    dirs.append(sub)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if not dirs:</span><br><span style="color: hsl(120, 100%, 40%);">+    error('No subdirectories found that are git clones')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return dirs</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def cmd_help():</span><br><span style="color: hsl(120, 100%, 40%);">+  global commands</span><br><span style="color: hsl(120, 100%, 40%);">+  global aliases</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if len(sys.argv) > 2:</span><br><span style="color: hsl(120, 100%, 40%);">+    error('no arguments allowed')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  lines = []</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  for name, cmd in commands.items():</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    names = [name,]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    for alias_name, alias_for in aliases.items():</span><br><span style="color: hsl(120, 100%, 40%);">+      if alias_for == name:</span><br><span style="color: hsl(120, 100%, 40%);">+        names.append(alias_name)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    line = ['|'.join(names), ]</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    func, doc = cmd</span><br><span style="color: hsl(120, 100%, 40%);">+    line.append(doc)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    lines.append(line)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  lines.append(('<git-command>', "Run arbitrary git command in each clone, shortcut for 'do'"))</span><br><span style="color: hsl(120, 100%, 40%);">+  print(format_summaries(lines, ': '))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def cmd_status():</span><br><span style="color: hsl(120, 100%, 40%);">+  if len(sys.argv) > 2:</span><br><span style="color: hsl(120, 100%, 40%);">+    error('no arguments allowed')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  infos = [git_branch_summary(git_dir) for git_dir in git_dirs()]</span><br><span style="color: hsl(120, 100%, 40%);">+  print(format_summaries(infos))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def cmd_do(argv=None):</span><br><span style="color: hsl(120, 100%, 40%);">+  if argv is None:</span><br><span style="color: hsl(120, 100%, 40%);">+    argv = sys.argv[2:]</span><br><span style="color: hsl(120, 100%, 40%);">+  for git_dir in git_dirs():</span><br><span style="color: hsl(120, 100%, 40%);">+    git(git_dir, *argv, may_fail=True, section_marker=True)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def cmd_sh():</span><br><span style="color: hsl(120, 100%, 40%);">+  cmd = sys.argv[2:]</span><br><span style="color: hsl(120, 100%, 40%);">+  for git_dir in git_dirs():</span><br><span style="color: hsl(120, 100%, 40%);">+    print('\n===== %s =====' % git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+    sys.stdout.flush()</span><br><span style="color: hsl(120, 100%, 40%);">+    subprocess.call(cmd, cwd=git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+    sys.stdout.flush()</span><br><span style="color: hsl(120, 100%, 40%);">+    sys.stderr.flush()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class SkipThisRepos(Exception):</span><br><span style="color: hsl(120, 100%, 40%);">+  pass</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def ask(git_dir, *question, valid_answers=('*',)):</span><br><span style="color: hsl(120, 100%, 40%);">+  while True:</span><br><span style="color: hsl(120, 100%, 40%);">+    print('\n' + '\n  '.join(question))</span><br><span style="color: hsl(120, 100%, 40%);">+    print('  ' + '\n  '.join((</span><br><span style="color: hsl(120, 100%, 40%);">+      's  skip this repos',</span><br><span style="color: hsl(120, 100%, 40%);">+      't  show in tig',</span><br><span style="color: hsl(120, 100%, 40%);">+      'g  show in gitk',</span><br><span style="color: hsl(120, 100%, 40%);">+      )))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    answer = sys.stdin.readline().strip()</span><br><span style="color: hsl(120, 100%, 40%);">+    if answer == 's':</span><br><span style="color: hsl(120, 100%, 40%);">+      raise SkipThisRepos()</span><br><span style="color: hsl(120, 100%, 40%);">+    if answer == 't':</span><br><span style="color: hsl(120, 100%, 40%);">+      subprocess.call(('tig', '--all'), cwd=git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+      continue</span><br><span style="color: hsl(120, 100%, 40%);">+    if answer == 'g':</span><br><span style="color: hsl(120, 100%, 40%);">+      subprocess.call(('gitk', '--all'), cwd=git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+      continue</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    for v in valid_answers:</span><br><span style="color: hsl(120, 100%, 40%);">+      if v == answer:</span><br><span style="color: hsl(120, 100%, 40%);">+        return answer</span><br><span style="color: hsl(120, 100%, 40%);">+      if v == '*':</span><br><span style="color: hsl(120, 100%, 40%);">+        return answer</span><br><span style="color: hsl(120, 100%, 40%);">+      if v == '+' and len(answer) > 0:</span><br><span style="color: hsl(120, 100%, 40%);">+        return answer</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def rebase(git_dir):</span><br><span style="color: hsl(120, 100%, 40%);">+  orig_branch, branch_status_str, local_mods = git_status(git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if local_mods:</span><br><span style="color: hsl(120, 100%, 40%);">+    do_commit = ask(git_dir, 'Local mods.',</span><br><span style="color: hsl(120, 100%, 40%);">+      'c  commit to this branch',</span><br><span style="color: hsl(120, 100%, 40%);">+      '<name>  commit to new branch',)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if do_commit == 'c':</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'commit', '-am', 'wip', may_fail=True)</span><br><span style="color: hsl(120, 100%, 40%);">+    else:</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'checkout', '-b', do_commit)</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'commit', '-am', 'wip', may_fail=True)</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'checkout', orig_branch)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    _, _, local_mods = git_status(git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if local_mods:</span><br><span style="color: hsl(120, 100%, 40%);">+      print('There still are local modifications')</span><br><span style="color: hsl(120, 100%, 40%);">+      raise SkipThisRepos()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if branch_status_str is None:</span><br><span style="color: hsl(120, 100%, 40%);">+    print('there is no upstream branch for %r' % orig_branch)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  elif branch_status_str.startswith('behind'):</span><br><span style="color: hsl(120, 100%, 40%);">+    if 'and can be fast-forwarded' in branch_status_str:</span><br><span style="color: hsl(120, 100%, 40%);">+      print('fast-forwarding...')</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'merge')</span><br><span style="color: hsl(120, 100%, 40%);">+    else:</span><br><span style="color: hsl(120, 100%, 40%);">+      do_merge = ask(git_dir, 'Behind. git merge?',</span><br><span style="color: hsl(120, 100%, 40%);">+        "<empty>  don't merge",</span><br><span style="color: hsl(120, 100%, 40%);">+        'ok  git merge',</span><br><span style="color: hsl(120, 100%, 40%);">+        valid_answers=('', 'ok')</span><br><span style="color: hsl(120, 100%, 40%);">+        )</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if do_merge == 'ok':</span><br><span style="color: hsl(120, 100%, 40%);">+        git(git_dir, 'merge')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  elif branch_status_str.startswith('ahead'):</span><br><span style="color: hsl(120, 100%, 40%);">+    do_commit = ask(git_dir, 'Ahead. commit to new branch?',</span><br><span style="color: hsl(120, 100%, 40%);">+      '<empty>  no',</span><br><span style="color: hsl(120, 100%, 40%);">+      '<name>   create new branch',</span><br><span style="color: hsl(120, 100%, 40%);">+      )</span><br><span style="color: hsl(120, 100%, 40%);">+    if do_commit:</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'checkout', '-b', do_commit)</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'commit', '-am', 'wip', may_fail=True)</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'checkout', orig_branch)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    do_reset = ask(git_dir, '%s: git reset --hard origin/%s?' % (orig_branch, orig_branch),</span><br><span style="color: hsl(120, 100%, 40%);">+      '<empty>  no',</span><br><span style="color: hsl(120, 100%, 40%);">+      'OK  yes (write OK in caps!)',</span><br><span style="color: hsl(120, 100%, 40%);">+      valid_answers=('', 'OK'))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if do_reset == 'OK':</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'reset', '--hard', 'origin/%s' % orig_branch)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  elif branch_status_str.startswith('diverged'):</span><br><span style="color: hsl(120, 100%, 40%);">+    do_reset = ask(git_dir, 'Diverged.',</span><br><span style="color: hsl(120, 100%, 40%);">+      '%s: git reset --hard origin/%s?' % (orig_branch, orig_branch),</span><br><span style="color: hsl(120, 100%, 40%);">+      '<empty>  no',</span><br><span style="color: hsl(120, 100%, 40%);">+      'OK  yes (write OK in caps!)',</span><br><span style="color: hsl(120, 100%, 40%);">+      valid_answers=('', 'OK'))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if do_reset == 'OK':</span><br><span style="color: hsl(120, 100%, 40%);">+      git(git_dir, 'reset', '--hard', 'origin/%s' % orig_branch)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return orig_branch</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+def cmd_rebase():</span><br><span style="color: hsl(120, 100%, 40%);">+  for git_dir in git_dirs():</span><br><span style="color: hsl(120, 100%, 40%);">+    try:</span><br><span style="color: hsl(120, 100%, 40%);">+      print('\n\n===== %s =====' % git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+      sys.stdout.flush()</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      branch = rebase(git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+      if branch != 'master':</span><br><span style="color: hsl(120, 100%, 40%);">+        git(git_dir, 'checkout', 'master')</span><br><span style="color: hsl(120, 100%, 40%);">+        rebase(git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+        git(git_dir, 'checkout', branch)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    except SkipThisRepos:</span><br><span style="color: hsl(120, 100%, 40%);">+      print('\nSkipping %r' % git_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+commands = {</span><br><span style="color: hsl(120, 100%, 40%);">+  'help': (cmd_help, 'List commands.'),</span><br><span style="color: hsl(120, 100%, 40%);">+  'status': (cmd_status, 'Show a branch summary and indicate modifications.'),</span><br><span style="color: hsl(120, 100%, 40%);">+  'rebase': (cmd_rebase, 'Interactively merge master and rebase current branch.'),</span><br><span style="color: hsl(120, 100%, 40%);">+  'sh': (cmd_sh, 'Run arbitrary shell command in each clone'),</span><br><span style="color: hsl(120, 100%, 40%);">+  'do': (cmd_do, 'Run arbitrary git command in each clone'),</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+aliases = {</span><br><span style="color: hsl(120, 100%, 40%);">+  'st': 'status',</span><br><span style="color: hsl(120, 100%, 40%);">+  'r': 'rebase',</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+if __name__ == '__main__':</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if len(sys.argv) < 2:</span><br><span style="color: hsl(120, 100%, 40%);">+    usage('Pass at least one argument to tell me what to do.')</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  command_str = sys.argv[1]</span><br><span style="color: hsl(120, 100%, 40%);">+  alias_for = aliases.get(command_str)</span><br><span style="color: hsl(120, 100%, 40%);">+  if alias_for:</span><br><span style="color: hsl(120, 100%, 40%);">+    command_str = alias_for</span><br><span style="color: hsl(120, 100%, 40%);">+  command = commands.get(command_str)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if command:</span><br><span style="color: hsl(120, 100%, 40%);">+    func, doc = command</span><br><span style="color: hsl(120, 100%, 40%);">+    func()</span><br><span style="color: hsl(120, 100%, 40%);">+  else:</span><br><span style="color: hsl(120, 100%, 40%);">+    # run arbitrary git command</span><br><span style="color: hsl(120, 100%, 40%);">+    cmd_do(sys.argv[1:])</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+# vim: shiftwidth=2 expandtab tabstop=2</span><br><span>diff --git a/src/s b/src/s</span><br><span>deleted file mode 100755</span><br><span>index f897bc1..0000000</span><br><span>--- a/src/s</span><br><span>+++ /dev/null</span><br><span>@@ -1,176 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-#!/usr/bin/env bash</span><br><span style="color: hsl(0, 100%, 40%);">-fastforwards=""</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Git() {</span><br><span style="color: hsl(0, 100%, 40%);">-  echo "git $@"</span><br><span style="color: hsl(0, 100%, 40%);">-  git $@</span><br><span style="color: hsl(0, 100%, 40%);">-  if [ "$?" != "0" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "GIT RETURNED ERROR!"</span><br><span style="color: hsl(0, 100%, 40%);">-    exit 1</span><br><span style="color: hsl(0, 100%, 40%);">-  fi</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Git_may_fail() {</span><br><span style="color: hsl(0, 100%, 40%);">-  git $@</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-Git_branch() {</span><br><span style="color: hsl(0, 100%, 40%);">-  echo "$(Git -C "$dir" status)" | grep 'On branch' | sed 's/On branch //'</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-gitk_start() {</span><br><span style="color: hsl(0, 100%, 40%);">-  if [ -n "$DISPLAY" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-    gitk --all &</span><br><span style="color: hsl(0, 100%, 40%);">-    gitk_started="1"</span><br><span style="color: hsl(0, 100%, 40%);">-  fi</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-status() {</span><br><span style="color: hsl(0, 100%, 40%);">-  st="$(Git status)"</span><br><span style="color: hsl(0, 100%, 40%);">-  mods="$(echo "$st" | grep 'modified:')"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  stline="$(echo "$st" | grep '\(behind\|ahead\|up-to-date\|diverged\)')"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  echo "$br"</span><br><span style="color: hsl(0, 100%, 40%);">-  echo "$stline"</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-dance() {</span><br><span style="color: hsl(0, 100%, 40%);">-  echo</span><br><span style="color: hsl(0, 100%, 40%);">-  echo</span><br><span style="color: hsl(0, 100%, 40%);">-  br="$(Git_branch)"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  echo "$dir"</span><br><span style="color: hsl(0, 100%, 40%);">-  cd "$dir"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  status</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if [ -z "$mods" -a -n "$(echo "$stline" | grep up-to-date)" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-    return 0</span><br><span style="color: hsl(0, 100%, 40%);">-  fi</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  gitk_start</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if [ -n "$mods" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "Local mods"</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "$mods"</span><br><span style="color: hsl(0, 100%, 40%);">-    echo</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "commit to new branch? (enter name, empty = no)"</span><br><span style="color: hsl(0, 100%, 40%);">-    read wipbranch</span><br><span style="color: hsl(0, 100%, 40%);">-    if [ -n "$wipbranch" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-      Git checkout -b "$wipbranch"</span><br><span style="color: hsl(0, 100%, 40%);">-      Git_may_fail commit -am wip</span><br><span style="color: hsl(0, 100%, 40%);">-      #Git push --set-upstream origin "$wipbranch"</span><br><span style="color: hsl(0, 100%, 40%);">-      Git checkout "$br"</span><br><span style="color: hsl(0, 100%, 40%);">-    else</span><br><span style="color: hsl(0, 100%, 40%);">-      echo "commit to this branch $br ?  (empty = no, 'ok' = yes)"</span><br><span style="color: hsl(0, 100%, 40%);">-      read ok</span><br><span style="color: hsl(0, 100%, 40%);">-      if [ "x$ok" = xok ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-        Git commit -am wip</span><br><span style="color: hsl(0, 100%, 40%);">-        #Git push</span><br><span style="color: hsl(0, 100%, 40%);">-      fi</span><br><span style="color: hsl(0, 100%, 40%);">-    fi</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    status</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if [ -n "$mods" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0</span><br><span style="color: hsl(0, 100%, 40%);">-    fi</span><br><span style="color: hsl(0, 100%, 40%);">-  fi</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if [ -n "$(echo "$stline" | grep behind)" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-    if [ -n "$(echo "$stline" | grep "and can be fast-forwarded")" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-      echo "fast forwarding..."</span><br><span style="color: hsl(0, 100%, 40%);">-      fastforwards="${fastforwards} $dir/$br:$(Git_may_fail rev-parse --short HEAD)"</span><br><span style="color: hsl(0, 100%, 40%);">-      ok="ok"</span><br><span style="color: hsl(0, 100%, 40%);">-    else</span><br><span style="color: hsl(0, 100%, 40%);">-      echo "Behind. git merge?  (empty = no, 'ok' = yes)"</span><br><span style="color: hsl(0, 100%, 40%);">-      read ok</span><br><span style="color: hsl(0, 100%, 40%);">-    fi</span><br><span style="color: hsl(0, 100%, 40%);">-    if [ "x$ok" = xok ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-      Git merge</span><br><span style="color: hsl(0, 100%, 40%);">-    fi</span><br><span style="color: hsl(0, 100%, 40%);">-  elif [ -n "$(echo "$stline" | grep ahead)" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "Ahead. commit to new branch? (enter name, empty = no)"</span><br><span style="color: hsl(0, 100%, 40%);">-    read wipbranch</span><br><span style="color: hsl(0, 100%, 40%);">-    if [ -n "$wipbranch" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-      Git checkout -b "$wipbranch"</span><br><span style="color: hsl(0, 100%, 40%);">-      Git_may_fail commit -am wip</span><br><span style="color: hsl(0, 100%, 40%);">-      #Git push --set-upstream origin "$wipbranch"</span><br><span style="color: hsl(0, 100%, 40%);">-      Git checkout "$br"</span><br><span style="color: hsl(0, 100%, 40%);">-    fi</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "$br: git reset --hard origin/$br ?  (empty = no, 'OK' IN CAPS = yes)"</span><br><span style="color: hsl(0, 100%, 40%);">-    read ok</span><br><span style="color: hsl(0, 100%, 40%);">-    if [ "x$ok" = xOK ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-      Git reset --hard "origin/$br"</span><br><span style="color: hsl(0, 100%, 40%);">-    fi</span><br><span style="color: hsl(0, 100%, 40%);">-    return 0</span><br><span style="color: hsl(0, 100%, 40%);">-  elif [ -n "$(echo "$stline" | grep diverged)" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "Diverged. git reset --hard origin/$br ?  (empty = no, 'OK' IN CAPS = yes)"</span><br><span style="color: hsl(0, 100%, 40%);">-    read ok</span><br><span style="color: hsl(0, 100%, 40%);">-    if [ "x$ok" = xOK ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-      wipbranch="neels/wip_$(date +%Y%m%d_%H%M)"</span><br><span style="color: hsl(0, 100%, 40%);">-      Git checkout -b "$wipbranch"</span><br><span style="color: hsl(0, 100%, 40%);">-      Git_may_fail commit -am wip</span><br><span style="color: hsl(0, 100%, 40%);">-      Git checkout "$br"</span><br><span style="color: hsl(0, 100%, 40%);">-      Git reset --hard "origin/$br"</span><br><span style="color: hsl(0, 100%, 40%);">-    fi</span><br><span style="color: hsl(0, 100%, 40%);">-  elif [ -z "$(echo "$stline" | grep up-to-date)" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "Nothing to do."</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "$st"</span><br><span style="color: hsl(0, 100%, 40%);">-  fi</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-kill_gitk() {</span><br><span style="color: hsl(0, 100%, 40%);">-  if [ "$gitk_started" = "1" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-    kill %1</span><br><span style="color: hsl(0, 100%, 40%);">-    gitk_started="0"</span><br><span style="color: hsl(0, 100%, 40%);">-  fi</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-basedir="$(pwd)"</span><br><span style="color: hsl(0, 100%, 40%);">-gitk_started="0"</span><br><span style="color: hsl(0, 100%, 40%);">-for gitdir in */.git ; do</span><br><span style="color: hsl(0, 100%, 40%);">-  cd "$basedir"</span><br><span style="color: hsl(0, 100%, 40%);">-  dir="$(dirname "$gitdir")"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  orig_branch="$(Git_branch)"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  kill_gitk</span><br><span style="color: hsl(0, 100%, 40%);">-  dance</span><br><span style="color: hsl(0, 100%, 40%);">-  cd "$basedir"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if [ "$orig_branch" != master ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-     kill_gitk</span><br><span style="color: hsl(0, 100%, 40%);">-       git -C "$dir" checkout master || continue</span><br><span style="color: hsl(0, 100%, 40%);">-     dance</span><br><span style="color: hsl(0, 100%, 40%);">-   cd "$basedir"</span><br><span style="color: hsl(0, 100%, 40%);">- pwd</span><br><span style="color: hsl(0, 100%, 40%);">-     git -C "$dir" checkout "$orig_branch"</span><br><span style="color: hsl(0, 100%, 40%);">-  fi</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#  if [ "$dir" = "openbsc" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-#    kill_gitk</span><br><span style="color: hsl(0, 100%, 40%);">-#    Git checkout "sysmocom/iu"</span><br><span style="color: hsl(0, 100%, 40%);">-#    dance</span><br><span style="color: hsl(0, 100%, 40%);">-#  fi</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  sleep .1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-done</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-kill_gitk</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-echo</span><br><span style="color: hsl(0, 100%, 40%);">-echo</span><br><span style="color: hsl(0, 100%, 40%);">-./st</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-if [ -n "$fastforwards" ]; then</span><br><span style="color: hsl(0, 100%, 40%);">-  echo</span><br><span style="color: hsl(0, 100%, 40%);">-  echo "FAST-FORWARDED: $fastforwards"</span><br><span style="color: hsl(0, 100%, 40%);">-fi</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-# vim: shiftwidth=2 expandtab</span><br><span>diff --git a/src/st b/src/st</span><br><span>deleted file mode 100755</span><br><span>index a47de6b..0000000</span><br><span>--- a/src/st</span><br><span>+++ /dev/null</span><br><span>@@ -1,10 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-#!/bin/sh</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-git_dirs() {</span><br><span style="color: hsl(0, 100%, 40%);">-  for gitdir in */.git ; do</span><br><span style="color: hsl(0, 100%, 40%);">-    echo "$(dirname "$gitdir")"</span><br><span style="color: hsl(0, 100%, 40%);">-  done</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-./git_branch_summary.py $(git_dirs)</span><br><span style="color: hsl(0, 100%, 40%);">-# vim: shiftwidth=2 expandtab</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11560">change 11560</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/11560"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-dev </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I579e7af26d76d5c5d83b2349695456bc7b54f5a2 </div>
<div style="display:none"> Gerrit-Change-Number: 11560 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>