summaryrefslogtreecommitdiffstats
path: root/commit.sh
blob: ade63f1526fee4643dc6de338fdf3b6c69663d73 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
##
# systr_record_commit_mesg <commit> <branch> [<mesg>]
#
# Setup and present user with an editor to enter a commit message for
# the given commit ID.  If <mesg> is given, that content will be the
# default in the opened file.  If <branch> does not match TRAC, an
# additional message will be given to the user, letting them know they
# are committing to another branch.  Once user is finished, the file
# is moved into the repository root, awaiting a call to systr_repo_finish_commit.
##
function systr_record_commit_mesg
{
    if [ $# -lt 2 ]; then
        echo "Fatal: too few args to record_commit_mesg" >&2
        exit 1
    fi

    commit="$1"
    branch="$2"

    if [ $# -gt 2 ]; then
        mesg="$3"
    else
        mesg=""
    fi

    echo "$mesg" >.systr/commit-edit-mesg.txt
    echo "# --" >>.systr/commit-edit-mesg.txt

    if [[ "$branch" != "$TRAC" ]]; then
        echo "# Committing to $branch" >>.systr/commit-edit-mesg.txt
        echo "#" >>.systr/commit-edit-mesg.txt
    fi

    systrunk status | sed 's/^/# /' >>.systr/commit-edit-mesg.txt
    vi .systr/commit-edit-mesg.txt
    sed '/^#/ d' <.systr/commit-edit-mesg.txt >"$path/revs/$commit.mesg"
}

##
# systrunk commit [<branch>=TRAC]
#
# Create a snapshot of the current state of the worktree and record
# it in the repository.  Your worktree must be up-to-date with <branch>
# before you can commit.  The branch committed to is updated to
# reference the new commit.  If <branch> does not exist in the
# repository, it is created.  If <branch> is a commit ID instead of
# a symbolic reference, the new commit will not exist on any branch,
# but an anonymous one referenced by TRAC.
##
function systr_commit
{
    if [ $# -gt 0 ]; then
        branch="$1"
    else
        branch="$TRAC"
    fi

    if [[ "$branch" == "BASE" ]]; then
        echo "Fatal: bad branch name BASE" >&2
        exit 1
    elif [[ "$branch" == "TRAC" ]]; then
        echo "Fatal: bad branch name TRAC" >&2
        exit 1
    elif [[ "$branch" == "NULL" ]]; then
        echo "Fatal: bad branch name NULL" >&2
        exit 1
    elif [[ "$branch" == "MERG" ]]; then
        echo "Fatal: bad branch name MERG" >&2
        exit 1
    fi

    branchcommit=$(systr_repo_resolve_reference "$branch" 2>/dev/null) || branchcommit="$BASE"
    systr_repo_resolve_reference "$branch" >/dev/null 2>&1 || echo "Creating new branch $branch"

    if [[ "$BASE" != "$branchcommit" ]]; then
        echo "Worktree is out-of-date, won't commit" >&2
        exit 1
    fi

    commit=$(systr_repo_create_commit)

    if [[ "$MERG" == "NULL" ]]; then
        systr_record_commit_mesg "$commit" "$branch"
    else
        systr_record_commit_mesg "$commit" "$branch" "Merge $MERG into $TRAC"
    fi

    echo "Sending files..."

    if [[ "$branchcommit" != "NULL" ]]; then
        systr_rsync_normal . "$path/revs/$commit/" "../$branchcommit/"
    else
        systr_rsync_normal . "$path/revs/$commit/"
    fi

    if [[ "$MERG" == "NULL" ]]; then
        systr_repo_finish_commit "$commit" "$branchcommit"
    else
        mergecommit=$(systr_repo_resolve_reference "$MERG")
        systr_repo_finish_commit "$commit" "$branchcommit" "$mergecommit"
    fi

    echo "$commit" >.systr/BASE
    echo "NULL" >.systr/MERG
    date >.systr/updated

    if [[ "$branch" != "$branchcommit" ]]; then
        systr_repo_set_reference "$branch" "$commit"
    fi

    if [[ "$TRAC" == "$BASE" ]]; then
        echo "$commit" >.systr/TRAC
    else
        echo "$branch" >.systr/TRAC
    fi
}

##
# systrunk reset <branch>
#
# Similar to systrunk commit, but doesn't require the worktree to
# be up-to-date with <branch>.  This command can be used to rollback
# a branch to a previous state by running systrunk checkout followed
# by this command.  If <branch> does not exist, this command will
# fail.  If <branch> is a commit ID instead of a symbolic reference,
# no action is taken.
##
function systr_reset
{
    if [ $# -lt 1 ]; then
        echo "Fatal: too few args to reset" >&2
        exit 1
    fi

    branch="$1"

    if [[ "$branch" == "BASE" ]]; then
        echo "Fatal: bad branch name BASE" >&2
        exit 1
    elif [[ "$branch" == "TRAC" ]]; then
        echo "Fatal: bad branch name TRAC" >&2
        exit 1
    elif [[ "$branch" == "NULL" ]]; then
        echo "Fatal: bad branch name NULL" >&2
        exit 1
    elif [[ "$branch" == "MERG" ]]; then
        echo "Fatal: bad branch name MERG" >&2
        exit 1
    fi

    if [[ "$MERG" != "NULL" ]]; then
        echo "Fatal: merge in progress, won't reset" >&2
        exit 1
    fi

    branchcommit=$(systr_repo_resolve_reference "$branch")

    if [[ "$branchcommit" == "$branch" ]]; then
        echo "Fatal: $branch is a commit ID, not a symbolic reference" >&2
        exit 1
    fi

    commit=$(systr_repo_create_commit)
    systr_record_commit_mesg "$commit" "$branch" "Reset $branch to state at $BASE"
    echo "Performing RESET"
    echo "Sending files..."

    if [[ "$BASE" != "NULL" ]]; then
        systr_rsync_normal . "$path/revs/$commit/" "../$BASE/"
    else
        systr_rsync_normal . "$path/revs/$commit/"
    fi

    systr_repo_finish_commit "$commit" "$branchcommit"
    echo "$commit" >.systr/BASE
    echo "NULL" >.systr/MERG
    date >.systr/updated
    systr_repo_set_reference "$branch" "$commit"
    echo "$branch" >.systr/TRAC
}