Merge branch 'maint'
* maint: 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-shellmaint
						commit
						a17b1d2f0b
					
				|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -3117,7 +3117,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); | ||||||
|  |  | ||||||
|  | @ -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); | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								git-am.sh
								
								
								
								
							
							
						
						
									
										24
									
								
								git-am.sh
								
								
								
								
							|  | @ -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 | ||||||
|  |  | ||||||
|  | @ -66,9 +66,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 | ||||||
|  | @ -82,7 +83,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" | ||||||
|  | @ -103,6 +104,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 | ||||||
|  | @ -120,13 +122,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 | ||||||
| } | } | ||||||
|  | @ -157,12 +161,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." ;; | ||||||
| 	*) | 	*) | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
| ' | ' | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano