Merge branch 'maint-1.5.4' into maint

* maint-1.5.4:
  git-bisect: make "start", "good" and "skip" succeed or fail atomically
  git-am: cope better with an empty Subject: line
  Ignore leading empty lines while summarizing merges
  bisect: squelch "fatal: ref HEAD not a symref" misleading message
  builtin-apply: Show a more descriptive error on failure when opening a patch
  Clarify documentation of git-cvsserver, particularly in relation to git-shell
This commit is contained in:
Junio C Hamano 2008-04-16 00:37:33 -07:00
commit 464509f790
6 changed files with 54 additions and 33 deletions

View file

@ -110,7 +110,9 @@ cvs -d ":ext;CVS_SERVER=git-cvsserver:user@server/path/repo.git" co <HEAD_name>
------ ------
This has the advantage that it will be saved in your 'CVS/Root' files and This has the advantage that it will be saved in your 'CVS/Root' files and
you don't need to worry about always setting the correct environment you don't need to worry about always setting the correct environment
variable. variable. SSH users restricted to git-shell don't need to override the default
with CVS_SERVER (and shouldn't) as git-shell understands `cvs` to mean
git-cvsserver and pretends that the other end runs the real cvs better.
-- --
2. For each repo that you want accessible from CVS you need to edit config in 2. For each repo that you want accessible from CVS you need to edit config in
the repo and add the following section. the repo and add the following section.
@ -141,25 +143,29 @@ allowing access over SSH.
enabled=1 enabled=1
------ ------
-- --
3. On the client machine you need to set the following variables. 3. If you didn't specify the CVSROOT/CVS_SERVER directly in the checkout command,
CVSROOT should be set as per normal, but the directory should point at the automatically saving it in your 'CVS/Root' files, then you need to set them
appropriate git repo. For example: explicitly in your environment. CVSROOT should be set as per normal, but the
directory should point at the appropriate git repo. As above, for SSH clients
_not_ restricted to git-shell, CVS_SERVER should be set to git-cvsserver.
+ +
-- --
For SSH access, CVS_SERVER should be set to git-cvsserver
Example:
------ ------
export CVSROOT=:ext:user@server:/var/git/project.git export CVSROOT=:ext:user@server:/var/git/project.git
export CVS_SERVER=git-cvsserver export CVS_SERVER=git-cvsserver
------ ------
-- --
4. For SSH clients that will make commits, make sure their .bashrc file 4. For SSH clients that will make commits, make sure their server-side
sets the GIT_AUTHOR and GIT_COMMITTER variables. .ssh/environment files (or .bashrc, etc., according to their specific shell)
export appropriate values for GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL,
GIT_COMMITTER_NAME, and GIT_COMMITTER_EMAIL. For SSH clients whose login
shell is bash, .bashrc may be a reasonable alternative.
5. Clients should now be able to check out the project. Use the CVS 'module' 5. Clients should now be able to check out the project. Use the CVS 'module'
name to indicate what GIT 'head' you want to check out. Example: name to indicate what GIT 'head' you want to check out. This also sets the
name of your newly checked-out directory, unless you tell it otherwise with
`-d <dir_name>`. For example, this checks out 'master' branch to the
`project-master` directory:
+ +
------ ------
cvs co -d project-master master cvs co -d project-master master

View file

@ -3121,7 +3121,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
fd = open(arg, O_RDONLY); fd = open(arg, O_RDONLY);
if (fd < 0) if (fd < 0)
usage(apply_usage); die("can't open patch '%s': %s", arg, strerror(errno));
read_stdin = 0; read_stdin = 0;
set_default_whitespace_mode(whitespace_option); set_default_whitespace_mode(whitespace_option);
errs |= apply_patch(fd, arg, inaccurate_eof); errs |= apply_patch(fd, arg, inaccurate_eof);

View file

@ -201,6 +201,15 @@ static void shortlog(const char *name, unsigned char *sha1,
continue; continue;
bol = strstr(commit->buffer, "\n\n"); bol = strstr(commit->buffer, "\n\n");
if (bol) {
unsigned char c;
do {
c = *++bol;
} while (isspace(c));
if (!c)
bol = NULL;
}
if (!bol) { if (!bol) {
append_to_list(&subjects, xstrdup(sha1_to_hex( append_to_list(&subjects, xstrdup(sha1_to_hex(
commit->object.sha1)), commit->object.sha1)),
@ -208,7 +217,6 @@ static void shortlog(const char *name, unsigned char *sha1,
continue; continue;
} }
bol += 2;
eol = strchr(bol, '\n'); eol = strchr(bol, '\n');
if (eol) { if (eol) {
oneline = xmemdupz(bol, eol - bol); oneline = xmemdupz(bol, eol - bol);

View file

@ -107,7 +107,7 @@ It does not apply to blobs recorded in its index."
# patch did not touch, so recursive ends up canceling them, # patch did not touch, so recursive ends up canceling them,
# saying that we reverted all those changes. # saying that we reverted all those changes.
eval GITHEAD_$his_tree='"$SUBJECT"' eval GITHEAD_$his_tree='"$FIRSTLINE"'
export GITHEAD_$his_tree export GITHEAD_$his_tree
git-merge-recursive $orig_tree -- HEAD $his_tree || { git-merge-recursive $orig_tree -- HEAD $his_tree || {
git rerere git rerere
@ -117,10 +117,6 @@ It does not apply to blobs recorded in its index."
unset GITHEAD_$his_tree unset GITHEAD_$his_tree
} }
reread_subject () {
git stripspace <"$1" | sed -e 1q
}
prec=4 prec=4
dotest=".dotest" dotest=".dotest"
sign= utf8=t keep= skip= interactive= resolved= binary= rebasing= sign= utf8=t keep= skip= interactive= resolved= binary= rebasing=
@ -331,7 +327,11 @@ do
echo "Patch is empty. Was it split wrong?" echo "Patch is empty. Was it split wrong?"
stop_here $this stop_here $this
} }
git stripspace < "$dotest/msg" > "$dotest/msg-clean" SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$dotest/info")"
case "$keep_subject" in -k) SUBJECT="[PATCH] $SUBJECT" ;; esac
(echo "$SUBJECT" ; echo ; cat "$dotest/msg") |
git stripspace > "$dotest/msg-clean"
;; ;;
esac esac
@ -347,9 +347,6 @@ do
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$dotest/info")"
case "$keep_subject" in -k) SUBJECT="[PATCH] $SUBJECT" ;; esac
case "$resume" in case "$resume" in
'') '')
if test '' != "$SIGNOFF" if test '' != "$SIGNOFF"
@ -368,10 +365,8 @@ do
ADD_SIGNOFF= ADD_SIGNOFF=
fi fi
{ {
printf '%s\n' "$SUBJECT"
if test -s "$dotest/msg-clean" if test -s "$dotest/msg-clean"
then then
echo
cat "$dotest/msg-clean" cat "$dotest/msg-clean"
fi fi
if test '' != "$ADD_SIGNOFF" if test '' != "$ADD_SIGNOFF"
@ -388,6 +383,7 @@ do
;; ;;
esac esac
esac esac
FIRSTLINE=$(head -1 "$dotest/final-commit")
resume= resume=
if test "$interactive" = t if test "$interactive" = t
@ -408,7 +404,7 @@ do
[aA]*) action=yes interactive= ;; [aA]*) action=yes interactive= ;;
[nN]*) action=skip ;; [nN]*) action=skip ;;
[eE]*) git_editor "$dotest/final-commit" [eE]*) git_editor "$dotest/final-commit"
SUBJECT=$(reread_subject "$dotest/final-commit") FIRSTLINE=$(head -1 "$dotest/final-commit")
action=again ;; action=again ;;
[vV]*) action=again [vV]*) action=again
LESS=-S ${PAGER:-less} "$dotest/patch" ;; LESS=-S ${PAGER:-less} "$dotest/patch" ;;
@ -431,7 +427,7 @@ do
stop_here $this stop_here $this
fi fi
printf 'Applying %s\n' "$SUBJECT" printf 'Applying %s\n' "$FIRSTLINE"
case "$resolved" in case "$resolved" in
'') '')
@ -489,7 +485,7 @@ do
tree=$(git write-tree) && tree=$(git write-tree) &&
parent=$(git rev-parse --verify HEAD) && parent=$(git rev-parse --verify HEAD) &&
commit=$(git commit-tree $tree -p $parent <"$dotest/final-commit") && commit=$(git commit-tree $tree -p $parent <"$dotest/final-commit") &&
git update-ref -m "$GIT_REFLOG_ACTION: $SUBJECT" HEAD $commit $parent || git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent ||
stop_here $this stop_here $this
if test -x "$GIT_DIR"/hooks/post-applypatch if test -x "$GIT_DIR"/hooks/post-applypatch

