Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
git workflow across forced updates
This is my workflow to handle forced updates in the git repository
conversion as smoothly as regular updates:
1. When I start working on a change, say for PR 12345, I create two
branches with a short name describing the change:
git branch pr12345-mumblefix-base origin/trunk
git checkout -b pr12345-mumblefix pr12345-mumblefix-base
2. I commit some changes on the branch with `git commit -i' to
interactively select the hunks to commit so I can keep separate
functional (or non-functional) changes.
Sometimes I want to amend a previous commit, so I find the commit
hash, say 1234abcd, and make a fixup commit:
git commit --fixup 1234abcd
This makes a magic commit message `fixup! <title of 1234abcd>'.
Then from time to time I rebase to apply the fixups:
git rebase -i --autosquash pr12345-mumblefix-base
3. Sometimes I push changes from the branch to the CVS repository with
git cvsexportcommit:
git cvsexportcommit -c -p -v -w ~/cvs/src 1234abcd
If the change is near an RCS id line ($NetBSD: ...$), it is
sometimes necessary to omit `-p' so the patch is allowed to apply
with smaller context, but I manually eyeball it before I do that,
just in case.
4. When I want to update the repository, I use the attached script to
create a new branch pr12345-mumblefix-v2 on a new base
pr12345-mumblefix-v2-base with all the same commits:
/path/to/git-update.sh pr12345-mumblefix origin/trunk
or, next time, to make pr12345-mumblefix-v3:
/path/to/git-update.sh pr12345-mumblefix-v2 origin/trunk
Of course, there might be merge conflicts to resolve. Sometimes if
I've already committed changes git will figure that out; sometimes
git won't figure it out but it's just a matter of skipping a commit
with `git rebase --skip'.
It's not highly polished -- if you want to give up on resolving the
merge conflicts, you can do `git rebase --abort', but git-update.sh
won't clean up the branches it already created. Nevertheless, it's
been very handy for my development needs.
(You can also put it in your PATH and then say `git update' instead
of `/path/to/git-update.sh'. Not sure if git plans to add a
standard `git update' command, though.)
5. When I'm done and I've pushed all the changes to CVS and the branch
is now empty on update, so pr12345-mumblefix-vN is the same as
pr12345-mumblefix-vN-base, I rename all the branches to be
closed/pr12345-mumblefix-vN and closed/pr12345-mumblefix-vN-base.
Not perfect but easy to ignore in `git branch' output.
(You can also just delete the branches, if the proposition of
deleting history doesn't make your skin crawl like it does for me.)
#!/bin/sh
# Copyright (c) 2023 Taylor R. Campbell
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
# NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -Ceu
run()
{
echo '#' "$@"
${DRY_RUN+:} "$@"
}
oldbranch=$1
newbase=${2-origin/trunk}
case $oldbranch in
*-v[0-9] | *-v[0-9][0-9])
prefix=${1%-v*}
oldversion=${1##*-v}
newversion=$((oldversion + 1))
;;
*)
prefix=$1
newversion=2
;;
esac
newbranch=${prefix}-v${newversion}
if git rev-parse --verify --quiet ${newbranch}-base >/dev/null; then
printf >&2 'git-update: new base %s already exists\n' ${newbranch}-base
exit 1
fi
if git rev-parse --verify --quiet ${newbranch} >/dev/null; then
printf >&2 'git-update: new branch %s already exists\n' ${newbranch}
exit 1
fi
if ! run git diff --stat --exit-code; then
printf >&2 'git-update: dirty working tree, aborting\n'
exit 1
fi
if ! run git diff --cached --stat --exit-code; then
printf >&2 'git-update: dirty staging area, aborting\n'
exit 1
fi
run git branch ${newbranch}-base $newbase
run git branch $newbranch $oldbranch
run git rebase --onto ${newbranch}-base ${oldbranch}-base $newbranch
Home |
Main Index |
Thread Index |
Old Index