зеркало из https://github.com/microsoft/git.git
Merge branches 'lh/submodules' and 'pb/am'
* lh/submodules: Add basic test-script for git-submodule Add git-submodule command * pb/am: Remove git-applypatch git-applymbox: Remove command
This commit is contained in:
Коммит
1a8b76912e
|
@ -7,8 +7,6 @@ git-add--interactive
|
|||
git-am
|
||||
git-annotate
|
||||
git-apply
|
||||
git-applymbox
|
||||
git-applypatch
|
||||
git-archimport
|
||||
git-archive
|
||||
git-bisect
|
||||
|
@ -126,6 +124,7 @@ git-ssh-push
|
|||
git-ssh-upload
|
||||
git-status
|
||||
git-stripspace
|
||||
git-submodule
|
||||
git-svn
|
||||
git-svnimport
|
||||
git-symbolic-ref
|
||||
|
|
|
@ -239,7 +239,7 @@ One test you could do yourself if your MUA is set up correctly is:
|
|||
$ git fetch http://kernel.org/pub/scm/git/git.git master:test-apply
|
||||
$ git checkout test-apply
|
||||
$ git reset --hard
|
||||
$ git applymbox a.patch
|
||||
$ git am a.patch
|
||||
|
||||
If it does not apply correctly, there can be various reasons.
|
||||
|
||||
|
@ -247,7 +247,7 @@ If it does not apply correctly, there can be various reasons.
|
|||
does not have much to do with your MUA. Please rebase the
|
||||
patch appropriately.
|
||||
|
||||
* Your MUA corrupted your patch; applymbox would complain that
|
||||
* Your MUA corrupted your patch; "am" would complain that
|
||||
the patch does not apply. Look at .dotest/ subdirectory and
|
||||
see what 'patch' file contains and check for the common
|
||||
corruption patterns mentioned above.
|
||||
|
|
|
@ -72,8 +72,6 @@ __DATA__
|
|||
git-add mainporcelain
|
||||
git-am mainporcelain
|
||||
git-annotate ancillaryinterrogators
|
||||
git-applymbox ancillaryinterrogators
|
||||
git-applypatch purehelpers
|
||||
git-apply plumbingmanipulators
|
||||
git-archimport foreignscminterface
|
||||
git-archive mainporcelain
|
||||
|
@ -180,6 +178,7 @@ git-ssh-fetch synchingrepositories
|
|||
git-ssh-upload synchingrepositories
|
||||
git-status mainporcelain
|
||||
git-stripspace purehelpers
|
||||
git-submodule mainporcelain
|
||||
git-svn foreignscminterface
|
||||
git-svnimport foreignscminterface
|
||||
git-symbolic-ref plumbingmanipulators
|
||||
|
|
|
@ -127,8 +127,7 @@ is terminated before the first occurrence of such a line.
|
|||
|
||||
When initially invoking it, you give it names of the mailboxes
|
||||
to crunch. Upon seeing the first patch that does not apply, it
|
||||
aborts in the middle, just like 'git-applymbox' does. You can
|
||||
recover from this in one of two ways:
|
||||
aborts in the middle,. You can recover from this in one of two ways:
|
||||
|
||||
. skip the current patch by re-running the command with '--skip'
|
||||
option.
|
||||
|
@ -145,7 +144,7 @@ names.
|
|||
|
||||
SEE ALSO
|
||||
--------
|
||||
gitlink:git-applymbox[1], gitlink:git-applypatch[1], gitlink:git-apply[1].
|
||||
gitlink:git-apply[1].
|
||||
|
||||
|
||||
Author
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
git-applymbox(1)
|
||||
================
|
||||
|
||||
NAME
|
||||
----
|
||||
git-applymbox - Apply a series of patches in a mailbox
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-applymbox' [-u] [-k] [-q] [-m] ( -c .dotest/<num> | <mbox> ) [ <signoff> ]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Splits mail messages in a mailbox into commit log message,
|
||||
authorship information and patches, and applies them to the
|
||||
current branch.
|
||||
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
-q::
|
||||
Apply patches interactively. The user will be given
|
||||
opportunity to edit the log message and the patch before
|
||||
attempting to apply it.
|
||||
|
||||
-k::
|
||||
Usually the program 'cleans up' the Subject: header line
|
||||
to extract the title line for the commit log message,
|
||||
among which (1) remove 'Re:' or 're:', (2) leading
|
||||
whitespaces, (3) '[' up to ']', typically '[PATCH]', and
|
||||
then prepends "[PATCH] ". This flag forbids this
|
||||
munging, and is most useful when used to read back 'git
|
||||
format-patch -k' output.
|
||||
|
||||
-m::
|
||||
Patches are applied with `git-apply` command, and unless
|
||||
it cleanly applies without fuzz, the processing fails.
|
||||
With this flag, if a tree that the patch applies cleanly
|
||||
is found in a repository, the patch is applied to the
|
||||
tree and then a 3-way merge between the resulting tree
|
||||
and the current tree.
|
||||
|
||||
-u::
|
||||
Pass `-u` flag to `git-mailinfo` (see gitlink:git-mailinfo[1]).
|
||||
The proposed commit log message taken from the e-mail
|
||||
are re-coded into UTF-8 encoding (configuration variable
|
||||
`i18n.commitencoding` can be used to specify project's
|
||||
preferred encoding if it is not UTF-8). This used to be
|
||||
optional but now it is the default.
|
||||
+
|
||||
Note that the patch is always used as-is without charset
|
||||
conversion, even with this flag.
|
||||
|
||||
-n::
|
||||
Pass `-n` flag to `git-mailinfo` (see
|
||||
gitlink:git-mailinfo[1]).
|
||||
|
||||
-c .dotest/<num>::
|
||||
When the patch contained in an e-mail does not cleanly
|
||||
apply, the command exits with an error message. The
|
||||
patch and extracted message are found in .dotest/, and
|
||||
you could re-run 'git applymbox' with '-c .dotest/<num>'
|
||||
flag to restart the process after inspecting and fixing
|
||||
them.
|
||||
|
||||
<mbox>::
|
||||
The name of the file that contains the e-mail messages
|
||||
with patches. This file should be in the UNIX mailbox
|
||||
format. See 'SubmittingPatches' document to learn about
|
||||
the formatting convention for e-mail submission.
|
||||
|
||||
<signoff>::
|
||||
The name of the file that contains your "Signed-off-by"
|
||||
line. See 'SubmittingPatches' document to learn what
|
||||
"Signed-off-by" line means. You can also just say
|
||||
'yes', 'true', 'me', or 'please' to use an automatically
|
||||
generated "Signed-off-by" line based on your committer
|
||||
identity.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
gitlink:git-am[1], gitlink:git-applypatch[1].
|
||||
|
||||
|
||||
Author
|
||||
------
|
||||
Written by Linus Torvalds <torvalds@osdl.org>
|
||||
|
||||
Documentation
|
||||
--------------
|
||||
Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the gitlink:git[7] suite
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
git-applypatch(1)
|
||||
=================
|
||||
|
||||
NAME
|
||||
----
|
||||
git-applypatch - Apply one patch extracted from an e-mail
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-applypatch' <msg> <patch> <info> [<signoff>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
This is usually not what an end user wants to run directly. See
|
||||
gitlink:git-am[1] instead.
|
||||
|
||||
Takes three files <msg>, <patch>, and <info> prepared from an
|
||||
e-mail message by 'git-mailinfo', and creates a commit. It is
|
||||
usually not necessary to use this command directly.
|
||||
|
||||
This command can run `applypatch-msg`, `pre-applypatch`, and
|
||||
`post-applypatch` hooks. See link:hooks.html[hooks] for more
|
||||
information.
|
||||
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
<msg>::
|
||||
Commit log message (sans the first line, which comes
|
||||
from e-mail Subject stored in <info>).
|
||||
|
||||
<patch>::
|
||||
The patch to apply.
|
||||
|
||||
<info>::
|
||||
Author and subject information extracted from e-mail,
|
||||
used on "author" line and as the first line of the
|
||||
commit log message.
|
||||
|
||||
|
||||
Author
|
||||
------
|
||||
Written by Linus Torvalds <torvalds@osdl.org>
|
||||
|
||||
Documentation
|
||||
--------------
|
||||
Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the gitlink:git[7] suite
|
||||
|
|
@ -16,7 +16,7 @@ DESCRIPTION
|
|||
Reading a single e-mail message from the standard input, and
|
||||
writes the commit log message in <msg> file, and the patches in
|
||||
<patch> file. The author name, e-mail and e-mail subject are
|
||||
written out to the standard output to be used by git-applypatch
|
||||
written out to the standard output to be used by git-am
|
||||
to create a commit. It is usually not necessary to use this
|
||||
command directly. See gitlink:git-am[1] instead.
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
git-submodule(1)
|
||||
================
|
||||
|
||||
NAME
|
||||
----
|
||||
git-submodule - Initialize, update or inspect submodules
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-submodule' [--quiet] [--cached] [status|init|update] [--] [<path>...]
|
||||
|
||||
|
||||
COMMANDS
|
||||
--------
|
||||
status::
|
||||
Show the status of the submodules. This will print the SHA-1 of the
|
||||
currently checked out commit for each submodule, along with the
|
||||
submodule path and the output of gitlink:git-describe[1] for the
|
||||
SHA-1. Each SHA-1 will be prefixed with `-` if the submodule is not
|
||||
initialized and `+` if the currently checked out submodule commit
|
||||
does not match the SHA-1 found in the index of the containing
|
||||
repository. This command is the default command for git-submodule.
|
||||
|
||||
init::
|
||||
Initialize the submodules, i.e. clone the git repositories specified
|
||||
in the .gitmodules file and checkout the submodule commits specified
|
||||
in the index of the containing repository. This will make the
|
||||
submodules HEAD be detached.
|
||||
|
||||
update::
|
||||
Update the initialized submodules, i.e. checkout the submodule commits
|
||||
specified in the index of the containing repository. This will make
|
||||
the submodules HEAD be detached.
|
||||
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
-q, --quiet::
|
||||
Only print error messages.
|
||||
|
||||
--cached::
|
||||
Display the SHA-1 stored in the index, not the SHA-1 of the currently
|
||||
checked out submodule commit. This option is only valid for the
|
||||
status command.
|
||||
|
||||
<path>::
|
||||
Path to submodule(s). When specified this will restrict the command
|
||||
to only operate on the submodules found at the specified paths.
|
||||
|
||||
FILES
|
||||
-----
|
||||
When cloning submodules, a .gitmodules file in the top-level directory
|
||||
of the containing repository is used to find the url of each submodule.
|
||||
This file should be formatted in the same way as $GIR_DIR/config. The key
|
||||
to each submodule url is "module.$path.url".
|
||||
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
Written by Lars Hjemli <hjemli@gmail.com>
|
||||
|
||||
GIT
|
||||
---
|
||||
Part of the gitlink:git[7] suite
|
|
@ -12,11 +12,10 @@ This document describes the currently defined hooks.
|
|||
applypatch-msg
|
||||
--------------
|
||||
|
||||
This hook is invoked by `git-applypatch` script, which is
|
||||
typically invoked by `git-applymbox`. It takes a single
|
||||
This hook is invoked by `git-am` script. It takes a single
|
||||
parameter, the name of the file that holds the proposed commit
|
||||
log message. Exiting with non-zero status causes
|
||||
`git-applypatch` to abort before applying the patch.
|
||||
`git-am` to abort before applying the patch.
|
||||
|
||||
The hook is allowed to edit the message file in place, and can
|
||||
be used to normalize the message into some project standard
|
||||
|
@ -29,8 +28,7 @@ The default 'applypatch-msg' hook, when enabled, runs the
|
|||
pre-applypatch
|
||||
--------------
|
||||
|
||||
This hook is invoked by `git-applypatch` script, which is
|
||||
typically invoked by `git-applymbox`. It takes no parameter,
|
||||
This hook is invoked by `git-am`. It takes no parameter,
|
||||
and is invoked after the patch is applied, but before a commit
|
||||
is made. Exiting with non-zero status causes the working tree
|
||||
after application of the patch not committed.
|
||||
|
@ -44,12 +42,11 @@ The default 'pre-applypatch' hook, when enabled, runs the
|
|||
post-applypatch
|
||||
---------------
|
||||
|
||||
This hook is invoked by `git-applypatch` script, which is
|
||||
typically invoked by `git-applymbox`. It takes no parameter,
|
||||
This hook is invoked by `git-am`. It takes no parameter,
|
||||
and is invoked after the patch is applied and a commit is made.
|
||||
|
||||
This hook is meant primarily for notification, and cannot affect
|
||||
the outcome of `git-applypatch`.
|
||||
the outcome of `git-am`.
|
||||
|
||||
pre-commit
|
||||
----------
|
||||
|
|
4
Makefile
4
Makefile
|
@ -206,10 +206,10 @@ SCRIPT_SH = \
|
|||
git-repack.sh git-request-pull.sh git-reset.sh \
|
||||
git-sh-setup.sh \
|
||||
git-tag.sh git-verify-tag.sh \
|
||||
git-applymbox.sh git-applypatch.sh git-am.sh \
|
||||
git-am.sh \
|
||||
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
|
||||
git-merge-resolve.sh git-merge-ours.sh \
|
||||
git-lost-found.sh git-quiltimport.sh
|
||||
git-lost-found.sh git-quiltimport.sh git-submodule.sh
|
||||
|
||||
SCRIPT_PERL = \
|
||||
git-add--interactive.perl \
|
||||
|
|
121
git-applymbox.sh
121
git-applymbox.sh
|
@ -1,121 +0,0 @@
|
|||
#!/bin/sh
|
||||
##
|
||||
## "dotest" is my stupid name for my patch-application script, which
|
||||
## I never got around to renaming after I tested it. We're now on the
|
||||
## second generation of scripts, still called "dotest".
|
||||
##
|
||||
## Update: Ryan Anderson finally shamed me into naming this "applymbox".
|
||||
##
|
||||
## You give it a mbox-format collection of emails, and it will try to
|
||||
## apply them to the kernel using "applypatch"
|
||||
##
|
||||
## The patch application may fail in the middle. In which case:
|
||||
## (1) look at .dotest/patch and fix it up to apply
|
||||
## (2) re-run applymbox with -c .dotest/msg-number for the current one.
|
||||
## Pay a special attention to the commit log message if you do this and
|
||||
## use a Signoff_file, because applypatch wants to append the sign-off
|
||||
## message to msg-clean every time it is run.
|
||||
##
|
||||
## git-am is supposed to be the newer and better tool for this job.
|
||||
|
||||
USAGE='[-u] [-k] [-q] [-m] (-c .dotest/<num> | mbox) [signoff]'
|
||||
. git-sh-setup
|
||||
|
||||
git var GIT_COMMITTER_IDENT >/dev/null || exit
|
||||
|
||||
keep_subject= query_apply= continue= utf8=-u resume=t
|
||||
while case "$#" in 0) break ;; esac
|
||||
do
|
||||
case "$1" in
|
||||
-u) utf8=-u ;;
|
||||
-n) utf8=-n ;;
|
||||
-k) keep_subject=-k ;;
|
||||
-q) query_apply=t ;;
|
||||
-c) continue="$2"; resume=f; shift ;;
|
||||
-m) fall_back_3way=t ;;
|
||||
-*) usage ;;
|
||||
*) break ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
case "$continue" in
|
||||
'')
|
||||
rm -rf .dotest
|
||||
mkdir .dotest
|
||||
num_msgs=$(git-mailsplit "$1" .dotest) || exit 1
|
||||
echo "$num_msgs patch(es) to process."
|
||||
shift
|
||||
esac
|
||||
|
||||
files=$(git-diff-index --cached --name-only HEAD) || exit
|
||||
if [ "$files" ]; then
|
||||
echo "Dirty index: cannot apply patches (dirty: $files)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$query_apply" in
|
||||
t) touch .dotest/.query_apply
|
||||
esac
|
||||
case "$fall_back_3way" in
|
||||
t) : >.dotest/.3way
|
||||
esac
|
||||
case "$keep_subject" in
|
||||
-k) : >.dotest/.keep_subject
|
||||
esac
|
||||
|
||||
signoff="$1"
|
||||
set x .dotest/0*
|
||||
shift
|
||||
while case "$#" in 0) break;; esac
|
||||
do
|
||||
i="$1"
|
||||
case "$resume,$continue" in
|
||||
f,$i) resume=t;;
|
||||
f,*) shift
|
||||
continue;;
|
||||
*)
|
||||
git-mailinfo $keep_subject $utf8 \
|
||||
.dotest/msg .dotest/patch <$i >.dotest/info || exit 1
|
||||
test -s .dotest/patch || {
|
||||
echo "Patch is empty. Was it split wrong?"
|
||||
exit 1
|
||||
}
|
||||
git-stripspace < .dotest/msg > .dotest/msg-clean
|
||||
;;
|
||||
esac
|
||||
while :; # for fixing up and retry
|
||||
do
|
||||
git-applypatch .dotest/msg-clean .dotest/patch .dotest/info "$signoff"
|
||||
case "$?" in
|
||||
0)
|
||||
# Remove the cleanly applied one to reduce clutter.
|
||||
rm -f .dotest/$i
|
||||
;;
|
||||
2)
|
||||
# 2 is a special exit code from applypatch to indicate that
|
||||
# the patch wasn't applied, but continue anyway
|
||||
;;
|
||||
*)
|
||||
ret=$?
|
||||
if test -f .dotest/.query_apply
|
||||
then
|
||||
echo >&2 "* Patch failed."
|
||||
echo >&2 "* You could fix it up in your editor and"
|
||||
echo >&2 " retry. If you want to do so, say yes here"
|
||||
echo >&2 " AFTER fixing .dotest/patch up."
|
||||
echo >&2 -n "Retry [y/N]? "
|
||||
read yesno
|
||||
case "$yesno" in
|
||||
[Yy]*)
|
||||
continue ;;
|
||||
esac
|
||||
fi
|
||||
exit $ret
|
||||
esac
|
||||
break
|
||||
done
|
||||
shift
|
||||
done
|
||||
# return to pristine
|
||||
rm -fr .dotest
|
|
@ -1,212 +0,0 @@
|
|||
#!/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
|
||||
##
|
||||
|
||||
USAGE='<msg> <patch> <info> [<signoff>]'
|
||||
. git-sh-setup
|
||||
|
||||
case "$#" in 3|4) ;; *) usage ;; esac
|
||||
|
||||
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
|
||||
|
||||
## We do not attempt the 3-way merge fallback unless this file exists.
|
||||
fall_back_3way=.dotest/.3way
|
||||
|
||||
MSGFILE=$1
|
||||
PATCHFILE=$2
|
||||
INFO=$3
|
||||
SIGNOFF=$4
|
||||
EDIT=${VISUAL:-${EDITOR:-vi}}
|
||||
|
||||
export GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' "$INFO")"
|
||||
export GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$INFO")"
|
||||
export GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$INFO")"
|
||||
export SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$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" || {
|
||||
test '' = "$LAST_SIGNED_OFF_BY" && echo
|
||||
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 "--------------------------"
|
||||
printf "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" || {
|
||||
|
||||
# git-apply exits with status 1 when the patch does not apply,
|
||||
# but it die()s with other failures, most notably upon corrupt
|
||||
# patch. In the latter case, there is no point to try applying
|
||||
# it to another tree and do 3-way merge.
|
||||
test $? = 1 || exit 1
|
||||
|
||||
test -f "$fall_back_3way" || exit 1
|
||||
|
||||
# Here if we know which revision the patch applies to,
|
||||
# we create a temporary working tree and index, apply the
|
||||
# patch, and attempt 3-way merge with the resulting tree.
|
||||
|
||||
O_OBJECT=`cd "$GIT_OBJECT_DIRECTORY" && pwd`
|
||||
rm -fr .patch-merge-*
|
||||
|
||||
if git-apply -z --index-info "$PATCHFILE" \
|
||||
>.patch-merge-index-info 2>/dev/null &&
|
||||
GIT_INDEX_FILE=.patch-merge-tmp-index \
|
||||
git-update-index -z --index-info <.patch-merge-index-info &&
|
||||
GIT_INDEX_FILE=.patch-merge-tmp-index \
|
||||
git-write-tree >.patch-merge-tmp-base &&
|
||||
(
|
||||
mkdir .patch-merge-tmp-dir &&
|
||||
cd .patch-merge-tmp-dir &&
|
||||
GIT_INDEX_FILE="../.patch-merge-tmp-index" \
|
||||
GIT_OBJECT_DIRECTORY="$O_OBJECT" \
|
||||
git-apply $binary --index
|
||||
) <"$PATCHFILE"
|
||||
then
|
||||
echo Using index info to reconstruct a base tree...
|
||||
mv .patch-merge-tmp-base .patch-merge-base
|
||||
mv .patch-merge-tmp-index .patch-merge-index
|
||||
else
|
||||
(
|
||||
N=10
|
||||
|
||||
# Otherwise, try nearby trees that can be used to apply the
|
||||
# patch.
|
||||
git-rev-list --max-count=$N HEAD
|
||||
|
||||
# or hoping the patch is against known tags...
|
||||
git-ls-remote --tags .
|
||||
) |
|
||||
while read base junk
|
||||
do
|
||||
# Try it if we have it as a tree.
|
||||
git-cat-file tree "$base" >/dev/null 2>&1 || continue
|
||||
|
||||
rm -fr .patch-merge-tmp-* &&
|
||||
mkdir .patch-merge-tmp-dir || break
|
||||
(
|
||||
cd .patch-merge-tmp-dir &&
|
||||
GIT_INDEX_FILE=../.patch-merge-tmp-index &&
|
||||
GIT_OBJECT_DIRECTORY="$O_OBJECT" &&
|
||||
export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY &&
|
||||
git-read-tree "$base" &&
|
||||
git-apply --index &&
|
||||
mv ../.patch-merge-tmp-index ../.patch-merge-index &&
|
||||
echo "$base" >../.patch-merge-base
|
||||
) <"$PATCHFILE" 2>/dev/null && break
|
||||
done
|
||||
fi
|
||||
|
||||
test -f .patch-merge-index &&
|
||||
his_tree=$(GIT_INDEX_FILE=.patch-merge-index git-write-tree) &&
|
||||
orig_tree=$(cat .patch-merge-base) &&
|
||||
rm -fr .patch-merge-* || exit 1
|
||||
|
||||
echo Falling back to patching base and 3-way merge using $orig_tree...
|
||||
|
||||
# This is not so wrong. Depending on which base we picked,
|
||||
# orig_tree may be wildly different from ours, but his_tree
|
||||
# has the same set of wildly different changes in parts the
|
||||
# patch did not touch, so resolve ends up canceling them,
|
||||
# saying that we reverted all those changes.
|
||||
|
||||
if git-merge-resolve $orig_tree -- HEAD $his_tree
|
||||
then
|
||||
echo Done.
|
||||
else
|
||||
echo Failed to merge in the changes.
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
parent=$(git-rev-parse --verify HEAD) &&
|
||||
commit=$(git-commit-tree $tree -p $parent <"$final") || exit 1
|
||||
echo Committed: $commit
|
||||
git-update-ref -m "applypatch: $SUBJECT" HEAD $commit $parent || exit
|
||||
|
||||
if test -x "$GIT_DIR"/hooks/post-applypatch
|
||||
then
|
||||
"$GIT_DIR"/hooks/post-applypatch
|
||||
fi
|
|
@ -0,0 +1,194 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# git-submodules.sh: init, update or list git submodules
|
||||
#
|
||||
# Copyright (c) 2007 Lars Hjemli
|
||||
|
||||
USAGE='[--quiet] [--cached] [status|init|update] [--] [<path>...]'
|
||||
. git-sh-setup
|
||||
require_work_tree
|
||||
|
||||
init=
|
||||
update=
|
||||
status=
|
||||
quiet=
|
||||
cached=
|
||||
|
||||
#
|
||||
# print stuff on stdout unless -q was specified
|
||||
#
|
||||
say()
|
||||
{
|
||||
if test -z "$quiet"
|
||||
then
|
||||
echo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Run clone + checkout on missing submodules
|
||||
#
|
||||
# $@ = requested paths (default to all)
|
||||
#
|
||||
modules_init()
|
||||
{
|
||||
git ls-files --stage -- "$@" | grep -e '^160000 ' |
|
||||
while read mode sha1 stage path
|
||||
do
|
||||
# Skip submodule paths that already contain a .git directory.
|
||||
# This will also trigger if $path is a symlink to a git
|
||||
# repository
|
||||
test -d "$path"/.git && continue
|
||||
|
||||
# If there already is a directory at the submodule path,
|
||||
# expect it to be empty (since that is the default checkout
|
||||
# action) and try to remove it.
|
||||
# Note: if $path is a symlink to a directory the test will
|
||||
# succeed but the rmdir will fail. We might want to fix this.
|
||||
if test -d "$path"
|
||||
then
|
||||
rmdir "$path" 2>/dev/null ||
|
||||
die "Directory '$path' exist, but is neither empty nor a git repository"
|
||||
fi
|
||||
|
||||
test -e "$path" &&
|
||||
die "A file already exist at path '$path'"
|
||||
|
||||
url=$(GIT_CONFIG=.gitmodules git-config module."$path".url)
|
||||
test -z "$url" &&
|
||||
die "No url found for submodule '$path' in .gitmodules"
|
||||
|
||||
# MAYBE FIXME: this would be the place to check GIT_CONFIG
|
||||
# for a preferred url for this submodule, possibly like this:
|
||||
#
|
||||
# modname=$(GIT_CONFIG=.gitmodules git-config module."$path".name)
|
||||
# alturl=$(git-config module."$modname".url)
|
||||
#
|
||||
# This would let the versioned .gitmodules file use the submodule
|
||||
# path as key, while the unversioned GIT_CONFIG would use the
|
||||
# logical modulename (if present) as key. But this would need
|
||||
# another fallback mechanism if the module wasn't named.
|
||||
|
||||
git-clone -n "$url" "$path" ||
|
||||
die "Clone of submodule '$path' failed"
|
||||
|
||||
(unset GIT_DIR && cd "$path" && git-checkout -q "$sha1") ||
|
||||
die "Checkout of submodule '$path' failed"
|
||||
|
||||
say "Submodule '$path' initialized"
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# Checkout correct revision of each initialized submodule
|
||||
#
|
||||
# $@ = requested paths (default to all)
|
||||
#
|
||||
modules_update()
|
||||
{
|
||||
git ls-files --stage -- "$@" | grep -e '^160000 ' |
|
||||
while read mode sha1 stage path
|
||||
do
|
||||
if ! test -d "$path"/.git
|
||||
then
|
||||
# Only mention uninitialized submodules when its
|
||||
# path have been specified
|
||||
test "$#" != "0" &&
|
||||
say "Submodule '$path' not initialized"
|
||||
continue;
|
||||
fi
|
||||
subsha1=$(unset GIT_DIR && cd "$path" &&
|
||||
git-rev-parse --verify HEAD) ||
|
||||
die "Unable to find current revision of submodule '$path'"
|
||||
|
||||
if test "$subsha1" != "$sha1"
|
||||
then
|
||||
(unset GIT_DIR && cd "$path" && git-fetch &&
|
||||
git-checkout -q "$sha1") ||
|
||||
die "Unable to checkout '$sha1' in submodule '$path'"
|
||||
|
||||
say "Submodule '$path': checked out '$sha1'"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# List all registered submodules, prefixed with:
|
||||
# - submodule not initialized
|
||||
# + different revision checked out
|
||||
#
|
||||
# If --cached was specified the revision in the index will be printed
|
||||
# instead of the currently checked out revision.
|
||||
#
|
||||
# $@ = requested paths (default to all)
|
||||
#
|
||||
modules_list()
|
||||
{
|
||||
git ls-files --stage -- "$@" | grep -e '^160000 ' |
|
||||
while read mode sha1 stage path
|
||||
do
|
||||
if ! test -d "$path"/.git
|
||||
then
|
||||
say "-$sha1 $path"
|
||||
continue;
|
||||
fi
|
||||
revname=$(unset GIT_DIR && cd "$path" && git-describe $sha1)
|
||||
if git diff-files --quiet -- "$path"
|
||||
then
|
||||
say " $sha1 $path ($revname)"
|
||||
else
|
||||
if test -z "$cached"
|
||||
then
|
||||
sha1=$(unset GIT_DIR && cd "$path" && git-rev-parse --verify HEAD)
|
||||
revname=$(unset GIT_DIR && cd "$path" && git-describe $sha1)
|
||||
fi
|
||||
say "+$sha1 $path ($revname)"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
while case "$#" in 0) break ;; esac
|
||||
do
|
||||
case "$1" in
|
||||
init)
|
||||
init=1
|
||||
;;
|
||||
update)
|
||||
update=1
|
||||
;;
|
||||
status)
|
||||
status=1
|
||||
;;
|
||||
-q|--quiet)
|
||||
quiet=1
|
||||
;;
|
||||
--cached)
|
||||
cached=1
|
||||
;;
|
||||
--)
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
case "$init,$update,$status,$cached" in
|
||||
1,,,)
|
||||
modules_init "$@"
|
||||
;;
|
||||
,1,,)
|
||||
modules_update "$@"
|
||||
;;
|
||||
,,*,*)
|
||||
modules_list "$@"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
|
@ -0,0 +1,143 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2007 Lars Hjemli
|
||||
#
|
||||
|
||||
test_description='Basic porcelain support for submodules
|
||||
|
||||
This test tries to verify basic sanity of the init, update and status
|
||||
subcommands of git-submodule.
|
||||
'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
#
|
||||
# Test setup:
|
||||
# -create a repository in directory lib
|
||||
# -add a couple of files
|
||||
# -add directory lib to 'superproject', this creates a DIRLINK entry
|
||||
# -add a couple of regular files to enable testing of submodule filtering
|
||||
# -mv lib subrepo
|
||||
# -add an entry to .gitmodules for path 'lib'
|
||||
#
|
||||
test_expect_success 'Prepare submodule testing' '
|
||||
mkdir lib &&
|
||||
cd lib &&
|
||||
git-init &&
|
||||
echo a >a &&
|
||||
git-add a &&
|
||||
git-commit -m "submodule commit 1" &&
|
||||
git-tag -a -m "rev-1" rev-1 &&
|
||||
rev1=$(git-rev-parse HEAD) &&
|
||||
if test -z "$rev1"
|
||||
then
|
||||
echo "[OOPS] submodule git-rev-parse returned nothing"
|
||||
false
|
||||
fi &&
|
||||
cd .. &&
|
||||
echo a >a &&
|
||||
echo z >z &&
|
||||
git-add a lib z &&
|
||||
git-commit -m "super commit 1" &&
|
||||
mv lib .subrepo &&
|
||||
GIT_CONFIG=.gitmodules git-config module.lib.url ./.subrepo
|
||||
'
|
||||
|
||||
test_expect_success 'status should only print one line' '
|
||||
lines=$(git-submodule status | wc -l) &&
|
||||
test $lines = 1
|
||||
'
|
||||
|
||||
test_expect_success 'status should initially be "missing"' '
|
||||
git-submodule status | grep "^-$rev1"
|
||||
'
|
||||
|
||||
test_expect_success 'init should fail when path is used by a file' '
|
||||
echo "hello" >lib &&
|
||||
if git-submodule init
|
||||
then
|
||||
echo "[OOPS] init should have failed"
|
||||
false
|
||||
elif test -f lib && test "$(cat lib)" != "hello"
|
||||
then
|
||||
echo "[OOPS] init failed but lib file was molested"
|
||||
false
|
||||
else
|
||||
rm lib
|
||||
fi
|
||||
'
|
||||
|
||||
test_expect_success 'init should fail when path is used by a nonempty directory' '
|
||||
mkdir lib &&
|
||||
echo "hello" >lib/a &&
|
||||
if git-submodule init
|
||||
then
|
||||
echo "[OOPS] init should have failed"
|
||||
false
|
||||
elif test "$(cat lib/a)" != "hello"
|
||||
then
|
||||
echo "[OOPS] init failed but lib/a was molested"
|
||||
false
|
||||
else
|
||||
rm lib/a
|
||||
fi
|
||||
'
|
||||
|
||||
test_expect_success 'init should work when path is an empty dir' '
|
||||
rm -rf lib &&
|
||||
mkdir lib &&
|
||||
git-submodule init &&
|
||||
head=$(cd lib && git-rev-parse HEAD) &&
|
||||
if test -z "$head"
|
||||
then
|
||||
echo "[OOPS] Failed to obtain submodule head"
|
||||
false
|
||||
elif test "$head" != "$rev1"
|
||||
then
|
||||
echo "[OOPS] Submodule head is $head but should have been $rev1"
|
||||
false
|
||||
fi
|
||||
'
|
||||
|
||||
test_expect_success 'status should be "up-to-date" after init' '
|
||||
git-submodule status | grep "^ $rev1"
|
||||
'
|
||||
|
||||
test_expect_success 'status should be "modified" after submodule commit' '
|
||||
cd lib &&
|
||||
echo b >b &&
|
||||
git-add b &&
|
||||
git-commit -m "submodule commit 2" &&
|
||||
rev2=$(git-rev-parse HEAD) &&
|
||||
cd .. &&
|
||||
if test -z "$rev2"
|
||||
then
|
||||
echo "[OOPS] submodule git-rev-parse returned nothing"
|
||||
false
|
||||
fi &&
|
||||
git-submodule status | grep "^+$rev2"
|
||||
'
|
||||
|
||||
test_expect_success 'the --cached sha1 should be rev1' '
|
||||
git-submodule --cached status | grep "^+$rev1"
|
||||
'
|
||||
|
||||
test_expect_success 'update should checkout rev1' '
|
||||
git-submodule update &&
|
||||
head=$(cd lib && git-rev-parse HEAD) &&
|
||||
if test -z "$head"
|
||||
then
|
||||
echo "[OOPS] submodule git-rev-parse returned nothing"
|
||||
false
|
||||
elif test "$head" != "$rev1"
|
||||
then
|
||||
echo "[OOPS] init did not checkout correct head"
|
||||
false
|
||||
fi
|
||||
'
|
||||
|
||||
test_expect_success 'status should be "up-to-date" after update' '
|
||||
git-submodule status | grep "^ $rev1"
|
||||
'
|
||||
|
||||
test_done
|
Загрузка…
Ссылка в новой задаче