View file

@ -62,9 +62,10 @@ bisect_start() {
# Verify HEAD. If we were bisecting before this, reset to the # Verify HEAD. If we were bisecting before this, reset to the
# top-of-line master first! # top-of-line master first!
# #
head=$(GIT_DIR="$GIT_DIR" git symbolic-ref HEAD) || head=$(GIT_DIR="$GIT_DIR" git symbolic-ref -q HEAD) ||
head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) || head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) ||
die "Bad HEAD - I need a HEAD" die "Bad HEAD - I need a HEAD"
start_head=''
case "$head" in case "$head" in
refs/heads/bisect) refs/heads/bisect)
if [ -s "$GIT_DIR/BISECT_START" ]; then if [ -s "$GIT_DIR/BISECT_START" ]; then
@ -78,7 +79,7 @@ bisect_start() {
# This error message should only be triggered by cogito usage, # This error message should only be triggered by cogito usage,
# and cogito users should understand it relates to cg-seek. # and cogito users should understand it relates to cg-seek.
[ -s "$GIT_DIR/head-name" ] && die "won't bisect on seeked tree" [ -s "$GIT_DIR/head-name" ] && die "won't bisect on seeked tree"
echo "${head#refs/heads/}" >"$GIT_DIR/BISECT_START" start_head="${head#refs/heads/}"
;; ;;
*) *)
die "Bad HEAD - strange symbolic ref" die "Bad HEAD - strange symbolic ref"
@ -99,6 +100,7 @@ bisect_start() {
done done
orig_args=$(sq "$@") orig_args=$(sq "$@")
bad_seen=0 bad_seen=0
eval=''
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
arg="$1" arg="$1"
case "$arg" in case "$arg" in
@ -116,13 +118,15 @@ bisect_start() {
0) state='bad' ; bad_seen=1 ;; 0) state='bad' ; bad_seen=1 ;;
*) state='good' ;; *) state='good' ;;
esac esac
bisect_write "$state" "$rev" 'nolog' eval="$eval bisect_write '$state' '$rev' 'nolog'; "
shift shift
;; ;;
esac esac
done done
sq "$@" >"$GIT_DIR/BISECT_NAMES" sq "$@" >"$GIT_DIR/BISECT_NAMES"
test -n "$start_head" && echo "$start_head" >"$GIT_DIR/BISECT_START"
eval "$eval"
echo "git-bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG" echo "git-bisect start$orig_args" >>"$GIT_DIR/BISECT_LOG"
bisect_auto_next bisect_auto_next
} }
@ -153,12 +157,14 @@ bisect_state() {
bisect_write "$state" "$rev" ;; bisect_write "$state" "$rev" ;;
2,bad|*,good|*,skip) 2,bad|*,good|*,skip)
shift shift
eval=''
for rev in "$@" for rev in "$@"
do do
sha=$(git rev-parse --verify "$rev^{commit}") || sha=$(git rev-parse --verify "$rev^{commit}") ||
die "Bad rev input: $rev" die "Bad rev input: $rev"
bisect_write "$state" "$sha" eval="$eval bisect_write '$state' '$sha'; "
done ;; done
eval "$eval" ;;
*,bad) *,bad)
die "'git bisect bad' can take only one argument." ;; die "'git bisect bad' can take only one argument." ;;
*) *)

