summaryrefslogtreecommitdiff
path: root/tools/git-applypatch
blob: e5bc3c0a77bad0559a1717d3a090d7b3c5b06784 (plain)
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
#!/bin/sh
##
## applypatch takes four file arguments, and uses those to
## apply the unpacked patch (surprise surprise) that they
## represent to the current tree.
##
## The arguments are:
##	$1 - file with commit message
##	$2 - file with the actual patch
##	$3 - "info" file with Author, email and subject
##	$4 - optional file containing signoff to add
##
. git-sh-setup-script || die "Not a git archive."

final=.dotest/final-commit
##
## If this file exists, we ask before applying
##
query_apply=.dotest/.query_apply

## We do not munge the first line of the commit message too much
## if this file exists.
keep_subject=.dotest/.keep_subject


MSGFILE=$1
PATCHFILE=$2
INFO=$3
SIGNOFF=$4
EDIT=${VISUAL:-${EDITOR:-vi}}

export GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' .dotest/info)"
export GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' .dotest/info)"
export GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' .dotest/info)"
export SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' .dotest/info)"

if test '' != "$SIGNOFF"
then
	if test -f "$SIGNOFF"
	then
		SIGNOFF=`cat "$SIGNOFF"` || exit
	elif case "$SIGNOFF" in yes | true | me | please) : ;; *) false ;; esac
	then
		SIGNOFF=`git-var GIT_COMMITTER_IDENT | sed -e '
				s/>.*/>/
				s/^/Signed-off-by: /'
		`
	else
		SIGNOFF=
	fi
	if test '' != "$SIGNOFF"
	then
		LAST_SIGNED_OFF_BY=`
			sed -ne '/^Signed-off-by: /p' "$MSGFILE" |
			tail -n 1
		`
		test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" ||
		echo "$SIGNOFF" >>"$MSGFILE"
	fi
fi

patch_header=
test -f "$keep_subject" || patch_header='[PATCH] '

{
	echo "$patch_header$SUBJECT"
	if test -s "$MSGFILE"
	then
		echo
		cat "$MSGFILE"
	fi
} >"$final"

interactive=yes
test -f "$query_apply" || interactive=no

while [ "$interactive" = yes ]; do
	echo "Commit Body is:"
	echo "--------------------------"
	cat "$final"
	echo "--------------------------"
	echo -n "Apply? [y]es/[n]o/[e]dit/[a]ccept all "
	read reply
	case "$reply" in
		y|Y) interactive=no;;
		n|N) exit 2;;	# special value to tell dotest to keep going
		e|E) "$EDIT" "$final";;
		a|A) rm -f "$query_apply"
		     interactive=no ;;
	esac
done

if test -x "$GIT_DIR"/hooks/applypatch-msg
then
	"$GIT_DIR"/hooks/applypatch-msg "$final" || exit
fi

echo
echo Applying "'$SUBJECT'"
echo

git-apply --index "$PATCHFILE" || exit 1

if test -x "$GIT_DIR"/hooks/pre-applypatch
then
	"$GIT_DIR"/hooks/pre-applypatch || exit
fi

tree=$(git-write-tree) || exit 1
echo Wrote tree $tree
commit=$(git-commit-tree $tree -p $(cat "$GIT_DIR"/HEAD) < "$final") || exit 1
echo Committed: $commit
echo $commit > "$GIT_DIR"/HEAD

if test -x "$GIT_DIR"/hooks/post-applypatch
then
	"$GIT_DIR"/hooks/post-applypatch
fi