-
Notifications
You must be signed in to change notification settings - Fork 134
/
Copy pathgit-patch.sh
executable file
·254 lines (207 loc) · 9.56 KB
/
git-patch.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#!/bin/bash
# git-patch.sh from https://github.com/wilsonmar/git-utilities
# This creates a patch file from one repository and adds it to another repository.
# Note: Creating a patch provides a log of exactly what is inserted into the target repo.
# customized based on specification in file secrets.sh within the same repo.
# TODO: https://wilsonmar.github.io/git-patch.md
# sh -c "$(curl -fsSL https://raw.githubusercontent.com/wilsonmar/git-utilities/master/git-patch.sh)"
# 1. Define variables containing the origin's repos. For example:
REPO_FROM_CONTAINER="$HOME/temp/hotwilson"
REPO_TO_CONTAINER="$HOME/temp/hotwilson"
GIT_HOST_FROM="https://github.com" # git@github.com: for SSH
GIT_HOST_TO="https://github.com" # git@github.com: for SSH
REPO_FROM_ACCOUNT="wilsonmar"
REPO_TO_ACCOUNT="github-candidate"
REPO_NAME_FROM="devops-cert-activity-wilsonmar2"
REPO_NAME_TO="devops-cert-activity-wilsonmar"
SHA_TO="6e6d819" # least recent 6e6d819
SHA_FROM="b0de12f" # most recent
PATCH_FILE="0new-feature.patch"
NEW_BRANCH_NAME="add from patch"
# Feature flags:
RELOAD_GITHUB_FROM="1" # 1=YES (remove folder from previous run), 0=No
RELOAD_GITHUB_TO="1" # 1=YES, 0=No
PAUSE_FOR_SHA="0" # 1=YES, 0=No ()
REMOVE_REPO_FROM_WHEN_DONE="0" # 0=No (default), "1"=Yes
REMOVE_REPO_TO_WHEN_DONE="0" # 0=No (default), "1"=Yes
# 2. Define utility functions:
function echo_f() { # echo fancy comment
local fmt="$1"; shift
printf "\\n >>> $fmt\\n" "$@"
}
function echo_c() { # echo command
local fmt="$1"; shift
printf " $fmt\\n" "$@"
}
#4 Collect starting system information and display on console:
TIME_START="$(date -u +%s)"
#FREE_DISKBLOCKS_END=$(df | sed -n -e '2{p;q}' | cut -d' ' -f 6) # no longer works
FREE_DISKBLOCKS_START="$(df -P | awk '{print $4}' | sed -n 2p)" # e.g. 342771200 from:
# Filesystem 512-blocks Used Available Capacity Mounted on
# /dev/disk1s1 976490568 611335160 342771200 65% /
LOG_PREFIX=$(date +%Y-%m-%dT%H:%M:%S%z)-$((1 + RANDOM % 1000))
# ISO-8601 date plus RANDOM=$((1 + RANDOM % 1000)) # 3 digit random number.
# LOGFILE="$0.$LOG_PREFIX.log"
echo_f "STARTING $0 from within $PWD ##################################"
echo_c "at $LOG_PREFIX with $FREE_DISKBLOCKS_START blocks free ..."
# 3. Navigate to the origin's repo. For example:
if [ ! -d "$REPO_FROM_CONTAINER" ]; then
echo_f "Directory $REPO_FROM_CONTAINER not found. Making it ..."
cd ~
mkdir "$REPO_FROM_CONTAINER"
cd "$REPO_FROM_CONTAINER"
else
echo_f "Navigating from PWD=$PWD to $REPO_FROM_CONTAINER"
cd ~
cd "$REPO_FROM_CONTAINER"
fi
if [ ! -d "$REPO_FROM_CONTAINER" ]; then
echo_f "Error creating directory at PWD=$REPO_FROM_CONTAINER."
exit
else
echo_c "Directories now:"
ls -d */
fi
# 4. Delete the folder for download again?
echo_f "REPO_NAME_FROM=$REPO_NAME_FROM"
if [ $RELOAD_GITHUB_FROM -eq "1" ]; then # 1=YES, 0=No
rm -rf "$REPO_NAME_FROM" # remove ...
echo_f "Cloning $GIT_HOST_FROM/$REPO_FROM_ACCOUNT/$REPO_NAME_FROM ..."
git clone "$GIT_HOST_FROM/$REPO_FROM_ACCOUNT/$REPO_NAME_FROM"
ls -l | egrep '^d' # list only folders using regular expression
fi
cd "$REPO_NAME_FROM"
URL_FROM="$PWD"
echo_f "Now at PWD=$URL_FROM"
# 5. Pause or go to identify SHAs:
if [ $PAUSE_FOR_SHA -eq "1" ]; then # 1=YES, 0=No
# By default, pause and list SHA's.
git log --oneline
exit # to edit this script with SHA values.
else
echo_f "SHA_FROM=\"$SHA_FROM\" - SHA_TO=\"$SHA_TO\" "
git log --oneline
fi
# 6. Create patch message file(s):
echo_f "Creating git patch message file $PATCH_FILE ..."
git format-patch "$SHA_FROM^..$SHA_TO" --stdout > "$PATCH_FILE"
# See https://git-scm.com/docs/git-format-patch
# NOTE: --stdout > 0new-feature.patch creates a single file from several patch files output.
# See https://thoughtbot.com/blog/send-a-patch-to-someone-using-git-format-patch
#git format-patch -1 # for just the lastest commit. See https://thoughtbot.com/blog/send-a-patch-to-someone-using-git-format-patch
# -1 for a single commit SHA or
# "$SHA_FROM^..$SHA_TO" for a range of commits.
# 0001-<commit msg>.patch
if [ ! -f "$PATCH_FILE" ]; then
echo_f "File $PATCH_FILE not found. Aborting!"
exit
else
ls -al *.patch
fi
# 7. Navigate to the target repo:
cd ..
echo_f "REPO_TO at $PWD/$REPO_NAME_TO"
if [ $RELOAD_GITHUB_TO -eq "1" ]; then # 1=YES, 0=No
rm -rf "$REPO_NAME_TO" # remove ...
echo_f "Cloning $GIT_HOST_TO/$REPO_TO_ACCOUNT/$REPO_NAME_TO ..."
git clone "$GIT_HOST_TO/$REPO_TO_ACCOUNT/$REPO_NAME_TO"
echo_f "Directories within $REPO_TO_CONTAINER :"
ls -l | egrep '^d' # list only folders using regular expression
fi
cd "$REPO_NAME_TO"
echo_f "Now at PWD=$PWD"
# 8. Verify .git/hooks actions listening:
# See https://wilsonmar.github.io/git-hooks
# applypatch-msg, pre-applypatch, and post-applypatch.
if [ -f ".git/hooks/applypatch-msg" ]; then
echo_f "Beware .git/hooks/applypatch-msg specifies:"
cat .git/hooks/applypatch-msg
fi
if [ -f ".git/hooks/pre-applypath" ]; then
echo_f "Beware .git/hooks/pre-applypath specifies:"
cat .git/hooks/pre-applypath
fi
if [ -f ".git/hooks/post-applypatch" ]; then
echo_f "Beware .git/hooks/post-applypatch specifies:"
cat .git/hooks/post-applypatch
fi
# 9. Create a branch:
# if NEW_BRANCH_NAME is not blank:
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
echo_f "At branch $CURRENT_BRANCH to create branch $NEW_BRANCH_NAME:"
git checkout -b "$NEW_BRANCH_NAME"
git branch # list branches
# 10. Apply patch:
# TODO: Move patch files to TO repo folder?
echo_f "Using git am to apply patch file $URL_FROM/$PATCH_FILE"
ls -l $URL_FROM/$PATCH_FILE # not 0*.patch
# See https://git-scm.com/docs/git-am/2.0.0 for options:
# git am $URL_FROM/0*.patch # doesn't read all files and issues errors.
# -3 means trying the three-way merge if the patch fails to apply cleanly
cat "$URL_FROM/$PATCH_FILE" | git am --ignore-space-change --ignore-whitespace
if [ $? -eq 0 ]; then
echo_f "No error in $? status returned."
else
echo_f "Error $? from statement. git am --abort --show-current-patch ..."
git am --abort
# git am --show-current-patch
fi
echo_f "Git log of new SHAs in $REPO_NAME_TO after messages applied:"
git log --oneline
# Note: the SHA of the patch that you merge with git am will not be the same SHA.
# However, the commit message text will be intact.
# 11. TODO: Create pull request in GitHub
# Using hub: https://www.skcript.com/svr/cli-pr-pull-request-command-line-github/
# Using GitHub API: See https://gist.github.com/devongovett/10399980
# Using GitHub API: See https://github.com/wjmelements/scripts#cpr
# See https://www.skcript.com/svr/cli-pr-pull-request-command-line-github/
# Check to see if hub is installed:
# https://andrewlock.net/creating-github-pull-requests-from-the-command-line-with-hub/
# 12. Remove folders
if [ "$REMOVE_REPO_FROM_WHEN_DONE" -eq "1" ]; then # 0=No (default), "1"=Yes
echo_f "Removing $URL_FROM/$PATCH_FILE as REMOVE_REPO_FROM_WHEN_DONE=$REMOVE_REPO_FROM_WHEN_DONE"
rm -rf "$REPO_TO_CONTAINER/$REPO_NAME_FROM"
if [ -d "$REPO_FROM_CONTAINER/$REPO_NAME_FROM" ]; then
FOLDER_DISK_SPACE="$(du -hs | tr -d '\040\011\012\015\056')"
echo_f "WARNING: $FOLDER_DISK_SPACE folder still at $REPO_FROM_CONTAINER/$REPO_NAME_FROM."
ls -al
fi
else
if [ -d "$REPO_FROM_CONTAINER/$REPO_NAME_FROM" ]; then
FOLDER_DISK_SPACE="$(du -hs | tr -d '\040\011\012\015\056')"
echo_f "WARNING: $FOLDER_DISK_SPACE folder remains at $REPO_FROM_CONTAINER/$REPO_NAME_FROM."
else
echo_f "Folder no longer at $REPO_FROM_CONTAINER/$REPO_NAME_FROM."
fi
fi
if [ "$REMOVE_REPO_TO_WHEN_DONE" -eq "1" ]; then # 0=No (default), "1"=Yes
echo_f "Removing $REPO_TO_CONTAINER/$REPO_NAME_TO as REMOVE_REPO_TO_WHEN_DONE=$REMOVE_REPO_TO_WHEN_DONE"
rm -rf "$REPO_TO_CONTAINER/$REPO_NAME_TO"
if [ -d "$REPO_TO_CONTAINER/$REPO_NAME_TO" ]; then
FOLDER_DISK_SPACE="$(du -hs | tr -d '\040\011\012\015\056')"
echo_f "WARNING: $FOLDER_DISK_SPACE folder still at $REPO_TO_CONTAINER/$REPO_NAME_TO."
ls -al
fi
else
if [ -d "$REPO_TO_CONTAINER/$REPO_NAME_TO" ]; then
FOLDER_DISK_SPACE="$(du -hs | tr -d '\040\011\012\015\056')"
echo_f "WARNING: $FOLDER_DISK_SPACE folder remains at $REPO_TO_CONTAINER/$REPO_NAME_TO."
else
echo_f "Folder no longer at $REPO_TO_CONTAINER/$REPO_NAME_TO."
fi
fi
### References
# https://stackoverflow.com/questions/3816040/git-apply-changes-introduced-by-commit-in-one-repo-to-another-repo/3816292#3816292
# https://stackoverflow.com/questions/5120038/is-it-possible-to-cherry-pick-a-commit-from-another-git-repository/9507417#9507417
#########
#18 Calculate and display end of run statistics:
FREE_DISKBLOCKS_END="$(df -P | awk '{print $4}' | sed -n 2p)"
DIFF=$(((FREE_DISKBLOCKS_START-FREE_DISKBLOCKS_END)/2048))
# 380691344 / 182G = 2091710.681318681318681 blocks per GB
# 182*1024=186368 MB
# 380691344 / 186368 G = 2042 blocks per MB
TIME_END=$(date -u +%s);
DIFF=$((TIME_END-TIME_START))
MSG="End of script after $((DIFF/60))m $((DIFF%60))s elapsed"
echo_f "$MSG and $DIFF MB disk space consumed."
#say "script ended." # through speaker