View file

@ -71,8 +71,12 @@ test_expect_success 'bisect start with one bad and good' '
git bisect next git bisect next
' '
test_expect_success 'bisect good and bad fails if not given only revs' ' test_expect_success 'bisect fails if given any junk instead of revs' '
git bisect reset && git bisect reset &&
test_must_fail git bisect start foo $HASH1 -- &&
test_must_fail git bisect start $HASH4 $HASH1 bar -- &&
test -z "$(git for-each-ref "refs/bisect/*")" &&
test_must_fail ls .git/BISECT_* &&
git bisect start && git bisect start &&
test_must_fail git bisect good foo $HASH1 && test_must_fail git bisect good foo $HASH1 &&
test_must_fail git bisect good $HASH1 bar && test_must_fail git bisect good $HASH1 bar &&
@ -80,6 +84,7 @@ test_expect_success 'bisect good and bad fails if not given only revs' '
test_must_fail git bisect bad $HASH3 $HASH4 && test_must_fail git bisect bad $HASH3 $HASH4 &&
test_must_fail git bisect skip bar $HASH3 && test_must_fail git bisect skip bar $HASH3 &&
test_must_fail git bisect skip $HASH1 foo && test_must_fail git bisect skip $HASH1 foo &&
test -z "$(git for-each-ref "refs/bisect/*")" &&
git bisect good $HASH1 && git bisect good $HASH1 &&
git bisect bad $HASH4 git bisect bad $HASH4
' '