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
13 . git-sh-setup || die
"Not a git archive."
15 final
=.dotest
/final-commit
17 ## If this file exists, we ask before applying
19 query_apply
=.dotest
/.query_apply
21 ## We do not munge the first line of the commit message too much
22 ## if this file exists.
23 keep_subject
=.dotest
/.keep_subject
25 ## We do not attempt the 3-way merge fallback unless this file exists.
26 fall_back_3way
=.dotest
/.3way
32 EDIT
=${VISUAL:-${EDITOR:-vi}}
34 export GIT_AUTHOR_NAME
="$(sed -n '/^Author/ s/Author: //p' "$INFO")"
35 export GIT_AUTHOR_EMAIL
="$(sed -n '/^Email/ s/Email: //p' "$INFO")"
36 export GIT_AUTHOR_DATE
="$(sed -n '/^Date/ s/Date: //p' "$INFO")"
37 export SUBJECT
="$(sed -n '/^Subject/ s/Subject: //p' "$INFO")"
39 if test '' != "$SIGNOFF"
43 SIGNOFF
=`cat "$SIGNOFF"` ||
exit
44 elif case "$SIGNOFF" in yes | true | me | please
) : ;; *) false
;; esac
46 SIGNOFF
=`git-var GIT_COMMITTER_IDENT | sed -e '
53 if test '' != "$SIGNOFF"
56 sed -ne '/^Signed-off-by: /p' "$MSGFILE" |
59 test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" ||
{
60 test '' = "$LAST_SIGNED_OFF_BY" && echo
67 test -f "$keep_subject" || patch_header
='[PATCH] '
70 echo "$patch_header$SUBJECT"
79 test -f "$query_apply" || interactive
=no
81 while [ "$interactive" = yes ]; do
82 echo "Commit Body is:"
83 echo "--------------------------"
85 echo "--------------------------"
86 echo -n "Apply? [y]es/[n]o/[e]dit/[a]ccept all "
90 n|N
) exit 2;; # special value to tell dotest to keep going
91 e|E
) "$EDIT" "$final";;
92 a|A
) rm -f "$query_apply"
97 if test -x "$GIT_DIR"/hooks
/applypatch-msg
99 "$GIT_DIR"/hooks
/applypatch-msg
"$final" ||
exit
103 echo Applying
"'$SUBJECT'"
106 git-apply
--index "$PATCHFILE" ||
{
108 # git-apply exits with status 1 when the patch does not apply,
109 # but it die()s with other failures, most notably upon corrupt
110 # patch. In the latter case, there is no point to try applying
111 # it to another tree and do 3-way merge.
112 test $?
= 1 ||
exit 1
114 test -f "$fall_back_3way" ||
exit 1
116 # Here if we know which revision the patch applies to,
117 # we create a temporary working tree and index, apply the
118 # patch, and attempt 3-way merge with the resulting tree.
120 O_OBJECT
=`cd "$GIT_OBJECT_DIRECTORY" && pwd`
121 rm -fr .patch-merge-
*
126 # if the patch records the base tree...
129 /^applies-to: \([0-9a-f]*\)$/{
135 # or hoping the patch is against our recent commits...
136 git-rev-list
--max-count=$N HEAD
138 # or hoping the patch is against known tags...
139 git-ls-remote
--tags .
143 # Try it if we have it as a tree.
144 git-cat-file tree
"$base" >/dev
/null
2>&1 ||
continue
146 rm -fr .patch-merge-tmp-
* &&
147 mkdir .patch-merge-tmp-dir ||
break
149 cd .patch-merge-tmp-dir
&&
150 GIT_INDEX_FILE
=..
/.patch-merge-tmp-index
&&
151 GIT_OBJECT_DIRECTORY
="$O_OBJECT" &&
152 export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY
&&
153 git-read-tree
"$base" &&
155 mv ..
/.patch-merge-tmp-index ..
/.patch-merge-index
&&
156 echo "$base" >..
/.patch-merge-base
157 ) <"$PATCHFILE" 2>/dev
/null
&& break
160 test -f .patch-merge-index
&&
161 his_tree
=$
(GIT_INDEX_FILE
=.patch-merge-index git-write-tree
) &&
162 orig_tree
=$
(cat .patch-merge-base
) &&
163 rm -fr .patch-merge-
* ||
exit 1
165 echo Falling back to patching base and
3-way merge using
$orig_tree...
167 # This is not so wrong. Depending on which base we picked,
168 # orig_tree may be wildly different from ours, but his_tree
169 # has the same set of wildly different changes in parts the
170 # patch did not touch, so resolve ends up cancelling them,
171 # saying that we reverted all those changes.
173 if git-merge-resolve
$orig_tree -- HEAD
$his_tree
177 echo Failed to merge
in the changes.
182 if test -x "$GIT_DIR"/hooks
/pre-applypatch
184 "$GIT_DIR"/hooks
/pre-applypatch ||
exit
187 tree
=$
(git-write-tree
) ||
exit 1
188 echo Wrote tree
$tree
189 parent
=$
(git-rev-parse
--verify HEAD
) &&
190 commit
=$
(git-commit-tree
$tree -p $parent <"$final") ||
exit 1
191 echo Committed
: $commit
192 git-update-ref HEAD
$commit $parent ||
exit
194 if test -x "$GIT_DIR"/hooks
/post-applypatch
196 "$GIT_DIR"/hooks
/post-applypatch