@@ -4,11 +4,17 @@ source bashlib
4
4
5
5
# Utilities.
6
6
gitg () {
7
+ [[ -e " $dcs /git.global" ]] || ftl ' Missing global DCS repository at %s' " $dcs " || exit
8
+ (( ! $# )) && return
9
+
7
10
GIT_DIR=" $dcs /git.global" \
8
11
GIT_WORK_TREE=" $workdir " \
9
12
command git " $@ "
10
13
}
11
14
gitl () {
15
+ [[ -e " $dcs /git.local" ]] || ftl ' Missing local DCS repository at %s' " $dcs " || exit
16
+ (( ! $# )) && return
17
+
12
18
GIT_DIR=" $dcs /git.local" \
13
19
GIT_ALTERNATE_OBJECT_DIRECTORIES=" $dcs /git.global/objects" \
14
20
GIT_WORK_TREE=" $workdir " \
@@ -32,37 +38,19 @@ githas() {
32
38
ogithas () {
33
39
ogit ls-files --error-unmatch " $@ " > /dev/null 2>&1
34
40
}
41
+ updateRepos () {
42
+ # Ensure both repos are available
43
+ gitg && gitl
35
44
45
+ # Ensure we're on the right branch
46
+ if [[ $( gitg symbolic-ref --short HEAD) != $branch_global ]]; then
47
+ gitg checkout -B " $branch_global "
48
+ fi
49
+ if [[ $( gitl symbolic-ref --short HEAD) != $branch_local ]]; then
50
+ gitl checkout -B " $branch_local "
51
+ fi
36
52
37
- # Initialize our working directory.
38
- workdir=$(
39
- default=$PWD
40
- until [[ -e .dcs.d || $PWD = / ]]; do cd ..; done
41
- [[ -e .dcs.d ]] && echo " $PWD " || echo " $default "
42
- )
43
- dcs=$workdir /.dcs.d
44
- if [[ ! -e " $dcs " ]]; then
45
- [[ $( ask -c Ny ' Initialize DCS in %s?' " $workdir " ) = y ]] || exit
46
- mkdir -p " $dcs "
47
- fi
48
- branch_global=global/master
49
- branch_local=local/${HOSTNAME%% .* }
50
- if [[ ! -e " $dcs /git.global" ]]; then
51
- command git init --bare " $dcs /git.global"
52
- echo " ref: refs/heads/$branch_global " > " $dcs /git.global/HEAD"
53
- elif [[ $( gitg symbolic-ref --short HEAD) != $branch_global ]]; then
54
- gitg checkout -B " $branch_global "
55
- fi
56
- if [[ ! -e " $dcs /git.local" ]]; then
57
- command git init --bare " $dcs /git.local"
58
- echo " ref: refs/heads/$branch_local " > " $dcs /git.local/HEAD"
59
- elif [[ $( gitl symbolic-ref --short HEAD) != $branch_local ]]; then
60
- gitl checkout -B " $branch_local "
61
- fi
62
-
63
-
64
- # Update global and local exclusion patterns.
65
- updateRepos () {
53
+ # Ensure the ignores are up-to-date
66
54
if [[ ! -e " $dcs /ignore.global" ]]; then
67
55
echo " /.dcs.d/git.*" > " $dcs /ignore.global"
68
56
gitg add " $dcs /ignore.global"
@@ -74,18 +62,48 @@ updateRepos() {
74
62
touch " $dcs /ignore.local"
75
63
gitl add " $dcs /ignore.local"
76
64
fi
77
- while IFS= read -rd ' ' localfile; do
65
+ while IFS= read -u3 - rd ' ' localfile; do
78
66
# FIXME: Handle filenames with * ? and newlines in them.
79
67
printf ' /%s\n' " $localfile "
80
- done < <( gitl ls-files --full-name -z " $workdir " ) >> " $dcs /git.global/info/exclude"
81
- }; updateRepos
68
+ done 3< <( gitl ls-files --full-name -z " $workdir " ) >> " $dcs /git.global/info/exclude"
69
+ }
70
+
71
+
72
+ # Initialize our working directory.
73
+ workdir=$(
74
+ default=$PWD
75
+ until [[ -e .dcs.d || $PWD = / ]]; do cd ..; done
76
+ [[ -e .dcs.d ]] && echo " $PWD " || echo " $default "
77
+ )
78
+ dcs=$workdir /.dcs.d
79
+ branch_global=global/master
80
+ branch_local=local/${HOSTNAME%% .* }
82
81
83
82
84
83
# Run dcs action.
85
84
action=${1:- status} ; shift
86
85
case $action in
86
+ init)
87
+ workdir=$PWD
88
+ dcs=$workdir /.dcs.d
89
+ if [[ ! -e " $dcs " ]]; then
90
+ [[ $( ask -c Ny ' Initialize DCS in %s?' " $workdir " ) = y ]] || exit
91
+ mkdir -p " $dcs "
92
+ fi
93
+ if [[ ! -e " $dcs /git.global" ]]; then
94
+ command git init --bare " $dcs /git.global"
95
+ echo " ref: refs/heads/$branch_global " > " $dcs /git.global/HEAD"
96
+ fi
97
+ if [[ ! -e " $dcs /git.local" ]]; then
98
+ command git init --bare " $dcs /git.local"
99
+ echo " ref: refs/heads/$branch_local " > " $dcs /git.local/HEAD"
100
+ fi
101
+ updateRepos
102
+
103
+ ;;
87
104
st|status)
88
105
[[ $1 = -a ]] && all=1 && shift
106
+ updateRepos
89
107
90
108
inf ' %s:' " $branch_global "
91
109
if (( all )) ; then
@@ -102,26 +120,61 @@ case $action in
102
120
fi
103
121
;;
104
122
123
+ s|stage)
124
+ stageFiles () {
125
+ inf ' Interactively staging:'
126
+ gitg ls-files --exclude-standard --directory --no-empty-directory -o " $@ "
127
+
128
+ while IFS= read -u3 -rd ' ' ; do
129
+ while true ; do
130
+ read size _ < <( du -xsh " $REPLY " )
131
+ count=$( gitg ls-files --exclude-standard --directory --no-empty-directory -o " $REPLY " | wc -l)
132
+ (( count == 1 )) && countSuffix= || countSuffix=s
133
+ stageAction=$( ask -c gliSec ' %s [%s, %d %s] - stage %slobal, %socal, %sgnore, %skip, %snter, show %sontents?' \
134
+ " $REPLY " " $size " " $count " " file$countSuffix " g l i s e c)
135
+ case $stageAction in
136
+ g) gitg add " $REPLY " && break ;;
137
+ l) gitl add " $REPLY " && break ;;
138
+ i) gitg ls-files --full-name --directory -o -z " $REPLY " >> " $dcs /ignore.global" && break ;;
139
+ S) break ;;
140
+ e) [[ -d " $REPLY " ]] && stageFiles " $REPLY " && break ;;
141
+ c) if [[ -d " $REPLY " ]]; then
142
+ gitg ls-files -o " $REPLY " | " ${PAGER:- less} "
143
+ else
144
+ " ${PAGER:- less} " " $REPLY "
145
+ fi ;;
146
+ esac
147
+ done
148
+ done 3< <( gitg ls-files --exclude-standard --directory --no-empty-directory -o -z " $@ " )
149
+ }
150
+
151
+ updateRepos
152
+ stageFiles " $@ "
153
+ ;;
154
+
105
155
u|unstage)
106
- while IFS= read -rd ' ' ; do
156
+ updateRepos
157
+
158
+ while IFS= read -u3 -rd ' ' ; do
107
159
gitg rm --cached " $REPLY "
108
- done < <( gitg ls-files -z " $@ " )
109
- while IFS= read -rd ' ' ; do
160
+ done 3 < <( gitg ls-files -z " $@ " )
161
+ while IFS= read -u3 - rd ' ' ; do
110
162
gitl rm --cached " $REPLY "
111
- done < <( gitl ls-files -z " $@ " )
163
+ done 3 < <( gitl ls-files -z " $@ " )
112
164
;;
113
165
114
166
g|global|l|local|G|globalize|L|localize)
167
+ updateRepos
115
168
repo_global
116
169
[[ $action = [lL]* ]] && repo_local
117
170
[[ $action = [GL] || $action = * ize ]] && move=1 || move=0
118
171
119
172
files=()
120
- while IFS= read -rd ' ' ; do
173
+ while IFS= read -u3 - rd ' ' ; do
121
174
if (( move )) || ! ogithas " $REPLY " ; then
122
175
files+=( " $REPLY " )
123
176
fi
124
- done < <(
177
+ done 3 < <(
125
178
if (( move )) ; then
126
179
ogit ls-files --exclude-standard -z " $@ "
127
180
else
@@ -144,6 +197,8 @@ case $action in
144
197
;;
145
198
146
199
d|down|pull)
200
+ updateRepos
201
+
147
202
if [[ $( gitg remote show) = origin ]]; then
148
203
inf ' Pulling %s...' " $branch_global "
149
204
gitg pull origin " $branch_global "
@@ -155,6 +210,7 @@ case $action in
155
210
;;
156
211
157
212
u|up|push)
213
+ updateRepos
158
214
gitg commit -m " dcs global commit"
159
215
gitl commit -m " dcs local commit" --untracked-files=no
160
216
@@ -169,6 +225,7 @@ case $action in
169
225
;;
170
226
171
227
r|remote)
228
+ updateRepos
172
229
if [[ $1 = -l ]]; then
173
230
repo_local
174
231
shift
0 commit comments