bimagic 1.5.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -2
- package/README.md +25 -2
- package/bimagic +199 -63
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2026 orion-kernel
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Bimagic - Git Wizard
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img width="400" style="border-radius: 12px;" alt="Image" src="
|
|
4
|
+
<img width="400" style="border-radius: 12px;" alt="Image" src="./Sample/logo.png" />
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">By Bimbok and adityapaul26</p>
|
|
@@ -42,6 +42,8 @@ Bimagic is an interactive command-line tool that streamlines common Git operatio
|
|
|
42
42
|
- 🎨 Theme Customization (ANSI and Hex color support)
|
|
43
43
|
- ⏳ Time Turner (Undo last commit)
|
|
44
44
|
- 🗃️ Stash operations (Push, Pop, List, Apply, Drop, Clear)
|
|
45
|
+
- 🔍 The Scrying Glass (Quick file preview with optional syntax highlighting)
|
|
46
|
+
- ⚡ Command Transparency (Displays the exact Git command being executed)
|
|
45
47
|
|
|
46
48
|
## Installation
|
|
47
49
|
|
|
@@ -153,6 +155,8 @@ export PATH="$HOME/bin:$PATH" # For user-local installation
|
|
|
153
155
|
- If not installed, the tool will not work.
|
|
154
156
|
- Node.js **v16 or higher**
|
|
155
157
|
- npm **v8+**
|
|
158
|
+
- [bat](https://github.com/sharkdp/bat) (optional; used for syntax highlighting in The Scrying Glass)
|
|
159
|
+
- [fzf](https://github.com/junegunn/fzf) (optional; used for side-by-side preview in The Scrying Glass)
|
|
156
160
|
|
|
157
161
|
## Configuration
|
|
158
162
|
|
|
@@ -371,7 +375,8 @@ At the top of the interface, a status box summarizes:
|
|
|
371
375
|
16. **Summon the Resurrection Stone (Recover lost code)** - Recover deleted commits or branches using Git reflog
|
|
372
376
|
17. **Revert commit(s)** - Revert one or more commits (multi-select)
|
|
373
377
|
18. **Stash operations** - Manage stashes (push, pop, list, apply, drop, clear)
|
|
374
|
-
19. **
|
|
378
|
+
19. **The Scrying Glass (Quick View)** - Browse and preview any file in the repository instantly
|
|
379
|
+
20. **Exit** - Quit the wizard
|
|
375
380
|
|
|
376
381
|
### Clone repository (Option 1)
|
|
377
382
|
|
|
@@ -543,6 +548,24 @@ Manage your git stashes with a comprehensive menu.
|
|
|
543
548
|
- **Drop**: Delete a specific stash
|
|
544
549
|
- **Clear**: Remove all stashes (with safety confirmation)
|
|
545
550
|
|
|
551
|
+
### The Scrying Glass (Option 19)
|
|
552
|
+
|
|
553
|
+
"The Scrying Glass" provides an instant, scrollable preview of any file in your repository—whether it's tracked by Git or just a new, untracked file.
|
|
554
|
+
|
|
555
|
+
#### Features:
|
|
556
|
+
|
|
557
|
+
- **Interactive Selection**: Quickly find files using an interactive filter.
|
|
558
|
+
- **Side-by-Side Preview**: Uses `fzf` (if installed) to provide a real-time preview of the file content while you browse the list.
|
|
559
|
+
- **Circular Selection**: Seamlessly wrap around from the last file to the first with infinite scrolling.
|
|
560
|
+
- **Themed Experience**: Selection and preview interface fully respect your custom `theme.wz` colors.
|
|
561
|
+
- **Scrollable Pager**: Uses `gum pager` for smooth reading of long files after selection.
|
|
562
|
+
- **Magic Highlight**: If `bat` is installed, it automatically provides syntax highlighting for a superior viewing experience.
|
|
563
|
+
- **Deep Integration**: Access it standalone from the main menu, or use it while adding/removing files to ensure you're acting on the right code.
|
|
564
|
+
|
|
565
|
+
### Command Transparency ⚡
|
|
566
|
+
|
|
567
|
+
Bimagic now shows you exactly what "spells" are being cast. Every time you perform a Git action through the wizard, the exact Git command is displayed in a vibrant, easy-to-read format. This ensures transparency, helps you learn Git commands, and provides confidence that the tool is doing exactly what you expect.
|
|
568
|
+
|
|
546
569
|
## Why Sudo Might Be Required
|
|
547
570
|
|
|
548
571
|
### Understanding the Need for Elevated Privileges
|
package/bimagic
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
VERSION="v1.
|
|
3
|
+
VERSION="v1.6.2"
|
|
4
4
|
|
|
5
5
|
if [[ "$1" == "--version" || "$1" == "-v" ]]; then
|
|
6
6
|
echo "Bimagic Git Wizard $VERSION"
|
|
@@ -118,6 +118,11 @@ play_sound() {
|
|
|
118
118
|
;;
|
|
119
119
|
esac
|
|
120
120
|
}
|
|
121
|
+
|
|
122
|
+
print_command() {
|
|
123
|
+
echo -e "${GRAY} ${PURPLE}Command:${NC} ${WHITE}$*${NC}"
|
|
124
|
+
}
|
|
125
|
+
|
|
121
126
|
print_status() {
|
|
122
127
|
gum style --foreground "$BIMAGIC_PRIMARY" "$1"
|
|
123
128
|
play_sound "success"
|
|
@@ -185,7 +190,9 @@ setup_remote() {
|
|
|
185
190
|
fi
|
|
186
191
|
|
|
187
192
|
if gum confirm "Set remote '$remote_name' to $remote_url?"; then
|
|
193
|
+
print_command "git remote remove \"$remote_name\""
|
|
188
194
|
git remote remove "$remote_name" 2>/dev/null
|
|
195
|
+
print_command "git remote add \"$remote_name\" \"$remote_url\""
|
|
189
196
|
git remote add "$remote_name" "$remote_url"
|
|
190
197
|
print_status " Remote '$remote_name' set to $remote_url"
|
|
191
198
|
return 0
|
|
@@ -447,6 +454,7 @@ clone_repo() {
|
|
|
447
454
|
print_status "Initializing interactive clone for $repo_name..."
|
|
448
455
|
|
|
449
456
|
# 1. Clone with --no-checkout and --filter=blob:none (downloads commits/trees, no file contents)
|
|
457
|
+
print_command "git clone --filter=blob:none --no-checkout $depth_arg \"$url\" \"$repo_name\""
|
|
450
458
|
print_status "Cloning structure for $repo_name..."
|
|
451
459
|
(
|
|
452
460
|
set -o pipefail
|
|
@@ -485,14 +493,8 @@ clone_repo() {
|
|
|
485
493
|
# FIX: Add --no-cone so Git accepts individual file paths
|
|
486
494
|
gum spin --title "Configuring sparse checkout..." -- git sparse-checkout init --no-cone
|
|
487
495
|
|
|
488
|
-
#
|
|
489
|
-
|
|
490
|
-
# that sparse-checkout patterns handle full paths.
|
|
491
|
-
# However, 'git sparse-checkout set' treats arguments as patterns.
|
|
492
|
-
# We turn off cone for precise file selection transparency if needed, but standard 'set' often works.
|
|
493
|
-
# To be safe for exact file paths, we simply pass them.
|
|
494
|
-
# If the list is huge, this might fail on command line length.
|
|
495
|
-
# Ideally we pipe to 'git sparse-checkout set --stdin', but gum returns newline separated.
|
|
496
|
+
# Set the selected paths
|
|
497
|
+
echo "$selected_paths" | git sparse-checkout set --stdin
|
|
496
498
|
|
|
497
499
|
print_status "Downloading selected files..."
|
|
498
500
|
(
|
|
@@ -510,6 +512,7 @@ clone_repo() {
|
|
|
510
512
|
|
|
511
513
|
else
|
|
512
514
|
# Standard clone with progress bar
|
|
515
|
+
print_command "git clone $depth_arg \"$url\" \"$repo_name\""
|
|
513
516
|
print_status "Cloning $url into $repo_name..."
|
|
514
517
|
|
|
515
518
|
# Use a subshell with pipefail to catch git clone errors
|
|
@@ -579,6 +582,7 @@ summon_gitignore() {
|
|
|
579
582
|
|
|
580
583
|
local url="https://raw.githubusercontent.com/github/gitignore/main/${template}.gitignore"
|
|
581
584
|
|
|
585
|
+
print_command "curl -sL \"$url\" -o .gitignore"
|
|
582
586
|
if gum spin --title "Fetching template..." -- curl -sL "$url" -o .gitignore; then
|
|
583
587
|
# Verify the file is not empty (curl might return 404 text if URL is wrong)
|
|
584
588
|
if grep -q "404: Not Found" .gitignore; then
|
|
@@ -653,6 +657,7 @@ ${body}"
|
|
|
653
657
|
echo
|
|
654
658
|
|
|
655
659
|
if gum confirm "Commit with this message?"; then
|
|
660
|
+
print_command "git commit -m \"$commit_msg\""
|
|
656
661
|
git commit -m "$commit_msg"
|
|
657
662
|
print_status " Mischief managed! (Commit successful)"
|
|
658
663
|
else
|
|
@@ -662,6 +667,7 @@ ${body}"
|
|
|
662
667
|
|
|
663
668
|
#function to display git graph
|
|
664
669
|
pretty_git_log() {
|
|
670
|
+
print_command "git log --graph --oneline --decorate --all"
|
|
665
671
|
git log --graph \
|
|
666
672
|
--abbrev-commit \
|
|
667
673
|
--decorate \
|
|
@@ -756,6 +762,7 @@ if [[ "$CLI_MODE" == "pull" ]]; then
|
|
|
756
762
|
fi
|
|
757
763
|
|
|
758
764
|
# 1. Fetch
|
|
765
|
+
print_command "git fetch --all"
|
|
759
766
|
if gum spin --title "Fetching updates..." -- git fetch --all; then
|
|
760
767
|
print_status "Fetch complete."
|
|
761
768
|
else
|
|
@@ -763,11 +770,11 @@ if [[ "$CLI_MODE" == "pull" ]]; then
|
|
|
763
770
|
fi
|
|
764
771
|
|
|
765
772
|
# 2. Pull
|
|
773
|
+
print_command "git pull --all"
|
|
766
774
|
if gum spin --title "Pulling all..." -- git pull --all; then
|
|
767
775
|
print_status "Pull all complete."
|
|
768
776
|
else
|
|
769
777
|
print_error "Pull failed. There might be conflicts or no upstream set."
|
|
770
|
-
exit 1
|
|
771
778
|
fi
|
|
772
779
|
exit 0
|
|
773
780
|
fi
|
|
@@ -812,17 +819,22 @@ if [[ "$CLI_MODE" == "undo" ]]; then
|
|
|
812
819
|
case "$undo_type" in
|
|
813
820
|
"Soft"*)
|
|
814
821
|
if [[ "$is_initial_commit" == "true" ]]; then
|
|
822
|
+
print_command "git update-ref -d HEAD"
|
|
815
823
|
git update-ref -d HEAD
|
|
816
824
|
else
|
|
825
|
+
print_command "git reset --soft HEAD~1"
|
|
817
826
|
git reset --soft HEAD~1
|
|
818
827
|
fi
|
|
819
828
|
print_status "✨ Success! I undid the commit, but kept your files ready to commit again."
|
|
820
829
|
;;
|
|
821
830
|
"Mixed"*)
|
|
822
831
|
if [[ "$is_initial_commit" == "true" ]]; then
|
|
832
|
+
print_command "git update-ref -d HEAD"
|
|
823
833
|
git update-ref -d HEAD
|
|
834
|
+
print_command "git rm --cached -r -q ."
|
|
824
835
|
git rm --cached -r -q .
|
|
825
836
|
else
|
|
837
|
+
print_command "git reset HEAD~1"
|
|
826
838
|
git reset HEAD~1
|
|
827
839
|
fi
|
|
828
840
|
print_status " Success! I undid the commit and unstaged the files."
|
|
@@ -831,10 +843,14 @@ if [[ "$CLI_MODE" == "undo" ]]; then
|
|
|
831
843
|
if gum confirm " DANGER: This deletes your work forever. Are you sure?"; then
|
|
832
844
|
if [[ "$is_initial_commit" == "true" ]]; then
|
|
833
845
|
# Unstage everything first, then clean to ensure files are deleted
|
|
846
|
+
print_command "git update-ref -d HEAD"
|
|
834
847
|
git update-ref -d HEAD
|
|
848
|
+
print_command "git rm --cached -r -q ."
|
|
835
849
|
git rm --cached -r -q . >/dev/null 2>&1
|
|
850
|
+
print_command "git clean -fd"
|
|
836
851
|
git clean -fd
|
|
837
852
|
else
|
|
853
|
+
print_command "git reset --hard HEAD~1"
|
|
838
854
|
git reset --hard HEAD~1
|
|
839
855
|
fi
|
|
840
856
|
print_status " Obliviate! The last commit and its changes are destroyed."
|
|
@@ -864,6 +880,7 @@ if [[ "$CLI_MODE" == "lazy" ]]; then
|
|
|
864
880
|
print_status " Lazy Wizard invoked!"
|
|
865
881
|
|
|
866
882
|
# 1. Add all changes
|
|
883
|
+
print_command "git add ."
|
|
867
884
|
if gum spin --title "Adding files..." -- git add .; then
|
|
868
885
|
print_status "Files added."
|
|
869
886
|
else
|
|
@@ -872,6 +889,7 @@ if [[ "$CLI_MODE" == "lazy" ]]; then
|
|
|
872
889
|
fi
|
|
873
890
|
|
|
874
891
|
# 2. Commit
|
|
892
|
+
print_command "git commit -m \"$CLI_MSG\""
|
|
875
893
|
if git commit -m "$CLI_MSG"; then
|
|
876
894
|
print_status "Committed: $CLI_MSG"
|
|
877
895
|
else
|
|
@@ -883,11 +901,13 @@ if [[ "$CLI_MODE" == "lazy" ]]; then
|
|
|
883
901
|
branch=$(get_current_branch)
|
|
884
902
|
print_status "Pushing to $branch..."
|
|
885
903
|
|
|
904
|
+
print_command "git push"
|
|
886
905
|
if gum spin --title "Pushing..." -- git push; then
|
|
887
906
|
print_status " Magic complete!"
|
|
888
907
|
else
|
|
889
908
|
# Try setting upstream if standard push failed
|
|
890
909
|
print_warning "Standard push failed. Trying to set upstream..."
|
|
910
|
+
print_command "git push -u origin \"$branch\""
|
|
891
911
|
if gum spin --title "Pushing (upstream)..." -- git push -u origin "$branch"; then
|
|
892
912
|
print_status " Magic complete (upstream set)!"
|
|
893
913
|
else
|
|
@@ -934,15 +954,18 @@ resurrect_commit() {
|
|
|
934
954
|
" Create a new branch here (Safest)")
|
|
935
955
|
local new_branch=$(gum input --placeholder "Enter new branch name (e.g., recovered-code)")
|
|
936
956
|
if [[ -n "$new_branch" ]]; then
|
|
957
|
+
print_command "git checkout -b \"$new_branch\" \"$target_hash\""
|
|
937
958
|
git checkout -b "$new_branch" "$target_hash"
|
|
938
959
|
print_status " Timeline restored! You are now on branch: $new_branch"
|
|
939
960
|
fi
|
|
940
961
|
;;
|
|
941
962
|
" Hard Reset current branch to here (Dangerous)")
|
|
942
963
|
if gum confirm "This will overwrite your CURRENT work. Are you absolutely sure?"; then
|
|
964
|
+
print_command "git reset --hard $target_hash"
|
|
943
965
|
git reset --hard "$target_hash"
|
|
944
|
-
print_status "
|
|
966
|
+
print_status " Timeline restored via hard reset!"
|
|
945
967
|
fi
|
|
968
|
+
|
|
946
969
|
;;
|
|
947
970
|
*)
|
|
948
971
|
print_status "The stone goes dormant."
|
|
@@ -950,6 +973,62 @@ resurrect_commit() {
|
|
|
950
973
|
esac
|
|
951
974
|
}
|
|
952
975
|
|
|
976
|
+
scrying_glass() {
|
|
977
|
+
print_status " Summoning the Scrying Glass..."
|
|
978
|
+
|
|
979
|
+
# Check if fzf is installed for the side-by-side preview experience
|
|
980
|
+
if command -v fzf &>/dev/null; then
|
|
981
|
+
local preview_cmd="cat {}"
|
|
982
|
+
if command -v bat &>/dev/null; then
|
|
983
|
+
preview_cmd="bat --color=always --style=numbers {}"
|
|
984
|
+
fi
|
|
985
|
+
|
|
986
|
+
# 1. Use fzf for interactive selection with side-by-side preview
|
|
987
|
+
# Map fzf colors to our theme variables
|
|
988
|
+
local file=$(git ls-files --cached --others --exclude-standard |
|
|
989
|
+
fzf --preview "$preview_cmd" \
|
|
990
|
+
--preview-window=right:60% \
|
|
991
|
+
--height=80% \
|
|
992
|
+
--layout=reverse \
|
|
993
|
+
--border \
|
|
994
|
+
--cycle \
|
|
995
|
+
--prompt=" Peer into: " \
|
|
996
|
+
--color="bg+:-1,fg+:$BIMAGIC_PRIMARY,hl:$BIMAGIC_SECONDARY,hl+:$BIMAGIC_SECONDARY,prompt:$BIMAGIC_INFO,pointer:$BIMAGIC_PRIMARY,marker:$BIMAGIC_SUCCESS,header:$BIMAGIC_PRIMARY,spinner:$BIMAGIC_PRIMARY,info:$BIMAGIC_MUTED")
|
|
997
|
+
|
|
998
|
+
if [[ -z "$file" ]]; then
|
|
999
|
+
print_status "The glass goes dark (Cancelled)."
|
|
1000
|
+
return 0
|
|
1001
|
+
fi
|
|
1002
|
+
|
|
1003
|
+
# After selection, we can optionally open it in a full pager if they want to read the whole thing
|
|
1004
|
+
if gum confirm "Open in full pager?"; then
|
|
1005
|
+
if command -v bat &>/dev/null; then
|
|
1006
|
+
bat --color=always "$file" | gum pager
|
|
1007
|
+
else
|
|
1008
|
+
gum pager <"$file"
|
|
1009
|
+
fi
|
|
1010
|
+
fi
|
|
1011
|
+
else
|
|
1012
|
+
# Fallback to standard gum behavior if fzf is missing
|
|
1013
|
+
# 1. Select the file using existing filter style
|
|
1014
|
+
local file=$(git ls-files --cached --others --exclude-standard |
|
|
1015
|
+
gum filter --placeholder "Select a file to peer into...")
|
|
1016
|
+
|
|
1017
|
+
if [[ -z "$file" ]]; then
|
|
1018
|
+
print_status "The glass goes dark (Cancelled)."
|
|
1019
|
+
return 0
|
|
1020
|
+
fi
|
|
1021
|
+
|
|
1022
|
+
# 2. Check for syntax highlighting capability
|
|
1023
|
+
print_status "Peering into: $file"
|
|
1024
|
+
if command -v bat &>/dev/null; then
|
|
1025
|
+
bat --color=always "$file" | gum pager
|
|
1026
|
+
else
|
|
1027
|
+
gum pager <"$file"
|
|
1028
|
+
fi
|
|
1029
|
+
fi
|
|
1030
|
+
}
|
|
1031
|
+
|
|
953
1032
|
show_welcome_banner() {
|
|
954
1033
|
clear
|
|
955
1034
|
echo -e "$(get_ansi_esc "$BANNER_COLOR_1")▗▖ ▄ ▄▄▄▄ ▗▄▖ ▗▄▄▖▄ ▗▄▄▖\033[0m"
|
|
@@ -1009,6 +1088,7 @@ while true; do
|
|
|
1009
1088
|
" Summon the Resurrection Stone (Recover lost code)" \
|
|
1010
1089
|
" Revert commit(s)" \
|
|
1011
1090
|
" Stash operations" \
|
|
1091
|
+
" The Scrying Glass (Quick View)" \
|
|
1012
1092
|
" Exit"
|
|
1013
1093
|
)
|
|
1014
1094
|
echo
|
|
@@ -1049,6 +1129,7 @@ while true; do
|
|
|
1049
1129
|
include_untracked=""
|
|
1050
1130
|
fi
|
|
1051
1131
|
|
|
1132
|
+
print_command "git stash push $include_untracked -m \"$msg\""
|
|
1052
1133
|
if git stash push $include_untracked -m "$msg"; then
|
|
1053
1134
|
print_status "Changes stashed successfully!"
|
|
1054
1135
|
else
|
|
@@ -1056,6 +1137,7 @@ while true; do
|
|
|
1056
1137
|
fi
|
|
1057
1138
|
;;
|
|
1058
1139
|
" Pop latest stash")
|
|
1140
|
+
print_command "git stash pop"
|
|
1059
1141
|
if git stash pop; then
|
|
1060
1142
|
print_status "Stash popped successfully!"
|
|
1061
1143
|
else
|
|
@@ -1078,6 +1160,7 @@ while true; do
|
|
|
1078
1160
|
stash_entry=$(git stash list | gum filter --placeholder "Select stash to apply")
|
|
1079
1161
|
if [[ -n "$stash_entry" ]]; then
|
|
1080
1162
|
stash_id=$(echo "$stash_entry" | cut -d: -f1)
|
|
1163
|
+
print_command "git stash apply $stash_id"
|
|
1081
1164
|
if git stash apply "$stash_id"; then
|
|
1082
1165
|
print_status "Applied $stash_id"
|
|
1083
1166
|
else
|
|
@@ -1095,6 +1178,7 @@ while true; do
|
|
|
1095
1178
|
if [[ -n "$stash_entry" ]]; then
|
|
1096
1179
|
stash_id=$(echo "$stash_entry" | cut -d: -f1)
|
|
1097
1180
|
if gum confirm "Are you sure you want to drop $stash_id?"; then
|
|
1181
|
+
print_command "git stash drop $stash_id"
|
|
1098
1182
|
if git stash drop "$stash_id"; then
|
|
1099
1183
|
print_status "Dropped $stash_id"
|
|
1100
1184
|
else
|
|
@@ -1110,6 +1194,7 @@ while true; do
|
|
|
1110
1194
|
fi
|
|
1111
1195
|
|
|
1112
1196
|
if gum confirm "DANGER: This will delete ALL stashes. Continue?"; then
|
|
1197
|
+
print_command "git stash clear"
|
|
1113
1198
|
if git stash clear; then
|
|
1114
1199
|
print_status "All stashes cleared."
|
|
1115
1200
|
else
|
|
@@ -1136,6 +1221,7 @@ while true; do
|
|
|
1136
1221
|
fi
|
|
1137
1222
|
|
|
1138
1223
|
if [[ "$dirname" == "." ]]; then
|
|
1224
|
+
print_command "git init"
|
|
1139
1225
|
git init
|
|
1140
1226
|
print_status "Repo initialized in current directory: $(pwd)"
|
|
1141
1227
|
else
|
|
@@ -1143,9 +1229,11 @@ while true; do
|
|
|
1143
1229
|
# Run init and rename in a subshell to avoid directory tracking issues
|
|
1144
1230
|
(
|
|
1145
1231
|
cd "$dirname" || exit 1
|
|
1232
|
+
print_command "git init"
|
|
1146
1233
|
git init
|
|
1147
1234
|
current_branch=$(git symbolic-ref --short HEAD 2>/dev/null)
|
|
1148
1235
|
if [[ "$current_branch" == "master" ]]; then
|
|
1236
|
+
print_command "git branch -M main"
|
|
1149
1237
|
git branch -M main
|
|
1150
1238
|
echo "Default branch renamed from 'master' to 'main' in $dirname"
|
|
1151
1239
|
fi
|
|
@@ -1154,30 +1242,49 @@ while true; do
|
|
|
1154
1242
|
fi
|
|
1155
1243
|
;;
|
|
1156
1244
|
" Add files")
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1245
|
+
while true; do
|
|
1246
|
+
add_choice=$(gum choose " Stage Files" " Preview Files" " Back")
|
|
1247
|
+
|
|
1248
|
+
if [[ "$add_choice" == " Back" ]]; then
|
|
1249
|
+
break
|
|
1250
|
+
fi
|
|
1251
|
+
|
|
1252
|
+
if [[ "$add_choice" == " Preview Files" ]]; then
|
|
1253
|
+
scrying_glass
|
|
1254
|
+
continue
|
|
1255
|
+
fi
|
|
1256
|
+
|
|
1257
|
+
# Stage Files logic
|
|
1258
|
+
# Show untracked + modified files, plus an [ALL] option
|
|
1259
|
+
files=$( (
|
|
1260
|
+
echo "[ALL]"
|
|
1261
|
+
git ls-files --others --modified --exclude-standard
|
|
1262
|
+
) | gum filter --no-limit --placeholder "Select files to add")
|
|
1263
|
+
|
|
1264
|
+
if [[ -z "$files" ]]; then
|
|
1265
|
+
print_warning "No files selected."
|
|
1171
1266
|
else
|
|
1172
|
-
#
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1267
|
+
# gum filter returns selected items separated by newlines.
|
|
1268
|
+
# We need to handle the case where [ALL] is selected along with other files.
|
|
1269
|
+
if echo "$files" | grep -q "\[ALL\]"; then
|
|
1270
|
+
print_command "git add ."
|
|
1271
|
+
git add .
|
|
1272
|
+
print_status "All files staged."
|
|
1273
|
+
else
|
|
1274
|
+
# Correctly handle filenames with spaces by reading line by line
|
|
1275
|
+
echo "$files" | while read -r f; do
|
|
1276
|
+
if [[ -n "$f" ]]; then
|
|
1277
|
+
print_command "git add \"$f\""
|
|
1278
|
+
git add "$f"
|
|
1279
|
+
fi
|
|
1280
|
+
done
|
|
1281
|
+
print_status "Selected files staged."
|
|
1282
|
+
# Optionally, list the files that were staged
|
|
1283
|
+
echo "$files"
|
|
1284
|
+
fi
|
|
1179
1285
|
fi
|
|
1180
|
-
|
|
1286
|
+
break
|
|
1287
|
+
done
|
|
1181
1288
|
;;
|
|
1182
1289
|
" Commit changes")
|
|
1183
1290
|
commit_mode=$(gum choose " Magic Commit (Builder)" " Quick Commit (One-line)")
|
|
@@ -1192,6 +1299,7 @@ while true; do
|
|
|
1192
1299
|
fi
|
|
1193
1300
|
|
|
1194
1301
|
if gum confirm "Commit changes?"; then
|
|
1302
|
+
print_command "git commit -m \"$msg\""
|
|
1195
1303
|
git commit -m "$msg"
|
|
1196
1304
|
print_status "Commit done!"
|
|
1197
1305
|
else
|
|
@@ -1225,6 +1333,7 @@ while true; do
|
|
|
1225
1333
|
|
|
1226
1334
|
if gum confirm "Push branch '$branch' to '$remote'?"; then
|
|
1227
1335
|
echo "Pushing branch '$branch' to '$remote'..."
|
|
1336
|
+
print_command "git push -u \"$remote\" \"$branch\""
|
|
1228
1337
|
gum spin --title "Pushing..." -- git push -u "$remote" "$branch"
|
|
1229
1338
|
else
|
|
1230
1339
|
print_status "Push cancelled."
|
|
@@ -1245,6 +1354,7 @@ while true; do
|
|
|
1245
1354
|
case "$pull_choice" in
|
|
1246
1355
|
"Pull all")
|
|
1247
1356
|
if gum confirm "Run 'git pull --all'?"; then
|
|
1357
|
+
print_command "git pull --all"
|
|
1248
1358
|
gum spin --title "Pulling all..." -- git pull --all
|
|
1249
1359
|
print_status "Pull all complete."
|
|
1250
1360
|
else
|
|
@@ -1268,6 +1378,7 @@ while true; do
|
|
|
1268
1378
|
|
|
1269
1379
|
if [[ -n "$remote" ]]; then
|
|
1270
1380
|
if gum confirm "Pull branch '$branch' from '$remote'?"; then
|
|
1381
|
+
print_command "git pull \"$remote\" \"$branch\""
|
|
1271
1382
|
gum spin --title "Pulling..." -- git pull "$remote" "$branch"
|
|
1272
1383
|
else
|
|
1273
1384
|
print_status "Pull cancelled."
|
|
@@ -1296,6 +1407,7 @@ while true; do
|
|
|
1296
1407
|
# Use gum filter to select from existing branches
|
|
1297
1408
|
existing_branch=$(git branch --format='%(refname:short)' | gum filter --placeholder "Select branch to switch to")
|
|
1298
1409
|
if [[ -n "$existing_branch" ]]; then
|
|
1410
|
+
print_command "git checkout \"$existing_branch\""
|
|
1299
1411
|
git checkout "$existing_branch"
|
|
1300
1412
|
print_status "Switched to branch: $existing_branch"
|
|
1301
1413
|
else
|
|
@@ -1305,6 +1417,7 @@ while true; do
|
|
|
1305
1417
|
"Create new branch")
|
|
1306
1418
|
new_branch=$(gum input --placeholder "Enter new branch name")
|
|
1307
1419
|
if [[ -n "$new_branch" ]]; then
|
|
1420
|
+
print_command "git checkout -b \"$new_branch\""
|
|
1308
1421
|
git checkout -b "$new_branch"
|
|
1309
1422
|
print_status "Created and switched to new branch: $new_branch"
|
|
1310
1423
|
else
|
|
@@ -1323,40 +1436,57 @@ while true; do
|
|
|
1323
1436
|
git status
|
|
1324
1437
|
;;
|
|
1325
1438
|
" Remove files/folders (rm)")
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
gum filter --no-limit --placeholder "Select files/folders to remove")
|
|
1439
|
+
while true; do
|
|
1440
|
+
remove_choice=$(gum choose "Remove Files" "Preview Files" "Back")
|
|
1329
1441
|
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
fi
|
|
1442
|
+
if [[ "$remove_choice" == "Back" ]]; then
|
|
1443
|
+
break
|
|
1444
|
+
fi
|
|
1334
1445
|
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
tput sgr0
|
|
1340
|
-
echo
|
|
1446
|
+
if [[ "$remove_choice" == "Preview Files" ]]; then
|
|
1447
|
+
scrying_glass
|
|
1448
|
+
continue
|
|
1449
|
+
fi
|
|
1341
1450
|
|
|
1342
|
-
|
|
1343
|
-
#
|
|
1344
|
-
|
|
1345
|
-
|
|
1451
|
+
# Remove Files logic
|
|
1452
|
+
# List tracked + untracked files for removal
|
|
1453
|
+
files=$(git ls-files --cached --others --exclude-standard |
|
|
1454
|
+
gum filter --no-limit --placeholder "Select files/folders to remove")
|
|
1346
1455
|
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1456
|
+
if [[ -z "$files" ]]; then
|
|
1457
|
+
print_warning "No files selected."
|
|
1458
|
+
break
|
|
1459
|
+
fi
|
|
1460
|
+
|
|
1461
|
+
echo "Files selected for removal:"
|
|
1462
|
+
# Use 'tput' for better visual separation and color
|
|
1463
|
+
tput setaf 3
|
|
1464
|
+
echo "$files"
|
|
1465
|
+
tput sgr0
|
|
1466
|
+
echo
|
|
1467
|
+
|
|
1468
|
+
if gum confirm "Confirm removal? This cannot be undone."; then
|
|
1469
|
+
# Use a 'while read' loop to correctly handle filenames with spaces
|
|
1470
|
+
echo "$files" | while read -r f; do
|
|
1471
|
+
if [[ -z "$f" ]]; then continue; fi # Skip empty lines
|
|
1472
|
+
|
|
1473
|
+
# Check if the file is tracked by git
|
|
1474
|
+
if git ls-files --error-unmatch "$f" >/dev/null 2>&1; then
|
|
1475
|
+
# It's a tracked file, use 'git rm'
|
|
1476
|
+
print_command "git rm -rf \"$f\""
|
|
1477
|
+
git rm -rf "$f"
|
|
1478
|
+
else
|
|
1479
|
+
# It's an untracked file, use 'rm'
|
|
1480
|
+
print_command "rm -rf \"$f\""
|
|
1481
|
+
rm -rf "$f"
|
|
1482
|
+
fi
|
|
1483
|
+
done
|
|
1484
|
+
print_status "Selected files/folders have been removed."
|
|
1485
|
+
else
|
|
1486
|
+
print_status "Operation cancelled."
|
|
1487
|
+
fi
|
|
1488
|
+
break
|
|
1489
|
+
done
|
|
1360
1490
|
;;
|
|
1361
1491
|
" Uninitialize repo")
|
|
1362
1492
|
print_warning "This will completely uninitialize the Git repository in this folder."
|
|
@@ -1365,6 +1495,7 @@ while true; do
|
|
|
1365
1495
|
|
|
1366
1496
|
if gum confirm "Are you sure you want to continue?"; then
|
|
1367
1497
|
if [ -d ".git" ]; then
|
|
1498
|
+
print_command "rm -rf .git"
|
|
1368
1499
|
rm -rf .git
|
|
1369
1500
|
print_status "Git repository has been uninitialized."
|
|
1370
1501
|
else
|
|
@@ -1374,6 +1505,9 @@ while true; do
|
|
|
1374
1505
|
print_status "Operation cancelled."
|
|
1375
1506
|
fi
|
|
1376
1507
|
;;
|
|
1508
|
+
" The Scrying Glass (Quick View)")
|
|
1509
|
+
scrying_glass
|
|
1510
|
+
;;
|
|
1377
1511
|
" Exit")
|
|
1378
1512
|
if gum confirm "Are you sure you want to exit?"; then
|
|
1379
1513
|
echo "Git Wizard vanishes in a puff of smoke..."
|
|
@@ -1397,6 +1531,7 @@ while true; do
|
|
|
1397
1531
|
else
|
|
1398
1532
|
if gum confirm "Merge branch '$merge_branch' into '$current_branch'?"; then
|
|
1399
1533
|
echo "Merging branch '$merge_branch' into '$current_branch'..."
|
|
1534
|
+
print_command "git merge \"$merge_branch\""
|
|
1400
1535
|
if gum spin --title "Merging..." -- git merge "$merge_branch"; then
|
|
1401
1536
|
print_status "Merge successful!"
|
|
1402
1537
|
else
|
|
@@ -1440,6 +1575,7 @@ while true; do
|
|
|
1440
1575
|
if gum confirm "Confirm revert?"; then
|
|
1441
1576
|
for c in $commits; do
|
|
1442
1577
|
echo "Reverting commit $c..."
|
|
1578
|
+
print_command "git revert --no-edit $c"
|
|
1443
1579
|
if git revert --no-edit "$c"; then
|
|
1444
1580
|
print_status "Commit $c reverted."
|
|
1445
1581
|
else
|