Skip to content

Commit b5e5559

Browse files
committed
BUG: Better handle file renames and copies
1 parent e4e478c commit b5e5559

File tree

1 file changed

+49
-9
lines changed

1 file changed

+49
-9
lines changed

myba.sh

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,37 @@ _parallelize () {
318318
}
319319

320320

321-
_commit_encrypt_one () { if [ "$1" != 'D' ]; then _encrypt_file "$2" "$(_encrypted_path "$2")"; fi; }
321+
_commit_encrypt_one () (
322+
_status="$(echo "$1" | cut -c1)" # "R100", "C100", ...
323+
# Reference: https://git-scm.com/docs/git-status#_output
324+
if [ "$_status" = 'A' ] || [ "$_status" = 'M' ]; then # newly added / modified
325+
_path="$2"
326+
elif [ "$_status" = 'R' ] || [ "$_status" = 'C' ]; then # renamed / copied
327+
_path="$(echo "$2" | cut -f2)"
328+
elif [ "$_status" = 'T' ]; then # typechange (regular file, symlink or submodule)
329+
# TODO: If readlink -f is in repo, simply commit a link to it?
330+
# Requires the same kind of check on decode side
331+
# TODO: Assert not submodule :)
332+
# Currently warn on anything but a file
333+
if [ ! -f "$2" ]; then
334+
warn "WARNING: Only regular files supported. A copy of '$2' will be made."
335+
fi
336+
_path="$2"
337+
else
338+
[ "$_status" = 'D' ] || [ "$_status" = 'U' ] || {
339+
warn "ERROR: Unknown git status '$1' for '$2' (known types: AMDRC)"
340+
}
341+
return 0
342+
fi
343+
_encrypt_file "$_path" "$(_encrypted_path "$_path")"
344+
)
345+
346+
347+
_commit_delete_enc_path () {
348+
git_enc lfs untrack "$1" || true # Ok if Git LFS is not used
349+
git_enc rm -f --sparse "$1"
350+
}
351+
322352

323353
cmd_commit () {
324354
# Commit to plain repo
@@ -329,16 +359,26 @@ cmd_commit () {
329359
manifest_path="manifest/$(git_plain rev-parse HEAD)"
330360
git_plain show --name-status --pretty=format: HEAD |
331361
_parallelize 8 2 _commit_encrypt_one
362+
# Do git stuff here and now, single process, avoiding errors like:
363+
# fatal: Unable to create .../_encrypted/.git/index.lock': File exists
332364
git_plain show --name-status --pretty=format: HEAD |
333-
# Do git stuff hereplace single process to avoid errors like
334-
# fatal: Unable to create .../_encrypted/.git/index.lock': File exists
335365
while IFS="$_tab" read -r _status _path; do
336-
_enc_path="$(_encrypted_path "$_path")"
337-
338-
if [ "$_status" = "D" ]; then
339-
git_enc lfs untrack "$_enc_path" || true # Ok if Git LFS is not used
340-
git_enc rm -f --sparse "$_enc_path"
341-
else
366+
_status="$(echo "$_status" | cut -c1)"
367+
# Handle statuses
368+
# Reference: https://git-scm.com/docs/git-status#_output
369+
if [ "$_status" = 'D' ]; then
370+
_commit_delete_enc_path "$(_encrypted_path "$_path")"
371+
elif [ "$_status" = 'R' ]; then # renamed
372+
_path_old="$(echo "$_path" | cut -f1)"
373+
_commit_delete_enc_path "$(_encrypted_path "$_path_old")"
374+
_path="$(echo "$_path" | cut -f2)"
375+
elif [ "$_status" = 'C' ]; then # copied
376+
_path="$(echo "$_path" | cut -f2)"
377+
fi
378+
# Add new encrypted file
379+
if [ "$_status" = 'A' ] || [ "$_status" = 'M' ] ||
380+
[ "$_status" = 'R' ] || [ "$_status" = 'C' ]; then
381+
_enc_path="$(_encrypted_path "$_path")"
342382
# If file larger than 40 MB, configure Git LFS
343383
if [ "$(_file_size "$ENC_REPO/$_enc_path")" -gt $((40 * 1024 * 1024)) ]; then
344384
git_enc lfs track --filename "$_enc_path"

0 commit comments

Comments
 (0)