reccover/undo accidental file delete

This commit is contained in:
Bhupesh-V 2021-04-23 12:19:58 +05:30
parent ff6c0f54d1
commit 99edc9a6d3
2 changed files with 43 additions and 4 deletions

View file

@ -36,7 +36,7 @@
- [ ] Undo `git tag` (rename a tag)
- [ ] Undo `git rebase`
- [ ] Undo `git cherry-pick`
- [ ] Undo accidental file delete (Restore a deleted file after a commit)
- [x] Undo accidental file delete (Restore a deleted file after a commit)
- [ ] Undo `git worktree remove` (recover deleted work-tree)
## Installation
@ -65,6 +65,27 @@ curl -fsSL https://raw.githubusercontent.com/Bhupesh-V/ugit/master/ugit && chmod
curl -fsSL https://raw.githubusercontent.com/Bhupesh-V/ugit/master/ugit && chmod +x ugit && mv ugit /usr/local/bin
```
## Please read ⚠️
Git comes with a garbage collector ([in case you didn't know](https://git-scm.com/docs/git-gc)) therefore undoing some commands will become impossible if the entries are deleted from the reflog.
One way to prevent this is to increase default time limits before the reflog entries expire:
Add these configuration in your global `.gitconfig` file:
```gitconfig
[gc]
# default 90 days
reflogExpire = 200
```
Used to set how long records in a branches reflog should be preserved.
```gitconfig
[gc]
# default 30 days
reflogExpireUnreachable = 90
```
Used to set how long inaccessible reflog records should be preserved.
## Not satisfied? 😒️
You can read my in-process guide on [**How to undo anything in Git**](https://bhupesh.gitbook.io/notes/git/how-to-undo-anything-in-git)

24
ugit
View file

@ -1,6 +1,7 @@
#!/usr/bin/env bash
# ugit: Undo your last oopsie in Git
# Read the guide: https://bhupesh.gitbook.io/notes/git/how-to-undo-anything-in-git
# TODO: Add self-updating --update #
@ -42,6 +43,8 @@ display_menu() {
printf "%s\n" "Undo [git stash apply]"
printf "%s\n" "Undo [git tag -d] tag delete"
printf "%s\n" "Undo [git rebase]"
printf "%s\n" "Undo/Recover commited file delete"
printf "%s\n" "Undo/Recover uncommited file delete"
}
option=$(display_menu | nl -n ln | fzf --header="Don't worry we all mess up sometimes" --height 30% --reverse --pointer='ᐅ' --cycle | awk '{print $1}')
@ -141,10 +144,8 @@ undo_git_stash_apply() {
recover_deleted_tag() {
# only works for annotated tags? :(
printf "%s" "Note: Only annotated tags can be restored"
# git fsck --unreachable | grep tag
# to see changes git show <COMMIT_HASH>
# git update-ref refs/tags/<tag-name> <COMMIT_HASH>
read -p "Enter lost Tag name (e.g v1.2): " -r TAG_NAME
COMMIT_HASH=$(git fsck --no-progress --unreachable --tags | awk '/tagged/ {print $6}')
[[ -z "$COMMIT_HASH" ]] && printf "%s\n" "Unable to find any deleted tags :(" && exit 1
@ -161,6 +162,21 @@ recover_deleted_tag() {
fi
}
undo_file_delete() {
if [[ "$1" == "uncommited" ]]; then
DELETED_FILE=$(git ls-files -d | fzf --ansi --height 20% --reverse --header="Choose deleted file to recover" | awk '{print $1}')
if git checkout HEAD "$DELETED_FILE"; then
printf "%s\n" "$DELETED_FILE Successfully Recovered"
exit 0
fi
fi
commit_hash=$(git log --diff-filter=D --oneline| fzf --ansi --height 20% --reverse --header="Choose commit that deleted the file" | awk '{print $1}')
read -p "Enter complete filename: " -r FILENAME
if git checkout "$commit_hash"~1 -- "$FILENAME"; then
printf "%s\n" "$FILENAME Successfully Recovered"
fi
}
case $option in
1) undo_git_commit;;
2) undo_git_push;;
@ -176,4 +192,6 @@ case $option in
12) undo_git_stash_apply;;
13) recover_deleted_tag;;
14) do_git_reset "Choose commit just before rebase started";;
15) undo_file_delete;;
16) undo_file_delete "uncommited";;
esac