3 # Undo a commit or a series of commits
4 # Copyright (c) Matt Porter, 2005
5 # Copyright (c) Petr Baudis, 2005
7 # Takes a commit ID which is the earliest commit to be removed from
8 # the repository. If no parameter is passed, it uncommits the latest
9 # commit ('HEAD'). Read the CAVEATS section before using it for the
12 # This command is a close relative of `cg-switch -f` (which does
13 # essentially the same thing, but is slightly more powerful at the
14 # expense of a more elaborate usage). Do not confuse either with the
15 # operation performed by `cg-seek`, which is meant only for temporary
16 # excursions to the project history.
20 # -t:: Restore the working copy of the previous commit
21 # This optional parameter makes `cg-admin-uncommit` to roll back
22 # the tree as well to the previous commit. Without this option
23 # (by default) 'Cogito' keeps the tree in its current state,
24 # therefore generating tree with local changes against the target
25 # commit, consisting of the changes in the rolled back commits.
29 # This command can be dangerous! It is safe to do as long as you do not
30 # push the commit out in the meantime, but you should 'NEVER' uncommit an
31 # already pushed out commit. Things will break for the fetchers since you
32 # just broke the fast-forward merging mechanism (the new commit is not
33 # descendant of the previous one), and the push command will refuse to
34 # push again after you uncommitted a pushed out commit, too. At the moment
35 # you pushed the commit out it's etched to the history, live with that.
37 # Testsuite: Marginal (part of t9210-update)
39 USAGE
="cg-admin-uncommit [-t] [COMMIT_ID]"
42 .
"${COGITO_LIB}"cg-Xlib ||
exit 1
44 [ -s "$_git/blocked" ] && die
"uncommitting blocked: $("cat $_git/blocked
")"
56 base
="$(cg-object-id -c)" ||
exit 1
58 commit
="$(cg-object-id -c "${ARGS[0]}")" ||
exit 1
59 [ "$(git-rev-list $commit ^$base)" ] && \
60 die
"$commit: not an ancestor of HEAD"
62 parent
="$(cg-object-id -p "$commit")" ||
exit 1
63 [ "$parent" ] || die
"cannot rewind behind the initial commit"
64 [ "$(echo "$parent" | wc -l)" -gt 1 ] &&
65 die
"cannot rewind merges; please 'cg-switch -f -r parentid $_git_head' instead"
68 echo "Rewinding $base (HEAD) -> $parent" >&2
70 tree_timewarp
"backwards" "$rollback_tree" "$base" "$parent"