From: martin f. krafft Date: Mon, 17 Nov 2008 21:55:07 +0000 (+0100) Subject: Merge commit 'refs/top-bases/debian/locations' into debian/locations X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=topgit.git;a=commitdiff_plain;h=ed5f8376b25da3793b40ce660f3ab8eca9f0cb7f;hp=5aa8cf9d4fba8b6dbbd7878eb78b2600e3736b9a Merge commit 'refs/top-bases/debian/locations' into debian/locations Conflicts: Makefile --- diff --git a/Makefile b/Makefile index 835811e..31cc98e 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,16 @@ -prefix = $(HOME) -bindir = $(prefix)/bin -cmddir = $(prefix)/share/topgit -docdir = $(prefix)/share/doc/topgit -hooksdir = $(cmddir)/hooks +prefix ?= $(HOME) +bindir := $(prefix)/bin +cmddir := $(prefix)/share/topgit +docdir := $(prefix)/share/doc/topgit +hooksdir := $(cmddir)/hooks -commands_in = $(wildcard tg-*.sh) +commands_in := $(wildcard tg-*.sh) hooks_in = hooks/pre-commit.sh -commands_out = $(patsubst %.sh,%,$(commands_in)) -hooks_out = $(patsubst %.sh,%,$(hooks_in)) -help_out = $(patsubst %.sh,%.txt,$(commands_in)) +commands_out := $(patsubst %.sh,%,$(commands_in)) +hooks_out := $(patsubst %.sh,%,$(hooks_in)) +help_out := $(patsubst %.sh,%.txt,$(commands_in)) all:: tg $(commands_out) $(hooks_out) $(help_out) diff --git a/README b/README index 1893dc0..5bfe3ee 100644 --- a/README +++ b/README @@ -49,7 +49,7 @@ branch. In order to flexibly accomodate even complex scenarios when you track many patches where many are independent but some depend on others, TopGit ignores the ancient Quilt heritage of patch series and instead allows the patches to freely form graphs (DAGs just like -Git history itself, only "one lever higher"). For now, you have +Git history itself, only "one level higher"). For now, you have to manually specify which patches does the current one depend on, but TopGit might help you with that in the future in a darcs-like fashion. @@ -266,6 +266,8 @@ tg depend adjusting '.topmsg', prepare them in the index before calling 'tg depend add'. + TODO: Subcommand for removing dependencies, obviously + tg info ~~~~~~~ Show a summary information about the current or specified @@ -298,6 +300,8 @@ tg mail its documentation for details on how to setup email for git. You can pass arbitrary options to this command through the '-s' parameter, but you must double-quote everything. + The '-r' parameter with msgid can be used to generate in-reply-to + and reference headers to an earlier mail. TODO: 'tg mail patchfile' to mail an already exported patch TODO: mailing patch series @@ -329,8 +333,14 @@ tg summary '!' marks that it has missing dependencies (even recursively), 'B' marks that it is out-of-date wrt. its base). + This can take long time to accurately determine all the relevant + information about each branch; you can pass '-t' to get just + terse list of topic branch names quickly. Alternately, you can + pass '--graphviz' to get a dot-suitable output to draw a dependency + graph between the topic branches. + TODO: Speed up by an order of magnitude - TODO: Graph view + TODO: Text graph view tg export ~~~~~~~~~ @@ -413,12 +423,17 @@ tg import ~~~~~~~~~ Import commits within the given revision range into TopGit, creating one topic branch per commit, the dependencies forming - a linear sequence starting on your current branch. + a linear sequence starting on your current branch (or a branch + specified by the '-d' parameter). The branch names are auto-guessed from the commit messages and prefixed by t/ by default; use '-p PREFIX' to specify an alternative prefix (even an empty one). + Alternatively, you can use the '-s NAME' parameter to specify + the name of target branch; the command will then take one more + argument describing a single commit to import. + tg update ~~~~~~~~~ Update the current topic branch wrt. changes in the branches @@ -478,7 +493,10 @@ can be prefilled from various optional topgit.* config options. .topdeps: Contains the one-per-line list of branches your patch depends on, pre-seeded with `tg create`. (Continuously updated) merge of these branches will be the "base" of your topic -branch. +branch. DO NOT EDIT THIS FILE MANUALLY!!! If you do so, you need +to know exactly what are you doing, since this file must stay in +sync with the Git history information, otherwise very bad things +will happen. TopGit also automagically installs a bunch of custom commit-related hooks that will verify if you are committing the .top* files in sane diff --git a/contrib/tg-completion.bash b/contrib/tg-completion.bash new file mode 100755 index 0000000..67f820e --- /dev/null +++ b/contrib/tg-completion.bash @@ -0,0 +1,450 @@ +# +# bash completion support for TopGit. +# +# Copyright (C) 2008 Jonas Fonseca +# Copyright (C) 2006,2007 Shawn O. Pearce +# Based git's git-completion.sh: http://repo.or.cz/w/git/fastimport.git +# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/). +# Distributed under the GNU General Public License, version 2.0. +# +# To use these routines: +# +# 1) Copy this file to somewhere (e.g. ~/.tg-completion.sh). +# 2) Source it from your ~/.bashrc. +# +# Note: Make sure the tg script is in your PATH before you source this +# script, so it can properly setup cached values. + +case "$COMP_WORDBREAKS" in +*:*) : great ;; +*) COMP_WORDBREAKS="$COMP_WORDBREAKS:" +esac + +### {{{ Utilities + +__tgdir () +{ + if [ -z "$1" ]; then + if [ -n "$__tg_dir" ]; then + echo "$__tg_dir" + elif [ -d .git ]; then + echo .git + else + git rev-parse --git-dir 2>/dev/null + fi + elif [ -d "$1/.git" ]; then + echo "$1/.git" + else + echo "$1" + fi +} + +__tgcomp_1 () +{ + local c IFS=' '$'\t'$'\n' + for c in $1; do + case "$c$2" in + --*=*) printf %s$'\n' "$c$2" ;; + *.) printf %s$'\n' "$c$2" ;; + *) printf %s$'\n' "$c$2 " ;; + esac + done +} + +__tgcomp () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + if [ $# -gt 2 ]; then + cur="$3" + fi + case "$cur" in + --*=) + COMPREPLY=() + ;; + *) + local IFS=$'\n' + COMPREPLY=($(compgen -P "$2" \ + -W "$(__tgcomp_1 "$1" "$4")" \ + -- "$cur")) + ;; + esac +} + +__tg_heads () +{ + local cmd i is_hash=y dir="$(__tgdir "$1")" + if [ -d "$dir" ]; then + git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ + refs/heads + return + fi + for i in $(git ls-remote "$1" 2>/dev/null); do + case "$is_hash,$i" in + y,*) is_hash=n ;; + n,*^{}) is_hash=y ;; + n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; + n,*) is_hash=y; echo "$i" ;; + esac + done +} + +__tg_refs () +{ + local cmd i is_hash=y dir="$(__tgdir "$1")" + if [ -d "$dir" ]; then + if [ -e "$dir/HEAD" ]; then echo HEAD; fi + git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ + refs/tags refs/heads refs/remotes + return + fi + for i in $(git ls-remote "$dir" 2>/dev/null); do + case "$is_hash,$i" in + y,*) is_hash=n ;; + n,*^{}) is_hash=y ;; + n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;; + n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;; + n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;; + n,*) is_hash=y; echo "$i" ;; + esac + done +} + +__tg_refs2 () +{ + local i + for i in $(__tg_refs "$1"); do + echo "$i:$i" + done +} + +__tg_refs_remotes () +{ + local cmd i is_hash=y + for i in $(git ls-remote "$1" 2>/dev/null); do + case "$is_hash,$i" in + n,refs/heads/*) + is_hash=y + echo "$i:refs/remotes/$1/${i#refs/heads/}" + ;; + y,*) is_hash=n ;; + n,*^{}) is_hash=y ;; + n,refs/tags/*) is_hash=y;; + n,*) is_hash=y; ;; + esac + done +} + +__tg_remotes () +{ + local i ngoff IFS=$'\n' d="$(__tgdir)" + shopt -q nullglob || ngoff=1 + shopt -s nullglob + for i in "$d/remotes"/*; do + echo ${i#$d/remotes/} + done + [ "$ngoff" ] && shopt -u nullglob + for i in $(git --git-dir="$d" config --list); do + case "$i" in + remote.*.url=*) + i="${i#remote.}" + echo "${i/.url=*/}" + ;; + esac + done +} + +__tg_find_subcommand () +{ + local word subcommand c=1 + + while [ $c -lt $COMP_CWORD ]; do + word="${COMP_WORDS[c]}" + for subcommand in $1; do + if [ "$subcommand" = "$word" ]; then + echo "$subcommand" + return + fi + done + c=$((++c)) + done +} + +__tg_complete_revlist () +{ + local pfx cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + *...*) + pfx="${cur%...*}..." + cur="${cur#*...}" + __tgcomp "$(__tg_refs)" "$pfx" "$cur" + ;; + *..*) + pfx="${cur%..*}.." + cur="${cur#*..}" + __tgcomp "$(__tg_refs)" "$pfx" "$cur" + ;; + *) + __tgcomp "$(__tg_refs)" + ;; + esac +} + +__tg_topics () +{ + tg summary -t +} + +__tg_commands () +{ + if [ -n "$__tg_all_commandlist" ]; then + echo "$__tg_all_commandlist" + return + fi + local i IFS=" "$'\n' + for i in $(tg help | sed -n 's/^Usage:.*(\(.*\)).*/\1/p' | tr '|' ' ') + do + case $i in + *--*) : helper pattern;; + *) echo $i;; + esac + done +} +__tg_all_commandlist= +__tg_all_commandlist="$(__tg_commands 2>/dev/null)" + +__tg_complete_arg () +{ + if [ $COMP_CWORD -gt 2 ] && [ "${COMP_WORDS[$COMP_CWORD - 1]}" = "$1" ]; then + return 0 + fi + return 1 +} + +### }}} +### {{{ Commands + +_tg_create () +{ + local cmd="$1" + local cur="${COMP_WORDS[COMP_CWORD]}" + + # Name must be the first arg after the create command + if [ $((cmd + 1)) = $COMP_CWORD ]; then + __tgcomp "$(__tg_topics)" + return + fi + + __tg_complete_arg "-r" && { + __tgcomp "$(__tg_remotes)" + return + } + + case "$cur" in + -*) + __tgcomp " + -r + " + ;; + *) + __tgcomp "$(__tg_refs)" + esac +} + +_tg_delete () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + + case "$cur" in + -*) + __tgcomp " + -f + " + ;; + *) + __tgcomp "$(__tg_topics)" + esac +} + +_tg_depend () +{ + local subcommands="add" + local subcommand="$(__git_find_subcommand "$subcommands")" + if [ -z "$subcommand" ]; then + __tgcomp "$subcommands" + return + fi + + case "$subcommand" in + add) + __tgcomp "$(__tg_refs)" + esac +} + +_tg_export () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + + __tg_complete_arg "--collapse" && { + __tgcomp "$(__tg_heads)" + return + } + + __tg_complete_arg "--quilt" && { + return + } + + case "$cur" in + *) + __tgcomp " + --collapse + --quilt + " + esac +} + +_tg_help () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + -*) + COMPREPLY=() + return + ;; + esac + __tgcomp "$(__tg_commands)" +} + +_tg_import () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + + __tg_complete_arg "-p" && { + COMPREPLY=() + return + } + + case "$cur" in + -*) + __tgcomp " + -p + " + ;; + *) + __tg_complete_revlist + esac +} + +_tg_info () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + + case "$cur" in + *) + __tgcomp "$(__tg_topics)" + esac +} + +_tg_mail () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + + case "$cur" in + *) + __tgcomp "$(__tg_topics)" + esac +} + +_tg_patch () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + + case "$cur" in + *) + __tgcomp "$(__tg_topics)" + esac +} + +_tg_remote () +{ + local cur="${COMP_WORDS[COMP_CWORD]}" + + case "$cur" in + *) + __tgcomp "$(__tg_remotes)" + esac +} + +_tg_summary () +{ + COMPREPLY=() +} + +_tg_update () +{ + COMPREPLY=() +} + +### }}} +### {{{ tg completion + +_tg () +{ + local i c=1 command __tg_dir + + while [ $c -lt $COMP_CWORD ]; do + i="${COMP_WORDS[c]}" + case "$i" in + -r) + c=$((++c)) + if [ $c -lt $COMP_CWORD ]; then + __tgcomp "$(__tg_remotes)" + return + fi + ;; + -h|--help) command="help"; break ;; + *) command="$i"; break ;; + esac + c=$((++c)) + done + + if [ -z "$command" ]; then + case "${COMP_WORDS[COMP_CWORD]}" in + -*) __tgcomp " + -r + -h + --help + " + ;; + *) __tgcomp "$(__tg_commands)" ;; + esac + return + fi + + case "$command" in + create) _tg_create "$c" ;; + delete) _tg_delete ;; + depend) _tg_depend ;; + export) _tg_export ;; + help) _tg_help ;; + import) _tg_import ;; + info) _tg_info ;; + mail) _tg_mail ;; + patch) _tg_patch ;; + remote) _tg_remote ;; + summary) _tg_summary ;; + update) _tg_update ;; + *) COMPREPLY=() ;; + esac +} + +### }}} + +complete -o default -o nospace -F _tg tg + +# The following are necessary only for Cygwin, and only are needed +# when the user has tab-completed the executable name and consequently +# included the '.exe' suffix. +# +if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then +complete -o default -o nospace -F _tg tg.exe +fi diff --git a/debian/README.source b/debian/README.source index 6fafbb4..e6c6f6c 100644 --- a/debian/README.source +++ b/debian/README.source @@ -1,7 +1,7 @@ Building topgit for Debian -------------------------- -The topgit source package uses quilt to apply and remove its patches. Please +The topgit source package uses quilt to apply and remove its patches. Please refer to /usr/share/doc/quilt/README.source for information about how to use quilt for source packages. @@ -18,6 +18,8 @@ Cloning a TopGit repository requires an additional step to normal Git cloning: 2. cd topgit 3. tg remote --populate origin +TODO: debcheckout support + Branches in use ''''''''''''''' The following branches are in use in the package: @@ -77,6 +79,9 @@ commit, build, test, upload, tag: This process is still very cumbersome and needs to be improved, ideally within TopGit. +TODO: provide Makefile snippet for the above to prevent useless duplication (#501991) +TODO: rewrite to use tg-export -b, which will be fixed in TopGit 0.5 (#500273) + 5. Importing a new upstream version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To import a new upstream, update the remote, merge the tag you want to merge diff --git a/debian/changelog b/debian/changelog index 40e7e14..a62613e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -topgit (0.4-1) unstable; urgency=low +topgit (0.5-1) unstable; urgency=low * New upstream release. diff --git a/tg-depend.sh b/tg-depend.sh old mode 100644 new mode 100755 index af78808..ff4541c --- a/tg-depend.sh +++ b/tg-depend.sh @@ -8,8 +8,16 @@ name= ## Parse options -subcmd="$1"; shift -[ "$subcmd" = "add" ] || die "unknown subcommand ($subcmd)" +subcmd="$1"; shift || : +case "$subcmd" in + -h|"") + echo "Usage: tg [...] depend add NAME" >&2 + exit 1;; + add) + ;; + *) + die "unknown subcommand ($subcmd)";; +esac while [ -n "$1" ]; do arg="$1"; shift @@ -35,7 +43,7 @@ baserev="$(git rev-parse --verify "refs/top-bases/$name" 2>/dev/null)" || ## Record new dependency -echo "$name" >>.topdeps -git add .topdeps +echo "$name" >>"$root_dir/.topdeps" +git add -f "$root_dir/.topdeps" git commit -m"New TopGit dependency: $name" $tg update diff --git a/tg-export.sh b/tg-export.sh index a7c459a..52af88d 100644 --- a/tg-export.sh +++ b/tg-export.sh @@ -21,7 +21,7 @@ while [ -n "$1" ]; do --collapse) driver=collapse;; -*) - echo "Usage: tg [...] export [-b BRANCH1,BRANCH2...] ([--collapse] NEWBRANCH | --quilt DIRECTORY)" >&2 + echo "Usage: tg [...] export ([--collapse] NEWBRANCH | [-b BRANCH1,BRANCH2...] --quilt DIRECTORY)" >&2 exit 1;; *) [ -z "$output" ] || die "output already specified ($output)" @@ -30,13 +30,17 @@ while [ -n "$1" ]; do done -name="$(git symbolic-ref HEAD | sed 's#^refs/heads/##')" -base_rev="$(git rev-parse --short --verify "refs/top-bases/$name" 2>/dev/null)" || - die "not on a TopGit-controlled branch" [ -z "$branches" -o "$driver" = "quilt" ] || die "-b works only with the quilt driver" +if [ -z "$branches" ]; then + # this check is only needed when no branches have been passed + name="$(git symbolic-ref HEAD | sed 's#^refs/heads/##')" + base_rev="$(git rev-parse --short --verify "refs/top-bases/$name" 2>/dev/null)" || + die "not on a TopGit-controlled branch" +fi + playground="$(mktemp -d -t tg-export.XXXXXX)" trap 'rm -rf "$playground"' EXIT diff --git a/tg-import.sh b/tg-import.sh index 799efc9..b036b86 100644 --- a/tg-import.sh +++ b/tg-import.sh @@ -5,7 +5,9 @@ # GPLv2 branch_prefix=t/ +single= ranges= +basedep= ## Parse options @@ -13,10 +15,14 @@ ranges= while [ -n "$1" ]; do arg="$1"; shift case "$arg" in + -d) + basedep="$1"; shift;; -p) branch_prefix="$1"; shift;; + -s) + single="$1"; shift;; -*) - echo "Usage: tg [...] import [-p PREFIX] RANGE..." >&2 + echo "Usage: tg [...] import [-d BASE_BRANCH] {[-p PREFIX] RANGE...|-s NAME COMMIT}" >&2 exit 1;; *) ranges="$ranges $arg";; @@ -36,7 +42,11 @@ git update-index --ignore-submodules --refresh || exit get_commit_msg() { commit="$1" - git log -1 --pretty=format:"From: %an <%ae>%n%n%s%n%n%b" "$commit" + headers="" + ! header="$(git config topgit.to)" || headers="$headers%nTo: $header" + ! header="$(git config topgit.cc)" || headers="$headers%nCc: $header" + ! header="$(git config topgit.bcc)" || headers="$headers%nBcc: $header" + git log -1 --pretty=format:"From: %an <%ae>$headers%nSubject: %s%n%n%b" "$commit" } get_branch_name() @@ -58,16 +68,25 @@ get_branch_name() process_commit() { commit="$1" - branch_name=$(get_branch_name "$commit") - info "---- Importing $commit to $branch_prefix$branch_name" - tg create "$branch_prefix""$branch_name" - git cherry-pick --no-commit "$commit" + branch_name="$2" + info "---- Importing $commit to $branch_name" + tg create "$branch_name" $basedep + basedep= get_commit_msg "$commit" > .topmsg git add -f .topmsg .topdeps + if ! git cherry-pick --no-commit "$commit"; then + info "The commit will also finish the import of this patch." + exit 2 + fi git commit -C "$commit" info "++++ Importing $commit finished" } +if [ -n "$single" ]; then + process_commit $ranges "$single" + exit +fi + # nice arg verification stolen from git-format-patch.sh for revpair in $ranges do @@ -92,7 +111,7 @@ do info "Merged already: $comment" ;; *) - process_commit "$rev" + process_commit "$rev" "$branch_prefix$(get_branch_name "$rev")" ;; esac done diff --git a/tg-mail.sh b/tg-mail.sh index 24e5f67..7b8f7ff 100644 --- a/tg-mail.sh +++ b/tg-mail.sh @@ -4,6 +4,7 @@ name= send_email_args= +in_reply_to= ## Parse options @@ -13,8 +14,10 @@ while [ -n "$1" ]; do case "$arg" in -s) send_email_args="$1"; shift;; + -r) + in_reply_to="$1"; shift;; -*) - echo "Usage: tg [...] mail [-s SEND_EMAIL_ARGS] [NAME]" >&2 + echo "Usage: tg [...] mail [-s SEND_EMAIL_ARGS] [-r REFERENCE_MSGID] [NAME]" >&2 exit 1;; *) [ -z "$name" ] || die "name already specified ($name)" @@ -26,13 +29,16 @@ done base_rev="$(git rev-parse --short --verify "refs/top-bases/$name" 2>/dev/null)" || die "not a TopGit-controlled branch" +if [ -n "$in_reply_to" ]; then + send_email_args="$send_email_args --in-reply-to=$in_reply_to" +fi + patchfile="$(mktemp -t tg-mail.XXXXXX)" -$tg patch $name >"$patchfile" +$tg patch "$name" >"$patchfile" -hlines=$(grep -n -m 1 '^---' "$patchfile" | sed 's/:---//') -header=$(head -n $(($hlines - 1)) "$patchfile") +header="$(sed -e '/^$/,$d' "$patchfile")" @@ -40,14 +46,12 @@ from="$(echo "$header" | grep '^From:' | sed 's/From:\s*//')" to="$(echo "$header" | grep '^To:' | sed 's/To:\s*//')" -# XXX: I can't get quoting right without arrays -people=() -[ -n "$from" ] && people=("${people[@]}" --from "$from") +people= +[ -n "$from" ] && people="$people --from '$from'" # FIXME: there could be multimple To -[ -n "$to" ] && people=("${people[@]}" --to "$to") - +[ -n "$to" ] && people="$people --to '$to'" # NOTE: git-send-email handles cc itself -git send-email $send_email_args "${people[@]}" "$patchfile" +eval git send-email $send_email_args "$people" "$patchfile" rm "$patchfile" diff --git a/tg-summary.sh b/tg-summary.sh index 409f456..3c90a6b 100644 --- a/tg-summary.sh +++ b/tg-summary.sh @@ -3,22 +3,64 @@ # (c) Petr Baudis 2008 # GPLv2 +terse= +graphviz= + ## Parse options -if [ -n "$1" ]; then - echo "Usage: tg [...] summary" >&2 - exit 1 -fi +while [ -n "$1" ]; do + arg="$1"; shift + case "$arg" in + -t) + terse=1;; + --graphviz) + graphviz=1;; + *) + echo "Usage: tg [...] summary [-t | --graphviz]" >&2 + exit 1;; + esac +done curname="$(git symbolic-ref HEAD | sed 's#^refs/\(heads\|top-bases\)/##')" +if [ -n "$graphviz" ]; then + cat < +# or +# | dot -Txlib + +digraph G { + +graph [ + rankdir = "TB" + label="TopGit Layout\n\n\n" + fontsize = 14 + labelloc=top + pad = "0.5,0.5" +]; + +EOT +fi + ## List branches git for-each-ref refs/top-bases | while read rev type ref; do name="${ref#refs/top-bases/}" + if [ -n "$terse" ]; then + echo "$name" + continue + fi + if [ -n "$graphviz" ]; then + git cat-file blob "$name:.topdeps" | while read dep; do + echo "\"$name\" -> \"$dep\";" + done + continue + fi + missing_deps= current=' ' @@ -52,3 +94,7 @@ git for-each-ref refs/top-bases | printf '%s\t%-31s\t%s\n' "$current$nonempty$remote$rem_update$deps_update$deps_missing$base_update" \ "$name" "$subject" done + +if [ -n "$graphviz" ]; then + echo '}' +fi diff --git a/tg-update.sh b/tg-update.sh index f36624f..040800d 100644 --- a/tg-update.sh +++ b/tg-update.sh @@ -75,7 +75,7 @@ if [ -s "$depcheck" ]; then info "Updating base with $dep changes..." if ! git merge "$dep"; then if [ -z "$TG_RECURSIVE" ]; then - resume="\`$tg update\` again" + resume="\`git checkout $name && $tg update\` again" else # subshell resume='exit' fi @@ -87,14 +87,16 @@ if [ -s "$depcheck" ]; then exit 2 fi done - - # Home, sweet home... - git checkout -q "$name" else info "The base is up-to-date." fi rm "$depcheck" +# Home, sweet home... +# (We want to always switch back, in case we were on the base from failed +# previous merge.) +git checkout -q "$name" + merge_with="refs/top-bases/$name" diff --git a/tg.sh b/tg.sh index ecc6574..a8eb718 100644 --- a/tg.sh +++ b/tg.sh @@ -222,7 +222,7 @@ do_help() sep="|" done - echo "TopGit v0.4 - A different patch queue manager" + echo "TopGit v0.5 - A different patch queue manager" echo "Usage: tg [-r REMOTE] ($cmds|help) ..." elif [ -r "@cmddir@"/tg-$1 ] ; then @cmddir@/tg-$1 -h || : @@ -241,6 +241,8 @@ do_help() set -e git_dir="$(git rev-parse --git-dir)" root_dir="$(git rev-parse --show-cdup)"; root_dir="${root_dir:-.}" +# Make sure root_dir doesn't end with a trailing slash. +root_dir="${root_dir%/}" base_remote="$(git config topgit.remote 2>/dev/null)" || : tg="tg" # make sure merging the .top* files will always behave sanely