Subject: tg-update rewrite proposal

From: Marc Weber <[email-masked]>
Date: Fri, 24 Apr 2009 01:11:24 +0200

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