Test commit
[cogito/jonas.git] / cg-admin-uncommit
blob7d6e8738572d6caa73c9dbbae3d3ec5291298144
1 #!/usr/bin/env bash
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
10 # first time.
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.
18 # OPTIONS
19 # -------
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.
27 # CAVEATS
28 # -------
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]"
40 _git_requires_root=1
42 . "${COGITO_LIB}"cg-Xlib || exit 1
44 [ -s "$_git/blocked" ] && die "uncommitting blocked: $("cat $_git/blocked")"
46 rollback_tree=
47 while optparse; do
48 if optparse -t; then
49 rollback_tree=1
50 else
51 optfail
53 done
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"