Last active
May 10, 2024 15:50
-
-
Save senthilmurukang/29b55a0c0e8694c406991799153f3c43 to your computer and use it in GitHub Desktop.
shell script to copy stash from one folder to another. Example usage: ./stash-copy.sh /path/to/git/old/folder /path/to/git/new/folder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
src=$1 | |
dest=$2 | |
current_directory=$(pwd) | |
cd $src | |
stashes=$(git stash list) | |
IFS=$'\n' | |
stash_messages=() | |
for stash in $stashes; do | |
stash_number=$(echo $stash | cut -d ':' -f 1 | sed 's/^stash@{\([0-9][0-9]*\)}/\1/g') | |
stash_message=$(echo $stash | cut -d ':' -f 2- | xargs) | |
stash_messages+=($stash_message) | |
git --no-pager stash show "stash@{$stash_number}" -p >"patch_$stash_number" | |
done | |
IFS=$' ' | |
cd $dest | |
echo "Number of stashes: ${#stash_messages[@]}" | |
for ((i = ${#stash_messages[@]} - 1; i >= 0; i--)); do | |
git apply "$src/patch_$i" | |
git stash push -m "${stash_messages[$i]}" > /dev/null | |
rm "$src/patch_$i" | |
done | |
cd $current_directory |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@senthilmurukang
Got it
1- Save staged changes without include untracked changes
git --no-pager stash show stash@{1} -p > patch_1
2- Save staged changes only untracked changes
git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 stash@{1}^3 >> patch_1(diff against an empty tree object)
3- Apply staged save in patch_1 fixing trailing whitespaces
git apply --reject --whitespace=fix patch_1
Alternative for step 2 recommended in case git changes its hash algorithm:
git diff $(git hash-object -t tree /dev/null) stash@{1}^3 >> patch_1
Explanation:
4b825dc642cb6eb9a060e54bf8d69288fbee4904 -> Git always has an empty tree in every repository whose ID is the magic number 4b825dc642cb6eb9a060e54bf8d69288fbee4904
stash@{1}^3 -> Untracked Files that were staged
printf "tree 0\0" | sha1sum
git hash-object -t tree /dev/null
git diff $(printf "tree 0\0" | sha1sum | awk '{print $1}') stash@{1}^3 >> patch_1
Source:
https://ericbouchut.com/2021/07/22/git-stash-internals/
https://ah.thameera.com/4b825dc642cb6eb9a060e54bf8d69288fbee4904/
git apply --reject --whitespace=fix patch_1
--whitespace=fix ensures whitespace errors are fixed before path is applied
--reject ensures atomicity (so no working directory files are modified if patch will not apply)
Source:
https://git-scm.com/docs/git-apply(check out for *.rej files with --reject param)