Skip to content

Commit be264aa

Browse files
committed
introduce "wip" - act as noop after removing "add" until ready
1 parent 41ddabb commit be264aa

File tree

2 files changed

+72
-13
lines changed

2 files changed

+72
-13
lines changed

git-add-files

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ CONFIG_ABBREV_COMMANDS="addfiles.abbreviateCommands"
1212
FILENAME="ADD_FILES"
1313

1414
CMD_ADD="add"
15+
CMD_WIP="wip"
1516
CMD_STAGED="staged"
1617
CMD_HALFSTAGED="halfstaged"
1718

1819
SHORT_CMD_ADD="a"
20+
SHORT_CMD_WIP="w"
1921
SHORT_CMD_STAGED="s"
2022
SHORT_CMD_HALFSTAGED="h"
2123

@@ -26,6 +28,8 @@ INFO_MSG="\
2628
# delete \"$CMD_HALFSTAGED\" (noop) lines to un-stage partially-staged files.
2729
# change \"$CMD_HALFSTAGED\" (noop) to \"$CMD_ADD\" to stage partially-staged files.
2830
#
31+
# \"wip\" is noop, cached in .git/add-files/wip
32+
#
2933
# all commands have a single-char shortcut.
3034
# empty lines and lines starting with '#' will be ignored.
3135
# to abort, exit with non-0 code (e.g. :cq in vim).
@@ -75,7 +79,13 @@ git_add_files() {
7579

7680
repodir="$(git rev-parse --show-toplevel)"
7781
gitdir="$(git rev-parse --git-dir)"
82+
83+
FILE_STORE="$gitdir/add-files"
7884
file="$gitdir/$FILENAME"
85+
FILE_WIP="$FILE_STORE/wip"
86+
87+
mkdir -p "$FILE_STORE"
88+
touch "$FILE_WIP"
7989

8090
COMMENT_REGEX="\s*#.*$"
8191

@@ -95,17 +105,24 @@ git_add_files() {
95105
printf "%s" "$1" | sed "s@^@$2@g"
96106
}
97107

108+
ADD_WITHOUT_WIP="$(printf "%b" "$ADD" | { grep -vFf "$FILE_WIP" ||: ; })"
109+
WIP="$(printf "%b" "$ADD" | { grep -Ff "$FILE_WIP" ||: ; })"
110+
98111
if test "$(git config "$CONFIG_ABBREV_COMMANDS")" = "true"; then
99-
ADD_READY="$( inject_prefix_into "$ADD" "$SHORT_CMD_ADD ")"
112+
ADD_READY="$(inject_prefix_into "$ADD_WITHOUT_WIP" "$SHORT_CMD_ADD ")"
113+
WIP_READY="$(inject_prefix_into "$WIP" "$SHORT_CMD_WIP ")"
100114
STAGED_READY="$(inject_prefix_into "$STAGED" "$SHORT_CMD_STAGED ")"
101115
else
102-
ADD_READY="$( inject_prefix_into "$ADD" "$CMD_ADD ")"
116+
ADD_READY="$(inject_prefix_into "$ADD_WITHOUT_WIP" "$CMD_ADD ")"
117+
WIP_READY="$(inject_prefix_into "$WIP" "$CMD_WIP ")"
103118
STAGED_READY="$(inject_prefix_into "$STAGED" "$CMD_STAGED ")"
104119
fi
105120

106-
sep=""
107-
test -n "$ADD_READY" && test -n "$STAGED_READY" && sep="\n\n"
108-
printf "%s%b%s\n%s" "$ADD_READY" "$sep" "$STAGED_READY" > "$file"
121+
sep1=""
122+
sep2=""
123+
test -n "$ADD_READY" && test -n "$WIP_READY" && sep1="\n\n"
124+
test -n "$WIP_READY" && test -n "$STAGED_READY" && sep2="\n\n"
125+
printf "%s%b%s%b%s\n%s" "$ADD_READY" "$sep1" "$WIP_READY" "$sep2" "$STAGED_READY" > "$file"
109126

110127
test "$(git config "$CONFIG_DISABLE_INFO")" != "true" && {
111128
printf "\n%s" "$INFO_MSG" >> "$file"
@@ -136,15 +153,22 @@ git_add_files() {
136153
}
137154
validate_file() {
138155
# TODO handle deletions
139-
test -f "$1" || msg "file does not exit '$1'"
156+
157+
# TODO handle submodule "files" which are directories,
158+
# and cannot be added if include uncommitted changes.
159+
160+
test -f "$1" || test -d "$1" || msg "file does not exit '$1'\n"
140161
}
141162

142163
marked_added="/tmp/marked_added"
143164
marked_staged="/tmp/marked_staged"
165+
marked_wip="/tmp/marked_wip"
144166
test -f "$marked_added" && mv -f "$marked_added" "$marked_added.prev"
145167
test -f "$marked_staged" && mv -f "$marked_staged" "$marked_staged.prev"
168+
test -f "$marked_wip" && mv -f "$marked_wip" "$marked_wip.prev"
146169
touch "$marked_added"
147170
touch "$marked_staged"
171+
touch "$marked_wip"
148172
had_adds=0
149173

150174
# process & validate lines, group filepaths.
@@ -158,17 +182,26 @@ git_add_files() {
158182

159183
validate_file "$filepath"
160184

161-
printf "%s\n" "$filepath" >> "$marked_added"
185+
printf "%s\n" "$file" >> "$marked_added"
162186
had_adds=1
163187
;;
188+
"$CMD_WIP"|"$SHORT_CMD_WIP"*)
189+
rest="$(line_tail "$line")"
190+
file="$(line_head "$rest")"
191+
filepath="$(realpath "$repodir/$file")"
192+
193+
validate_file "$filepath"
194+
195+
printf "%s\n" "$file" >> "$marked_wip"
196+
;;
164197
"$CMD_STAGED"|"$SHORT_CMD_STAGED"*)
165198
rest="$(line_tail "$line")"
166199
file="$(line_head "$rest")"
167200
filepath="$(realpath "$repodir/$file")"
168201

169202
validate_file "$filepath"
170203

171-
printf "%s\n" "$filepath" >> "$marked_staged"
204+
printf "%s\n" "$file" >> "$marked_staged"
172205
;;
173206
"$CMD_HALFSTAGED"|"$SHORT_CMD_HALFSTAGED"*)
174207
# noop
@@ -181,13 +214,16 @@ git_add_files() {
181214

182215
# add all lines that were kept as "add"
183216

184-
test "$had_adds" -eq 0 || git add --pathspec-from-file="$marked_added"
217+
# TODO refactor abs
218+
var_marked_added="$(inject_prefix_into "$(cat "$marked_added")" "$repodir/")"
219+
marked_added_abs="/tmp/marked_added_abs"
220+
printf "%s" "$var_marked_added" > "$marked_added_abs"
221+
test "$had_adds" -eq 0 || git add --pathspec-from-file="$marked_added_abs"
185222

186223
# unstage if any "staged" lines were removed
187224

188-
staged_fullpaths="$(inject_prefix_into "$STAGED" "$repodir/")"
189225
were_staged="/tmp/were_staged"
190-
printf "%s\n" "$staged_fullpaths" > "$were_staged"
226+
printf "%s\n" "$STAGED" > "$were_staged"
191227

192228
delta_staged="/tmp/delta_staged"
193229
diff --minimal "$were_staged" "$marked_staged" > "$delta_staged" || {
@@ -198,7 +234,28 @@ git_add_files() {
198234
unmarked_staged="/tmp/unmarked_staged"
199235
grep "^<" "$delta_staged" | sed 's@^< @@g' > "$unmarked_staged"
200236

201-
git reset --pathspec-from-file="$unmarked_staged" HEAD
237+
# convert to absolute filepaths,
238+
# for --pathspec-from-file to work
239+
# TODO refactor abs
240+
var_unmarked_staged="$(cat "$unmarked_staged")"
241+
var_unmarked_staged_abs="$(inject_prefix_into "$var_unmarked_staged" "$repodir/")"
242+
unmarked_staged_abs="/tmp/unmarked_staged_abs"
243+
printf "%s" "$var_unmarked_staged_abs" > "$unmarked_staged_abs"
244+
245+
git reset --pathspec-from-file="$unmarked_staged_abs" HEAD
246+
}
247+
248+
# mark all lines as "wip" that have removed "add"
249+
250+
were_to_be_added="/tmp/were_to_be_added"
251+
printf "%s\n" "$ADD" > "$were_to_be_added"
252+
253+
delta_add="/tmp/delta_add"
254+
diff --minimal "$were_to_be_added" "$marked_added" > "$delta_add" || {
255+
unmarked_add="/tmp/unmarked_add"
256+
grep "^<" "$delta_add" | sed 's@^< @@g' > "$unmarked_add"
257+
258+
cat "$unmarked_add" "$marked_wip" | sort | uniq > "$FILE_WIP"
202259
}
203260
}
204261

syntax.gitaddfiles.vim

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ syn case match
1414
let s:c = escape((matchstr(getline('$'), '^[#;@!$%^&|:]\S\@!') . '#')[0], '^$.*[]~\"/')
1515

1616
syn match gitaddfilesAdd "\v^a%(dd)=>" nextgroup=gitaddfilesFile skipwhite
17+
syn match gitaddfilesWip "\v^w%(ip)=>" nextgroup=gitaddfilesFile skipwhite
1718
syn match gitaddfilesEdit "\v^e%(dit)=>" nextgroup=gitaddfilesFile skipwhite
1819
syn match gitaddfilesStaged "\v^s%(taged)=>" nextgroup=gitaddfilesFile skipwhite
1920
syn match gitaddfilesHalfstaged "\v^h%(alfstaged)=>" nextgroup=gitaddfilesFile skipwhite
@@ -26,7 +27,8 @@ exe 'syn match gitaddfilesComment "^\s*' . s:c . '.*" '
2627
unlet s:c
2728

2829
hi def link gitaddfilesAdd String
29-
hi def link gitaddfilesEdit Type
30+
hi def link gitaddfilesWip Type
31+
hi def link gitaddfilesEdit PreProc
3032
hi def link gitaddfilesStaged Conditional
3133
hi def link gitaddfilesHalfstaged Comment
3234
hi def link gitaddfilesNoop Comment

0 commit comments

Comments
 (0)