tg-update rewrite proposal
From: Marc Weber <hidden>
Date: 2016-06-15 22:46:39
Hi Uwe,
I came up with this proposal for a rewrite for tg-update.sh now:
I hope this fits your ideas about tg update as well..
Note that second "for each dependency [1]" below allowing handling updates
against multiple remote repos.
I hope that its easy to understand this short documentation draft.
Sincerly
Marc Weber
# documentation:
# Uwe Klein Koenig suggests keeping updating with remote branches
# which corresponds to "git pull" in default git separate from
# updating branches with deps (normal branhces and/or tg branches)
#
# Because of [3] my implementation of tg update starts at the bottom going up
# first updating with remotes then with deps by default.
# However you can choose to only update with remotes
# or with deps only using --remotes-only or --local-only
# I hope this satisfies everyone.
# Providing a subshellless update experience can only be done by saving
# some state the way git-rebase does. STATE_DIR will be used to save this state
#
# What's saved in STATE_DIR ?
#
# $STATE_DIR/$BRANCHES_VISITING_ORDER is a list of dependency names [1] which is generated
# by traversing the dependency tree of branches form bottom up
#
# Example:
# A B C D
# \ / \ /
# t/1 t/2
# \ /
# t/working
#
# will result in
#
# A
# B
# t/1
# C
# D
# t/2
# t/working
# Then the first line is picked and the specified branch is updated.
# updating is done in this order [3]:
#
# first:
# if not --local-only
# foreach remote location:
# - merge base with remote tg branch (thereby also including the remote base)
# update the base ref [2]
# - update tg [*]
#
# then:
# if not --remote-only
# for each dependency [1]
# - merge base with dep [2]
# - update tg [*]
#
# [*]: merge new base with topgit branch updating the topgit ref.
# After this step the base is always contained in the current branch
#
# Similar to $STATE_DIR/BRANCHES_VISITING_ORDER a file $STATE_DIR/$BRANCH_UPDATE_TASKS is
# created containing the subtasks of a branch update.
#
# Example file with additional comment lines, two remote locations:
#
# # first:
# merge_base_with: $REMOTE_HASH
# update_tg
# merge_base_with: $REMOTE_HASH2
# update_tg
#
# # then:
# merge_base_with: $DEP1_HASH
# update_tg
# merge_base_with: $DEP2_HASH
# update_tg
# merge_base_with: $DEP3_HASH
# update_tg
# So the overall implementation is easy and looks like this:
#
# if !exists $STATE_DIR/BRANCHES_VISITING_ORDER
# then create file, goto else
# else pop_or_continue
#
# pop_or_continue:
# if !exists $STATE_DIR/$BRANCH_UPDATE_TASKS
# then create file, goto else
# else pop_or_continue_subtask
#
# pop_or_continue_subtask:
# ...
# [1] note for users who knew the old code: not including remotes
#
# [2] This means creating a commit to the topic branch changing the .topbase file only
#
# [3] I think the following statements make sense:
# *) You want to update against remote first. Or you want to have a way to do so.
# Why? The remote may already have done some of the dirty merge work for you.
# If you resolving the same conflicts first by updating with deps and then merge
# with remote -> hell!
# *) You don't want to run tg update multiple times. Thus the update strategy has
# to start at the bottom and go up to the current branch
# state dir and filenames:
STATE_DIR=.git/tg-update-in-progress
BRANCHES_VISITING_ORDER=branches-visiting-order
BRANCH_UPDATE_TASKS=branch-update-tasks
## Parse options
if [ -n "$1" ]; then
echo "Usage: tg [--local-only] [--remote-only] update" >&2
exit 1
fi