3 ## applypatch takes four file arguments, and uses those to
4 ## apply the unpacked patch (surprise surprise) that they
5 ## represent to the current tree.
8 ## $1 - file with commit message
9 ## $2 - file with the actual patch
10 ## $3 - "info" file with Author, email and subject
11 ## $4 - optional file containing signoff to add
14 USAGE
='<msg> <patch> <info> [<signoff>]'
17 case "$#" in 3|
4) ;; *) usage
;; esac
19 final
=.dotest
/final-commit
21 ## If this file exists, we ask before applying
23 query_apply
=.dotest
/.query_apply
25 ## We do not munge the first line of the commit message too much
26 ## if this file exists.
27 keep_subject
=.dotest
/.keep_subject
29 ## We do not attempt the 3-way merge fallback unless this file exists.
30 fall_back_3way
=.dotest
/.3way
36 EDIT
=${VISUAL:-${EDITOR:-vi}}
38 export GIT_AUTHOR_NAME
="$(sed -n '/^Author/ s/Author: //p' "$INFO")"
39 export GIT_AUTHOR_EMAIL
="$(sed -n '/^Email/ s/Email: //p' "$INFO")"
40 export GIT_AUTHOR_DATE
="$(sed -n '/^Date/ s/Date: //p' "$INFO")"
41 export SUBJECT
="$(sed -n '/^Subject/ s/Subject: //p' "$INFO")"
43 if test '' != "$SIGNOFF"
47 SIGNOFF
=`cat "$SIGNOFF"` ||
exit
48 elif case "$SIGNOFF" in yes | true | me | please
) : ;; *) false
;; esac
50 SIGNOFF
=`git-var GIT_COMMITTER_IDENT | sed -e '
57 if test '' != "$SIGNOFF"
60 sed -ne '/^Signed-off-by: /p' "$MSGFILE" |
63 test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" ||
{
64 test '' = "$LAST_SIGNED_OFF_BY" && echo
71 test -f "$keep_subject" || patch_header
='[PATCH] '
74 echo "$patch_header$SUBJECT"
83 test -f "$query_apply" || interactive
=no
85 while [ "$interactive" = yes ]; do
86 echo "Commit Body is:"
87 echo "--------------------------"
89 echo "--------------------------"
90 printf "Apply? [y]es/[n]o/[e]dit/[a]ccept all "
94 n|N
) exit 2;; # special value to tell dotest to keep going
95 e|E
) "$EDIT" "$final";;
96 a|A
) rm -f "$query_apply"
101 if test -x "$GIT_DIR"/hooks
/applypatch-msg
103 "$GIT_DIR"/hooks
/applypatch-msg
"$final" ||
exit
107 echo Applying
"'$SUBJECT'"
110 git-apply
--index "$PATCHFILE" ||
{
112 # git-apply exits with status 1 when the patch does not apply,
113 # but it die()s with other failures, most notably upon corrupt
114 # patch. In the latter case, there is no point to try applying
115 # it to another tree and do 3-way merge.
116 test $?
= 1 ||
exit 1
118 test -f "$fall_back_3way" ||
exit 1
120 # Here if we know which revision the patch applies to,
121 # we create a temporary working tree and index, apply the
122 # patch, and attempt 3-way merge with the resulting tree.
124 O_OBJECT
=`cd "$GIT_OBJECT_DIRECTORY" && pwd`
125 rm -fr .patch-merge-
*
127 if git-apply
-z --index-info "$PATCHFILE" \
128 >.patch-merge-index-info
2>/dev
/null
&&
129 GIT_INDEX_FILE
=.patch-merge-tmp-index \
130 git-update-index
-z --index-info <.patch-merge-index-info
&&
131 GIT_INDEX_FILE
=.patch-merge-tmp-index \
132 git-write-tree
>.patch-merge-tmp-base
&&
134 mkdir .patch-merge-tmp-dir
&&
135 cd .patch-merge-tmp-dir
&&
136 GIT_INDEX_FILE
="../.patch-merge-tmp-index" \
137 GIT_OBJECT_DIRECTORY
="$O_OBJECT" \
138 git-apply
$binary --index
141 echo Using index info to reconstruct a base tree...
142 mv .patch-merge-tmp-base .patch-merge-base
143 mv .patch-merge-tmp-index .patch-merge-index
148 # Otherwise, try nearby trees that can be used to apply the
150 git-rev-list
--max-count=$N HEAD
152 # or hoping the patch is against known tags...
153 git-ls-remote
--tags .
157 # Try it if we have it as a tree.
158 git-cat-file tree
"$base" >/dev
/null
2>&1 ||
continue
160 rm -fr .patch-merge-tmp-
* &&
161 mkdir .patch-merge-tmp-dir ||
break
163 cd .patch-merge-tmp-dir
&&
164 GIT_INDEX_FILE
=..
/.patch-merge-tmp-index
&&
165 GIT_OBJECT_DIRECTORY
="$O_OBJECT" &&
166 export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY
&&
167 git-read-tree
"$base" &&
169 mv ..
/.patch-merge-tmp-index ..
/.patch-merge-index
&&
170 echo "$base" >..
/.patch-merge-base
171 ) <"$PATCHFILE" 2>/dev
/null
&& break
175 test -f .patch-merge-index
&&
176 his_tree
=$
(GIT_INDEX_FILE
=.patch-merge-index git-write-tree
) &&
177 orig_tree
=$
(cat .patch-merge-base
) &&
178 rm -fr .patch-merge-
* ||
exit 1
180 echo Falling back to patching base and
3-way merge using
$orig_tree...
182 # This is not so wrong. Depending on which base we picked,
183 # orig_tree may be wildly different from ours, but his_tree
184 # has the same set of wildly different changes in parts the
185 # patch did not touch, so resolve ends up canceling them,
186 # saying that we reverted all those changes.
188 if git-merge-resolve
$orig_tree -- HEAD
$his_tree
192 echo Failed to merge
in the changes.
197 if test -x "$GIT_DIR"/hooks
/pre-applypatch
199 "$GIT_DIR"/hooks
/pre-applypatch ||
exit
202 tree
=$
(git-write-tree
) ||
exit 1
203 echo Wrote tree
$tree
204 parent
=$
(git-rev-parse
--verify HEAD
) &&
205 commit
=$
(git-commit-tree
$tree -p $parent <"$final") ||
exit 1
206 echo Committed
: $commit
207 git-update-ref
-m "applypatch: $SUBJECT" HEAD
$commit $parent ||
exit
209 if test -x "$GIT_DIR"/hooks
/post-applypatch
211 "$GIT_DIR"/hooks
/post-applypatch