├── README.md └── git-redate /README.md: -------------------------------------------------------------------------------- 1 | # git-redate 2 | ### Made by [Potato Labs](http://taterlabs.com) 3 | 4 | Change the dates of several git commits with a single command. 5 | 6 | ![alt tag](https://i.stack.imgur.com/yE4cQ.gif) 7 | 8 | # Installation 9 | 10 | For homebrew users, you need to run `brew tap PotatoLabs/homebrew-git-redate` and then `brew install git-redate`. 11 | 12 | If you're not using homebrew, you can clone this repo and move the `git-redate` file into any folders in your $PATH. Restart your terminal afterwards and you're good to go! 13 | 14 | For window's users, you may paste the file into `${INSTALLATION_PATH}\mingw64\libexec\git-core`. Assuming you used the default settings the installation path will be `C:\Program Files\Git`. 15 | 16 | # Usage 17 | 18 | Simply run: `git redate --commits [[number of commits to view]]`. You'll have to force push in order for your commit history to be rewritten. 19 | 20 | To be able to edit all the commits at once add the --all option: `git redate --all` 21 | 22 | **Make sure to run this on a clean working directory otherwise it won't work.** 23 | 24 | The `--commits` (a.k.a. `-c`) argument is optional, and defaults to 5 if not provided. 25 | 26 | -------------------------------------------------------------------------------- /git-redate: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | is_git_repo() { 4 | git rev-parse --show-toplevel > /dev/null 2>&1 5 | result=$? 6 | if test $result != 0; then 7 | >&2 echo 'Not a git repo!' 8 | exit $result 9 | fi 10 | } 11 | 12 | is_git_repo 13 | 14 | make_editor_choice() { 15 | 16 | echo "Which editor do you want to use for this repo?\n"; 17 | echo "1. VI\n"; 18 | echo "2. NANO\n"; 19 | echo "3. Your own\n" 20 | echo "You Choose: "; 21 | 22 | read CHOOSE_EDITOR 23 | } 24 | 25 | get_editor_executable() { 26 | 27 | echo "What is the path to your prefered test editor?\n"; 28 | read EDITOR_PATH 29 | } 30 | 31 | 32 | is_has_editor() { 33 | SETTINGS_FILE="~/.redate-settings"; 34 | if [ -f "$SETTINGS_FILE" ] 35 | then 36 | OUR_EDITOR=$(cat ${SETTINGS_FILE}); 37 | elif [ ! -z "$EDITOR" ] 38 | then 39 | OUR_EDITOR="$EDITOR"; 40 | else 41 | make_editor_choice; 42 | if [ ${CHOOSE_EDITOR} == 3 ] || [ ${CHOOSE_EDITOR} == "3" ]; then 43 | get_editor_executable 44 | OUR_EDITOR=${EDITOR_PATH} 45 | elif [ ${CHOOSE_EDITOR} == 1 ] || [ ${CHOOSE_EDITOR} == "1" ]; then 46 | OUR_EDITOR="vi"; 47 | else 48 | OUR_EDITOR="nano"; 49 | fi 50 | echo ${OUR_EDITOR} > ${SETTINGS_FILE} 51 | fi 52 | } 53 | 54 | is_has_editor 55 | 56 | 57 | ALL=0 58 | DEBUG=0 59 | LIMITCHUNKS=20 60 | 61 | while [[ $# -ge 1 ]] 62 | do 63 | key="$1" 64 | 65 | case $key in 66 | -c| --commits) 67 | COMMITS="$2" 68 | if [ -z "${COMMITS}" ]; then COMMITS="5"; fi; 69 | shift 70 | ;; 71 | -l| --limit) 72 | LIMITCHUNKS="$2" 73 | if [ -z "${LIMITCHUNKS}" ]; then LIMITCHUNKS="20"; fi; 74 | shift 75 | ;; 76 | -d| --debug) 77 | DEBUG=1 78 | shift 79 | ;; 80 | -a| --all) 81 | ALL=1 82 | shift 83 | ;; 84 | *) 85 | # unknown option 86 | ;; 87 | esac 88 | shift 89 | done 90 | 91 | die () { 92 | echo >&2 `basename $0`: $* 93 | exit 1 94 | } 95 | 96 | tmpfile=$(mktemp gitblah-XXXX) 97 | [ -f "$tmpfile" ] || die "could not get tmpfile=[$tmpfile]" 98 | trap "rm -f $tmpfile" EXIT 99 | 100 | 101 | datefmt=%cI 102 | if [ "`git log -n1 --pretty=format:"$datefmt"`" == "$datefmt" ]; 103 | then 104 | datefmt=%ci 105 | fi 106 | 107 | if [ "${ALL}" -eq 1 ]; 108 | then 109 | git log --pretty=format:"$datefmt | %H | %s" > $tmpfile; 110 | else 111 | if [ -n "${COMMITS+set}" ]; 112 | then git log -n ${COMMITS} --pretty=format:"$datefmt | %H | %s" > $tmpfile; 113 | else git log -n 5 --pretty=format:"$datefmt | %H | %s" > $tmpfile; 114 | fi 115 | fi 116 | 117 | ${VISUAL:-${EDITOR:-${OUR_EDITOR}}} $tmpfile 118 | 119 | 120 | ITER=0 121 | COLITER=0 122 | declare -a COLLECTION 123 | 124 | COUNTCOMMITS=$(awk 'END {print NR}' $tmpfile) 125 | 126 | while read commit || [ -n "$commit" ]; do 127 | 128 | IFS="|" read date hash message <<< "$commit" 129 | shopt -s nocasematch 130 | if [[ "$date" == 'now' ]]; then 131 | date=$(date +%Y-%m-%dT%H:%M:%S%z); 132 | fi 133 | shopt -u nocasematch 134 | if [ "$datefmt" == "%cI" ] 135 | then 136 | DATE_NO_SPACE="$(echo "${date}" | tr -d '[[:space:]]')" 137 | else 138 | DATE_NO_SPACE="$(echo "${date}")" 139 | fi 140 | 141 | 142 | COMMIT_ENV=$(cat <<-END 143 | if [ \$GIT_COMMIT = $hash ]; 144 | then 145 | export GIT_AUTHOR_DATE="$DATE_NO_SPACE" 146 | export GIT_COMMITTER_DATE="$DATE_NO_SPACE"; 147 | fi; 148 | END 149 | ) 150 | 151 | ((ITER++)) 152 | 153 | if [ "${DEBUG}" -eq 1 ] && [ $((ITER % LIMITCHUNKS)) == $((LIMITCHUNKS - 1)) ]; 154 | then 155 | echo "Chunk $COLITER Finished" 156 | fi 157 | 158 | if [ $((ITER % LIMITCHUNKS)) == 0 ] 159 | then 160 | ((COLITER++)) 161 | 162 | if [ "${DEBUG}" -eq 1 ]; 163 | then 164 | echo "Chunk $COLITER Started" 165 | fi 166 | 167 | fi 168 | 169 | COLLECTION[$COLITER]=${COLLECTION[COLITER]}"$COMMIT_ENV" 170 | if [ "${DEBUG}" -eq 1 ] 171 | then 172 | echo "Commit $ITER/$COUNTCOMMITS Collected" 173 | fi 174 | 175 | done < $tmpfile 176 | 177 | ITERATOR=0 178 | for each in "${COLLECTION[@]}" 179 | do 180 | 181 | ((ITERATOR++)) 182 | 183 | if [ "${ALL}" -eq 1 ]; 184 | then 185 | if [ "${DEBUG}" -eq 1 ]; 186 | then 187 | echo "Chunk $ITERATOR/"${#COLLECTION[@]}" Started" 188 | git filter-branch -f --env-filter "$each" -- --all 189 | echo "Chunk $ITERATOR/"${#COLLECTION[@]}" Finished" 190 | else 191 | git filter-branch -f --env-filter "$each" -- --all >/dev/null 192 | fi 193 | else 194 | if [ "${DEBUG}" -eq 1 ]; 195 | then 196 | echo "Chunk $ITERATOR/"${#COLLECTION[@]}" Started" 197 | git filter-branch -f --env-filter "$each" HEAD~${COMMITS}..HEAD 198 | echo "Chunk $ITERATOR/"${#COLLECTION[@]}" Finished" 199 | else 200 | git filter-branch -f --env-filter "$each" HEAD~${COMMITS}..HEAD >/dev/null 201 | fi 202 | fi 203 | done 204 | 205 | if [ $? = 0 ] ; then 206 | echo "Git commit dates updated. Run 'git push -f BRANCH_NAME' to push your changes." 207 | else 208 | echo "Git redate failed. Please make sure you run this on a clean working directory." 209 | fi 210 | --------------------------------------------------------------------------------