@@ -437,7 +437,7 @@ function olderThanMinutes() {
437
437
return " ${?} "
438
438
else
439
439
echo >&2
440
- echo " [1;31mWARNING[0m: neither a find that supports -mmin (such as GNU find) or perl is available, disabling remote status checking. Install GNU find as gfind or perl to enable this feature, or set GIT_PROMPT_FETCH_REMOTE_STATUS=0 to disable this warning." >&2
440
+ echo " [1;31mWARNING [0m: neither a find that supports -mmin (such as GNU find) or perl is available, disabling remote status checking. Install GNU find as gfind or perl to enable this feature, or set GIT_PROMPT_FETCH_REMOTE_STATUS=0 to disable this warning." >&2
441
441
echo >&2
442
442
GIT_PROMPT_FETCH_REMOTE_STATUS=0
443
443
return 1
@@ -485,17 +485,52 @@ function replaceSymbols() {
485
485
}
486
486
487
487
function createPrivateIndex {
488
- # Create a copy of the index to avoid conflicts with parallel git commands, e.g. git rebase.
488
+ # Create a temporary directory and copy of the index to avoid conflicts
489
+ # with parallel git commands, e.g. git rebase.
490
+ # Returns the path to the temporary directory, or empty string on failure.
489
491
local __GIT_INDEX_FILE
490
- local __GIT_INDEX_PRIVATE
492
+ local __GIT_INDEX_PRIVATE_DIR
493
+ local __GIT_INDEX_PRIVATE_PATH
494
+
495
+ # Determine the original index file path
491
496
if [[ -z " ${GIT_INDEX_FILE+x} " ]]; then
492
- __GIT_INDEX_FILE=" $( git rev-parse --git-dir) /index"
497
+ # Ensure git command runs in the correct directory context if needed,
498
+ # though rev-parse --git-dir should be robust.
499
+ __GIT_INDEX_FILE=" $( git rev-parse --git-dir 2> /dev/null) /index"
500
+ if [[ $? -ne 0 || -z " $__GIT_INDEX_FILE " || ! -f " $__GIT_INDEX_FILE " ]]; then
501
+ echo " bash-git-prompt: Could not find git index file." >&2
502
+ return 1
503
+ fi
493
504
else
494
505
__GIT_INDEX_FILE=" ${GIT_INDEX_FILE} "
506
+ if [[ ! -f " $__GIT_INDEX_FILE " ]]; then
507
+ echo " bash-git-prompt: Specified GIT_INDEX_FILE does not exist: ${__GIT_INDEX_FILE} " >&2
508
+ return 1
509
+ fi
495
510
fi
496
- __GIT_INDEX_PRIVATE=" ${TMPDIR:-/ tmp} /git-index-private$$ "
497
- command cp " ${__GIT_INDEX_FILE} " " ${__GIT_INDEX_PRIVATE} " 2> /dev/null
498
- echo " ${__GIT_INDEX_PRIVATE} "
511
+
512
+ # Use mktemp -d to create a secure temporary directory
513
+ # The template ensures the directory name starts with 'git-prompt-index.'
514
+ __GIT_INDEX_PRIVATE_DIR=$( mktemp -d " ${TMPDIR:-/ tmp} /git-prompt-index.XXXXXXXXXX" )
515
+ if [[ $? -ne 0 || -z " $__GIT_INDEX_PRIVATE_DIR " || ! -d " $__GIT_INDEX_PRIVATE_DIR " ]]; then
516
+ echo " bash-git-prompt: Failed to create temporary directory." >&2
517
+ return 1
518
+ fi
519
+
520
+ # Define the path for the index copy within the temporary directory
521
+ __GIT_INDEX_PRIVATE_PATH=" ${__GIT_INDEX_PRIVATE_DIR} /index"
522
+
523
+ # Copy the original index to the temporary location
524
+ command cp " ${__GIT_INDEX_FILE} " " ${__GIT_INDEX_PRIVATE_PATH} " 2> /dev/null
525
+ if [[ $? -ne 0 ]]; then
526
+ echo " bash-git-prompt: Failed to copy git index to temporary directory: ${__GIT_INDEX_PRIVATE_DIR} " >&2
527
+ command rm -rf " ${__GIT_INDEX_PRIVATE_DIR} " # Clean up the created temp dir if copy fails
528
+ return 1
529
+ fi
530
+
531
+ # Return the path to the temporary directory
532
+ echo " ${__GIT_INDEX_PRIVATE_DIR} "
533
+ return 0
499
534
}
500
535
501
536
function get_branch_prefix() {
@@ -541,14 +576,55 @@ function updatePrompt() {
541
576
export __GIT_PROMPT_SHOW_UNTRACKED_FILES=" ${GIT_PROMPT_SHOW_UNTRACKED_FILES-normal} "
542
577
export __GIT_PROMPT_SHOW_CHANGED_FILES_COUNT=" ${GIT_PROMPT_SHOW_CHANGED_FILES_COUNT:- 1} "
543
578
544
- local GIT_INDEX_PRIVATE=" $( createPrivateIndex) "
545
- # important to define GIT_INDEX_FILE as local: This way it only affects this function (and below) - even with the export afterwards
579
+ # Create private index directory
580
+ local GIT_INDEX_PRIVATE_DIR
581
+ GIT_INDEX_PRIVATE_DIR=$( createPrivateIndex)
582
+ local create_private_index_exit_code=$?
583
+
584
+ # Define local variable for cleanup, regardless of success/failure of createPrivateIndex
585
+ # This ensures cleanup attempt if the directory path was partially created or returned.
586
+ local -r final_git_index_private_dir=" ${GIT_INDEX_PRIVATE_DIR} "
587
+
588
+ # Check if private index creation failed
589
+ if [[ $create_private_index_exit_code -ne 0 ]]; then
590
+ # Error message already printed by createPrivateIndex
591
+ # Set empty prompt and return to avoid running git status with potential issues
592
+ PS1=" ${EMPTY_PROMPT} "
593
+ # Attempt cleanup in case directory was partially created
594
+ [[ -n " $final_git_index_private_dir " ]] && command rm -rf " ${final_git_index_private_dir} " 2> /dev/null
595
+ return 1 # Indicate an issue
596
+ fi
597
+
598
+ # Define the path to the private index file within the temp directory
599
+ local GIT_INDEX_PRIVATE=" ${final_git_index_private_dir} /index"
600
+ # Important: define GIT_INDEX_FILE as local. Export it for __GIT_STATUS_CMD.
546
601
local GIT_INDEX_FILE
547
602
export GIT_INDEX_FILE=" ${GIT_INDEX_PRIVATE} "
548
603
549
604
local -a git_status_fields
550
- while IFS=$' \n ' read -r line; do git_status_fields+=(" ${line} " ); done < <( " ${__GIT_STATUS_CMD} " 2> /dev/null)
605
+ local git_status_exit_code=0
606
+ # Use a subshell to isolate potential errors and ensure cleanup happens
607
+ (
608
+ # Run the status command. Redirect stderr to avoid cluttering the user's terminal on errors.
609
+ while IFS=$' \n ' read -r line; do git_status_fields+=(" ${line} " ); done < <( " ${__GIT_STATUS_CMD} " 2> /dev/null)
610
+ )
611
+ git_status_exit_code=$?
612
+
613
+ # Check if git status command failed or returned no data
614
+ if [[ $git_status_exit_code -ne 0 || ${# git_status_fields[@]} -eq 0 ]]; then
615
+ # Git status failed or repo is gone? Set empty prompt and clean up.
616
+ PS1=" ${EMPTY_PROMPT} "
617
+ command rm -rf " ${final_git_index_private_dir} " 2> /dev/null
618
+ # Maybe print a warning if the exit code was non-zero?
619
+ if [[ $git_status_exit_code -ne 0 ]]; then
620
+ echo " bash-git-prompt: git status command failed (exit code ${git_status_exit_code} )." >&2
621
+ fi
622
+ # Unset exported variable
623
+ unset GIT_INDEX_FILE
624
+ return 1 # Indicate an issue
625
+ fi
551
626
627
+ # Process git status fields
552
628
export GIT_BRANCH=$( replaceSymbols " ${git_status_fields[@]: 0: 1} " )
553
629
if [[ $__GIT_PROMPT_SHOW_TRACKING != " 0" ]]; then
554
630
local GIT_REMOTE=" $( replaceSymbols " ${git_status_fields[@]: 1: 1} " ) "
@@ -578,6 +654,7 @@ function updatePrompt() {
578
654
local GIT_DETACHED_HEAD=" ${git_status_fields[@]: 10: 1} "
579
655
580
656
local NEW_PROMPT=" ${EMPTY_PROMPT} "
657
+ # Check if git_status_fields has content (redundant due to earlier check, but safe)
581
658
if [[ " ${# git_status_fields[@]} " -gt 0 ]]; then
582
659
583
660
if [[ -z " ${GIT_REMOTE_USERNAME_REPO+x} " ]]; then
@@ -640,11 +717,18 @@ function updatePrompt() {
640
717
NEW_PROMPT=" ${PROMPT_START} $( ${prompt_callback} ) $( gp_add_virtualenv_to_prompt) ${STATUS_PREFIX}${STATUS}${PROMPT_END} "
641
718
fi
642
719
else
720
+ # This case should ideally not be reached due to the check after running __GIT_STATUS_CMD
643
721
NEW_PROMPT=" ${EMPTY_PROMPT} "
644
722
fi
645
723
724
+ # Final PS1 assignment
646
725
PS1=" ${NEW_PROMPT// _LAST_COMMAND_INDICATOR_/ ${LAST_COMMAND_INDICATOR}${ResetColor} } "
647
- command rm " ${GIT_INDEX_PRIVATE} " 2> /dev/null
726
+
727
+ # Cleanup the temporary directory
728
+ command rm -rf " ${final_git_index_private_dir} " 2> /dev/null
729
+
730
+ # Unset the exported variable
731
+ unset GIT_INDEX_FILE
648
732
}
649
733
650
734
# Helper function that returns virtual env information to be set in prompt
@@ -769,3 +853,5 @@ function gp_install_prompt {
769
853
}
770
854
771
855
gp_install_prompt
856
+
857
+
0 commit comments