diff --git a/.gitignore b/.gitignore index edc82d6..1f4e0d8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,9 @@ __pycache__ tags *.pyc make-* -src +src/* +!src/g +!src/e +!src/st +!src/s +!src/README diff --git a/src/README b/src/README new file mode 100644 index 0000000..4444824 --- /dev/null +++ b/src/README @@ -0,0 +1,129 @@ +This dir is intended to keep all the git clones. + +There are some handy scripts I use for my daily Osmocom development: + + ./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.) + +Examples: + +----------------------------------------------------------------------------- + +./g fetch # run 'git fetch' in each clone = fetch all from upstream + +===== libasn1c ===== +remote: Counting objects: 29, done +remote: Finding sources: 100% (26/26) +remote: Total 26 (delta 8), reused 22 (delta 8) +Unpacking objects: 100% (26/26), done. +From ssh://go/libasn1c + 4151e59..aaae8c7 master -> origin/master + +===== libosmo-abis ===== + +===== libosmo-netif ===== +remote: Counting objects: 105, done +remote: Finding sources: 100% (92/92) +remote: Total 92 (delta 54), reused 92 (delta 54) +Unpacking objects: 100% (92/92), done. +From ssh://go/libosmo-netif + 6032a35..e786055 master -> origin/master + + 058d3b7...89180ef pespin/jitterbuffer -> origin/pespin/jitterbuffer (forced update) + * [new branch] pespin/osmux-lostpkt -> origin/pespin/osmux-lostpkt + +===== libosmo-sccp ===== + +===== libosmocore ===== +remote: Counting objects: 36, done +remote: Finding sources: 100% (24/24) +remote: Total 24 (delta 18), reused 24 (delta 18) +Unpacking objects: 100% (24/24), done. +From ssh://go/libosmocore + 4a29f34..733810c master -> origin/master + +[...] + +----------------------------------------------------------------------------- + +./st # any modifications / updates? (e.g. useful after './g fetch') + # (checks only 'master' and the current checked-out branch) + + libasn1c master + libosmo-abis master +libosmo-netif master + libosmo-sccp MODS master[+1|-10] + libosmocore master + libsmpp34 master + openggsn master + osmo-bsc pre_release[+43|-43] + osmo-hlr master + osmo-iuh pre_release[+1] + osmo-mgw pre_release + osmo-msc pre_release + osmo-sgsn pre_release + +# This shows me that I have local mods in libosmo-sccp, while my local master +# branch has one commit that isn't on upstream ("+1"); but at the same time +# origin/master has moved on by 10 commits ("-10"). +# My osmo-bsc git is on branch 'pre_release', and apparently I have amended the +# 44th commit before pre_release's HEAD. +# And on osmo-iuh, I have one un-pushed local commit. + +----------------------------------------------------------------------------- + +./e 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. + + +libosmocore +master +Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. +Behind. git merge? (empty = no, 'ok' = yes) +ok # <-- type 'ok' and hit enter +git merge +Updating ff932bb..4a29f34 +Fast-forward + include/osmocom/gprs/gprs_rlc.h | 25 +++++++++++++++++++ + include/osmocom/gsm/tlv.h | 21 +++++++++++++++- + src/gsm/gprs_rlc.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/gsm/libosmogsm.map | 6 +++++ + 4 files changed, 141 insertions(+), 1 deletion(-) + + +libosmo-netif +master +Your branch is up-to-date with 'origin/master'. + + +libosmo-sccp +master +Your branch and 'origin/master' have diverged, +Diverged. git reset --hard origin/master ? (empty = no, 'ok' = yes) +# a 'gitk' opens; just hit 'enter' to keep local diverged commits. +# If you type 'ok', local mods are saved to a wip branch first. + +Local mods + modified: src/osmo_ss7_vty.c + +commit to new branch? (enter name, empty = no) + +commit to this branch master ? (empty = no, 'ok' = yes) + +[...] + +----------------------------------------------------------------------------- + + +Enjoy, + +~Neels + diff --git a/src/e b/src/e new file mode 100755 index 0000000..6606a90 --- /dev/null +++ b/src/e @@ -0,0 +1,10 @@ +#!/bin/sh +base="$PWD" +for gitdir in */.git ; do + cd "$base" + dir="$(dirname "$gitdir")" + echo + echo "===== $dir =====" + cd "$dir" + $@ +done diff --git a/src/g b/src/g new file mode 100755 index 0000000..ed30489 --- /dev/null +++ b/src/g @@ -0,0 +1,7 @@ +#!/bin/sh +for gitdir in */.git ; do + dir="$(dirname "$gitdir")" + echo + echo "===== $dir =====" + git -C "$dir" $@ +done diff --git a/src/git_branch_summary.py b/src/git_branch_summary.py new file mode 100755 index 0000000..6bd4378 --- /dev/null +++ b/src/git_branch_summary.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +import sys, subprocess, re + +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')).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')) + 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/s b/src/s new file mode 100755 index 0000000..2933164 --- /dev/null +++ b/src/s @@ -0,0 +1,154 @@ +#!/usr/bin/env bash +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 +} + +dance() { + echo + echo + br="$(Git_branch)" + + echo "$dir" + cd "$dir" + + st="$(Git status)" + mods="$(echo "$st" | grep 'modified:')" + + stline="$(echo "$st" | grep '\(behind\|ahead\|up-to-date\|diverged\)')" + + echo "$br" + echo "$stline" + + if [ -z "$mods" -a -n "$(echo "$stline" | grep up-to-date)" ]; then + return 0 + fi + + gitk_start + + if [ -n "$(echo "$stline" | grep behind)" ]; then + echo "Behind. git merge? (empty = no, 'ok' = yes)" + read ok + 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' = 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' = 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 + + 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" + return 0 + fi + + echo "commit to this branch $br ? (empty = no, 'ok' = yes)" + read ok + if [ "x$ok" = xok ]; then + Git commit -am wip + #Git push + return 0 + fi + 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 + +# vim: shiftwidth=2 expandtab diff --git a/src/st b/src/st new file mode 100755 index 0000000..a47de6b --- /dev/null +++ b/src/st @@ -0,0 +1,10 @@ +#!/bin/sh + +git_dirs() { + for gitdir in */.git ; do + echo "$(dirname "$gitdir")" + done +} + +./git_branch_summary.py $(git_dirs) +# vim: shiftwidth=2 expandtab