# setup_ours (no arguments)
setup_ours()
{
- if [ ! -s "$git_dir/info/gitattributes" ] || ! grep -q topmsg "$git_dir/info/gitattributes"; then
+ if [ ! -s "$git_dir/info/attributes" ] || ! grep -q topmsg "$git_dir/info/attributes"; then
{
echo -e ".topmsg\tmerge=ours"
echo -e ".topdeps\tmerge=ours"
- } >>"$git_dir/info/gitattributes"
+ } >>"$git_dir/info/attributes"
fi
if ! git config merge.ours.driver >/dev/null; then
git config merge.ours.name '"always keep ours" merge driver'
# to the branch (e.g. B_DIRTY B1 B2 NAME), one path per line,
# inner paths first. Innermost name can be ':' if the head is
# not in sync with the base.
+# It will also return non-zero status if NAME needs update.
+# If needs_update() hits missing dependencies, it will append
+# them to space-separated $missing_deps list and skip them.
needs_update()
{
- {
- git cat-file blob "$1:.topdeps" 2>/dev/null |
- while read _dep; do
- _dep_is_tgish=1
- git rev-parse --verify "refs/top-bases/$_dep" >/dev/null 2>&1 ||
- _dep_is_tgish=
-
- # Shoo shoo, keep our environment alone!
- [ -z "$_dep_is_tgish" ] || (needs_update "$_dep" "$@")
-
- _dep_base_uptodate=1
- if [ -n "$_dep_is_tgish" ]; then
- branch_contains "$_dep" "refs/top-bases/$_dep" || _dep_base_uptodate=
- fi
-
- if [ -z "$_dep_base_uptodate" ]; then
- # _dep needs to be synced with its base
- echo ": $_dep $*"
- elif ! branch_contains "refs/top-bases/$1" "$_dep"; then
- # Some new commits in _dep
- echo "$_dep $*"
- fi
- done
- } || : # $1 is not tracked by TopGit anymore
+ depsfile="$(mktemp)"
+ git cat-file blob "$1:.topdeps" >"$depsfile"
+ _ret=0
+ while read _dep; do
+ if ! git rev-parse --verify "$_dep" >/dev/null 2>&1; then
+ # All hope is lost
+ missing_deps="$missing_deps $_dep"
+ continue
+ fi
+
+ _dep_is_tgish=1
+ git rev-parse --verify "refs/top-bases/$_dep" >/dev/null 2>&1 ||
+ _dep_is_tgish=
+
+ # Shoo shoo, keep our environment alone!
+ [ -z "$_dep_is_tgish" ] ||
+ (needs_update "$_dep" "$@") ||
+ _ret=$?
+
+ _dep_base_uptodate=1
+ if [ -n "$_dep_is_tgish" ]; then
+ branch_contains "$_dep" "refs/top-bases/$_dep" || _dep_base_uptodate=
+ fi
+
+ if [ -z "$_dep_base_uptodate" ]; then
+ # _dep needs to be synced with its base
+ echo ": $_dep $*"
+ _ret=1
+ elif ! branch_contains "refs/top-bases/$1" "$_dep"; then
+ # Some new commits in _dep
+ echo "$_dep $*"
+ _ret=1
+ fi
+ done <"$depsfile"
+ missing_deps="${missing_deps# }"
+ rm "$depsfile"
+ return $_ret
}
# branch_empty NAME
git symbolic-ref HEAD "$_base"
}
+# Show the help messages.
+do_help()
+{
+ if [ -z "$1" ] ; then
+ ## Build available commands list for help output
+
+ cmds=
+ sep=
+ for cmd in "@cmddir@"/tg-*; do
+ ! [ -r "$cmd" ] && continue
+ # strip directory part and "tg-" prefix
+ cmd="$(basename "$cmd")"
+ cmd="${cmd#tg-}"
+ cmds="$cmds$sep$cmd"
+ sep="|"
+ done
+
+ echo "TopGit v0.1 - A different patch queue manager"
+ echo "Usage: tg ($cmds|help) ..."
+ elif [ -r "@sharedir@/tg-$1.txt" ] ; then
+ cat "@sharedir@/tg-$1.txt"
+ else
+ echo "`basename $0`: no help for $1" 1>&2
+ fi
+}
+
## Initial setup
setup_ours
setup_hook "pre-commit"
+[ -d "@cmddir@" ] ||
+ die "No command directory: '@cmddir@'"
## Dispatch
shift
case "$cmd" in
-help)
- echo "TopGit v0.1 - A different patch queue manager"
- echo "Usage: tg (create|delete|info|patch|summary|update|help) ..."
+help|--help|-h)
+ do_help "$1"
exit 1;;
-create|delete|info|patch|summary|update)
- . "@cmddir@"/tg-$cmd;;
--hooks-path)
# Internal command
echo "@hooksdir@";;
*)
- echo "Unknown subcommand: $cmd" >&2
- exit 1;;
+ [ -r "@cmddir@"/tg-$cmd ] || {
+ echo "Unknown subcommand: $cmd" >&2
+ exit 1
+ }
+ . "@cmddir@"/tg-$cmd;;
esac