From eab9a40b6dd5c1c571b1deb264133db47bb4794d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 18 Dec 2007 19:32:14 +0000 Subject: [PATCH 01/35] Teach diff machinery to display other prefixes than "a/" and "b/" With the new options "--src-prefix=", "--dst-prefix=" and "--no-prefix", you can now control the path prefixes of the diff machinery. These used to by hardwired to "a/" for the source prefix and "b/" for the destination prefix. Initial patch by Pascal Obry. Sane option names suggested by Linus. Signed-off-by: Johannes Schindelin Acked-by: Linus Torvalds Signed-off-by: Junio C Hamano --- Documentation/diff-options.txt | 9 +++++++++ diff.c | 25 +++++++++++++++++-------- diff.h | 1 + 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 9ecc1d7bc4..1a78635fba 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -211,5 +211,14 @@ endif::git-format-patch[] --no-ext-diff:: Disallow external diff drivers. +--src-prefix=:: + Show the given source prefix instead of "a/". + +--dst-prefix=:: + Show the given destination prefix instead of "b/". + +--no-prefix:: + Do not show any source or destination prefix. + For more detailed explanation on these common options, see also link:diffcore.html[diffcore documentation]. diff --git a/diff.c b/diff.c index e26584cdfc..61fd49236a 100644 --- a/diff.c +++ b/diff.c @@ -290,9 +290,10 @@ static void emit_rewrite_diff(const char *name_a, const char *name_b, struct diff_filespec *one, struct diff_filespec *two, - int color_diff) + struct diff_options *o) { int lc_a, lc_b; + int color_diff = DIFF_OPT_TST(o, COLOR_DIFF); const char *name_a_tab, *name_b_tab; const char *metainfo = diff_get_color(color_diff, DIFF_METAINFO); const char *fraginfo = diff_get_color(color_diff, DIFF_FRAGINFO); @@ -309,9 +310,9 @@ static void emit_rewrite_diff(const char *name_a, diff_populate_filespec(two, 0); lc_a = count_lines(one->data, one->size); lc_b = count_lines(two->data, two->size); - printf("%s--- a/%s%s%s\n%s+++ b/%s%s%s\n%s@@ -", - metainfo, name_a, name_a_tab, reset, - metainfo, name_b, name_b_tab, reset, fraginfo); + printf("%s--- %s%s%s%s\n%s+++ %s%s%s%s\n%s@@ -", + metainfo, o->a_prefix, name_a, name_a_tab, reset, + metainfo, o->b_prefix, name_b, name_b_tab, reset, fraginfo); print_line_count(lc_a); printf(" +"); print_line_count(lc_b); @@ -1212,8 +1213,8 @@ static void builtin_diff(const char *name_a, const char *set = diff_get_color_opt(o, DIFF_METAINFO); const char *reset = diff_get_color_opt(o, DIFF_RESET); - a_one = quote_two("a/", name_a + (*name_a == '/')); - b_two = quote_two("b/", name_b + (*name_b == '/')); + a_one = quote_two(o->a_prefix, name_a + (*name_a == '/')); + b_two = quote_two(o->b_prefix, name_b + (*name_b == '/')); lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null"; lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null"; printf("%sdiff --git %s %s%s\n", set, a_one, b_two, reset); @@ -1242,8 +1243,7 @@ static void builtin_diff(const char *name_a, if ((one->mode ^ two->mode) & S_IFMT) goto free_ab_and_return; if (complete_rewrite) { - emit_rewrite_diff(name_a, name_b, one, two, - DIFF_OPT_TST(o, COLOR_DIFF)); + emit_rewrite_diff(name_a, name_b, one, two, o); o->found_changes = 1; goto free_ab_and_return; } @@ -2020,6 +2020,9 @@ void diff_setup(struct diff_options *options) else DIFF_OPT_CLR(options, COLOR_DIFF); options->detect_rename = diff_detect_rename_default; + + options->a_prefix = "a/"; + options->b_prefix = "b/"; } int diff_setup_done(struct diff_options *options) @@ -2291,6 +2294,12 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) else if (40 < options->abbrev) options->abbrev = 40; } + else if (!prefixcmp(arg, "--src-prefix=")) + options->a_prefix = arg + 13; + else if (!prefixcmp(arg, "--dst-prefix=")) + options->b_prefix = arg + 13; + else if (!strcmp(arg, "--no-prefix")) + options->a_prefix = options->b_prefix = ""; else return 0; return 1; diff --git a/diff.h b/diff.h index 7e8000a5d7..beccf85962 100644 --- a/diff.h +++ b/diff.h @@ -69,6 +69,7 @@ struct diff_options { const char *orderfile; const char *pickaxe; const char *single_follow; + const char *a_prefix, *b_prefix; unsigned flags; int context; int break_opt; From 885ed372d09f68806b17fc8fd0ac13a46636aeb2 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 19 Dec 2007 16:21:30 -0800 Subject: [PATCH 02/35] t4024: fix test script to use simpler sed pattern The earlier test stripped away expected number of 'z' but the output would have been very hard to read once somebody broke the common tail optimization. Instead, count the number of 'z' and show it, to help diagnosing the problem better in the future. Signed-off-by: Junio C Hamano --- t/t4024-diff-optimize-common.sh | 158 +++++++++++++++++++++++++------- 1 file changed, 123 insertions(+), 35 deletions(-) diff --git a/t/t4024-diff-optimize-common.sh b/t/t4024-diff-optimize-common.sh index 20fe87b7dd..3c66102f7a 100755 --- a/t/t4024-diff-optimize-common.sh +++ b/t/t4024-diff-optimize-common.sh @@ -10,58 +10,146 @@ z="$z$z$z$z$z$z$z$z" ;# 512 z="$z$z$z$z" ;# 2048 z2047=$(expr "$z" : '.\(.*\)') ; #2047 -test_expect_success setup ' +x=zzzzzzzzzz ;# 10 +y="$x$x$x$x$x$x$x$x$x$x" ;# 100 +z="$y$y$y$y$y$y$y$y$y$y" ;# 1000 +z1000=$z +z100=$y +z10=$x - echo "a$z2047" >file-a && - echo "b" >file-b && - echo "$z2047" >>file-b && - echo "c$z2047" | tr -d "\012" >file-c && - echo "d" >file-d && - echo "$z2047" | tr -d "\012" >>file-d && +zs() { + count="$1" + while test "$count" -ge 1000 + do + count=$(($count - 1000)) + printf "%s" $z1000 + done + while test "$count" -ge 100 + do + count=$(($count - 100)) + printf "%s" $z100 + done + while test "$count" -ge 10 + do + count=$(($count - 10)) + printf "%s" $z10 + done + while test "$count" -ge 1 + do + count=$(($count - 1)) + printf "z" + done +} - git add file-a file-b file-c file-d && +zc () { + sed -e "/^index/d" \ + -e "s/$z1000/Q/g" \ + -e "s/QQQQQQQQQ/Z9000/g" \ + -e "s/QQQQQQQQ/Z8000/g" \ + -e "s/QQQQQQQ/Z7000/g" \ + -e "s/QQQQQQ/Z6000/g" \ + -e "s/QQQQQ/Z5000/g" \ + -e "s/QQQQ/Z4000/g" \ + -e "s/QQQ/Z3000/g" \ + -e "s/QQ/Z2000/g" \ + -e "s/Q/Z1000/g" \ + -e "s/$z100/Q/g" \ + -e "s/QQQQQQQQQ/Z900/g" \ + -e "s/QQQQQQQQ/Z800/g" \ + -e "s/QQQQQQQ/Z700/g" \ + -e "s/QQQQQQ/Z600/g" \ + -e "s/QQQQQ/Z500/g" \ + -e "s/QQQQ/Z400/g" \ + -e "s/QQQ/Z300/g" \ + -e "s/QQ/Z200/g" \ + -e "s/Q/Z100/g" \ + -e "s/000Z//g" \ + -e "s/$z10/Q/g" \ + -e "s/QQQQQQQQQ/Z90/g" \ + -e "s/QQQQQQQQ/Z80/g" \ + -e "s/QQQQQQQ/Z70/g" \ + -e "s/QQQQQQ/Z60/g" \ + -e "s/QQQQQ/Z50/g" \ + -e "s/QQQQ/Z40/g" \ + -e "s/QQQ/Z30/g" \ + -e "s/QQ/Z20/g" \ + -e "s/Q/Z10/g" \ + -e "s/00Z//g" \ + -e "s/z/Q/g" \ + -e "s/QQQQQQQQQ/Z9/g" \ + -e "s/QQQQQQQQ/Z8/g" \ + -e "s/QQQQQQQ/Z7/g" \ + -e "s/QQQQQQ/Z6/g" \ + -e "s/QQQQQ/Z5/g" \ + -e "s/QQQQ/Z4/g" \ + -e "s/QQQ/Z3/g" \ + -e "s/QQ/Z2/g" \ + -e "s/Q/Z1/g" \ + -e "s/0Z//g" \ + ; +} - echo "A$z2047" >file-a && - echo "B" >file-b && - echo "$z2047" >>file-b && - echo "C$z2047" | tr -d "\012" >file-c && - echo "D" >file-d && - echo "$z2047" | tr -d "\012" >>file-d - -' - -cat >expect <<\EOF -diff --git a/file-a b/file-a ---- a/file-a -+++ b/file-a +expect_pattern () { + cnt="$1" + cat <file-a$n && + ( echo b; zs $n; echo ) >file-b$n && + ( printf c; zs $n ) >file-c$n && + ( echo d; zs $n ) >file-d$n && + + git add file-a$n file-b$n file-c$n file-d$n && + + ( zs $n ; echo A ) >file-a$n && + ( echo B; zs $n; echo ) >file-b$n && + ( printf C; zs $n ) >file-c$n && + ( echo D; zs $n ) >file-d$n && + + expect_pattern $n || break + + done >expect +' test_expect_success 'diff -U0' ' - git diff -U0 | sed -e "/^index/d" -e "s/$z2047/Z/g" >actual && + for n in $sample + do + git diff -U0 file-?$n + done | zc >actual && diff -u expect actual ' From fbcf1184026197128582369074201c490009b4eb Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 19 Dec 2007 19:23:03 -0800 Subject: [PATCH 03/35] fix git commit --amend -m "new message" The prepare_log_message() function serves two purposes: - Prepares the commit log message template, to be given to the end user; - Return true if there is something committable; 7168624c3530d8c7ee32f930f8fb2ba302b9801f (Do not generate full commit log message if it is not going to be used) cheated to omit the former when we know the log message template is not going to be used. However, its replacement logic to see if there is something committable was botched. When amending, it should compare the index with the parent of the HEAD, not the current HEAD. Otherwise you cannot run --amend to fix only the message without changing the tree. Signed-off-by: Junio C Hamano --- builtin-commit.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/builtin-commit.c b/builtin-commit.c index 0a9101324f..96410de55d 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -375,6 +375,7 @@ static int prepare_log_message(const char *index_file, const char *prefix) if (no_edit) { struct rev_info rev; unsigned char sha1[40]; + const char *parent = "HEAD"; fclose(fp); @@ -384,9 +385,12 @@ static int prepare_log_message(const char *index_file, const char *prefix) if (get_sha1("HEAD", sha1) != 0) return !!active_nr; + if (amend) + parent = "HEAD^1"; + init_revisions(&rev, ""); rev.abbrev = 0; - setup_revisions(0, NULL, &rev, "HEAD"); + setup_revisions(0, NULL, &rev, parent); DIFF_OPT_SET(&rev.diffopt, QUIET); DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS); run_diff_index(&rev, 1 /* cached */); From 03270628ed61f56431658eacd335b8f2f8ecc05a Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 20 Dec 2007 02:12:12 -0500 Subject: [PATCH 04/35] Reallow git-rebase --interactive --continue if commit is unnecessary During git-rebase --interactive's --continue implementation we used to silently restart the rebase if the user had made the commit for us. This is common if the user stops to edit a commit and does so by amending it. My recent change to watch git-commit's exit status broke this behavior. Thanks to Bernt Hansen for catching it in 1.5.4-rc1. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 47581ced5a..090c3e5143 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -372,8 +372,10 @@ do test ! -f "$DOTEST"/amend || git reset --soft HEAD^ } && export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE && - git commit --no-verify -F "$DOTEST"/message -e || + if ! git commit --no-verify -F "$DOTEST"/message -e + then die "Could not commit staged changes." + fi require_clean_work_tree do_rest From 5d29275638f48ee442202f0c478d1d8b9d396cc6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 20 Dec 2007 12:58:06 -0800 Subject: [PATCH 05/35] shell-scripts usage(): consistently exit with non-zero Earlier conversion of shell scripts to parse-options made usage() to run "git cmd -h" which in turn emit LONG_USAGE and exit with 0 status. This is inconsistent with the scripts that do not use parse-options, whose usage() died with the message, exiting with 1. Signed-off-by: Junio C Hamano --- git-sh-setup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/git-sh-setup.sh b/git-sh-setup.sh index 270d559297..aae14090bd 100755 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -18,7 +18,8 @@ die() { if test -n "$OPTIONS_SPEC"; then usage() { - exec "$0" -h + "$0" -h + exit 1 } parseopt_extra= From cdd859159e7677c466a319e4349c8b3933f8c5d6 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Thu, 20 Dec 2007 12:50:34 +0100 Subject: [PATCH 06/35] Mention git-shell's "cvs" substitution in the RelNotes git shell became much more powerful for existing CVS setups. We should not hide from those people who only read release notes. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.5.4.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/RelNotes-1.5.4.txt b/Documentation/RelNotes-1.5.4.txt index cd79124958..fb521c3fa7 100644 --- a/Documentation/RelNotes-1.5.4.txt +++ b/Documentation/RelNotes-1.5.4.txt @@ -175,7 +175,9 @@ Updates since v1.5.3 * "git remote" learned "rm" subcommand. - * "git cvsserver" can be run via "git shell". + * "git cvsserver" can be run via "git shell". Also, "cvs" is + recognized as a synonym for "git cvsserver", so that CVS users + can be switched to git just by changing their login shell. * "git cvsserver" acts more like receive-pack by running post-receive and post-update hooks. From 6a7f14c4651f9773eb5e7e8111721a979ce2a64c Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 20 Dec 2007 07:11:25 -0500 Subject: [PATCH 07/35] clean up 1.5.4 release notes Mostly typo and small grammatical fixes with one or two rewordings for clarity. But note the important fix for status.relativepaths. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.5.4.txt | 33 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/Documentation/RelNotes-1.5.4.txt b/Documentation/RelNotes-1.5.4.txt index fb521c3fa7..528b26f7c7 100644 --- a/Documentation/RelNotes-1.5.4.txt +++ b/Documentation/RelNotes-1.5.4.txt @@ -14,28 +14,28 @@ Removal Deprecation notices ------------------- - * Next feature release of git (this change is scheduled for v1.6.0) + * The next feature release of git (this change is scheduled for v1.6.0) will by default install dashed form of commands (e.g. "git-commit") outside of users' normal $PATH, and will install only selected commands ("git" itself, and "gitk") in $PATH. This implies: - - Using dashed form of git commands (e.g. "git-commit") from the + - Using dashed forms of git commands (e.g. "git-commit") from the command line has been informally deprecated since early 2006, but now it officially is, and will be removed in the future. Use - dashless form (e.g. "git commit") instead. + dashless forms (e.g. "git commit") instead. - - Using dashed from from your scripts, without first prepending the + - Using dashed forms from your scripts, without first prepending the return value from "git --exec-path" to the scripts' PATH, has been informally deprecated since early 2006, but now it officially is. - - Use of dashed form with "PATH=$(git --exec-path):$PATH; export + - Use of dashed forms with "PATH=$(git --exec-path):$PATH; export PATH" early in your script is not deprecated with this change. Users are strongly encouraged to adjust their habits and scripts now to prepare for this. * The post-receive hook was introduced in March 2007 to supersede - post-update hook, primarily to overcome the command line length + the post-update hook, primarily to overcome the command line length limitation of the latter. Use of post-update hook will be deprecated in future versions of git, starting from v1.6.0. @@ -43,10 +43,11 @@ Deprecation notices option, and will be removed in the future. * "git peek-remote" is deprecated, as "git ls-remote" was written in C - and works for all transports, and will be removed in the future. + and works for all transports; "git peek-remote" will be removed in + the future. * From v1.6.0, the repack.usedeltabaseoffset config option will default - to true, which will give denser packfile (i.e. more efficient storage). + to true, which will give denser packfiles (i.e. more efficient storage). The downside is that git older than version 1.4.4 will not be able to directly use a repository packed using this setting. @@ -67,7 +68,7 @@ Updates since v1.5.3 * gitk is now merged as a subdirectory of git.git project, in preparation for its i18n. - * progress display from many commands are a lot nicer to the eye. + * progress displays from many commands are a lot nicer to the eye. Transfer commands show throughput data. * many commands that pay attention to per-directory .gitignore now do @@ -76,12 +77,12 @@ Updates since v1.5.3 * Output processing for '--pretty=format:' has been optimized. - * Rename detection of diff family, while detecting exact matches, has + * Rename detection of diff family while detecting exact matches has been greatly optimized. - * Rename detection of diff family tries to make more naturally looking - pairing. Earlier if more than one identical rename sources were - found in the preimage, they were picked pretty much at random. + * Rename detection of diff family tries to make more natural looking + pairing. Earlier, if multiple identical rename sources were + found in the preimage, the source used was picked pretty much at random. * Value "true" for color.diff and color.status configuration used to mean "always" (even when the output is not going to a terminal). @@ -114,7 +115,7 @@ Updates since v1.5.3 * "git rebase --interactive" mode can now work on detached HEAD. - * Other minor to serious bugs in "git rebase -i" has been fixed. + * Other minor to serious bugs in "git rebase -i" have been fixed. * "git rebase" now detaches head during its operation, so after a successful "git rebase" operation, the reflog entry branch@{1} for @@ -247,7 +248,7 @@ Updates since v1.5.3 * The format "git show" outputs an annotated tag has been updated to include "Tagger: " and "Date: " lines from the tag itself. Strictly speaking this is a backward incompatible change, but this is a - reasonable usability fix and people's script shouldn't have been + reasonable usability fix and people's scripts shouldn't have been relying on the exact output from "git show" Porcelain anyway. * "git cvsexportcommit" learned -w option to specify and switch to the @@ -283,7 +284,7 @@ Updates since v1.5.3 makes copy-and-pasting for git-checkout/git-add/git-rm easier. The traditional behaviour to show the full path relative to the top of the work tree can be had by setting status.relativepaths - configuration variable to true. + configuration variable to false. * "git blame" kept text for each annotated revision in core needlessly; this has been corrected. From feb7f38b01761a695ecf53f94237251c1d3aa650 Mon Sep 17 00:00:00 2001 From: Charles Bailey Date: Thu, 20 Dec 2007 13:00:40 +0000 Subject: [PATCH 08/35] Remove old generated files from .gitignore. Some entries in .gitignore are obselete. These should be cleaned up just for the sake of general tidiness and so that any developers who have a working tree that was moved forward without a clean know that they have old stuff in their work tree. Signed-off-by: Charles Bailey Signed-off-by: Junio C Hamano --- .gitignore | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.gitignore b/.gitignore index dab5bc2a3c..7f8421dcd0 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,6 @@ git-fetch git-fetch--tool git-fetch-pack git-filter-branch -git-findtags git-fmt-merge-msg git-for-each-ref git-format-patch @@ -59,7 +58,6 @@ git-index-pack git-init git-init-db git-instaweb -git-local-fetch git-log git-lost-found git-ls-files @@ -120,10 +118,6 @@ git-show git-show-branch git-show-index git-show-ref -git-ssh-fetch -git-ssh-pull -git-ssh-push -git-ssh-upload git-stash git-status git-stripspace From 8a82b133547a93e8bdc08fd199c237f540eb9249 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 20 Dec 2007 15:05:45 +0100 Subject: [PATCH 09/35] everyday: replace 'prune' and 'repack' with 'gc' In everyday tasks, "repack -a -d -f" won't be used, so there is not much point mentioning "repack". By showing the --prune option to "gc", we can do without mentioning "git prune", too. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- Documentation/everyday.txt | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt index ce7c170d69..f1993e2935 100644 --- a/Documentation/everyday.txt +++ b/Documentation/everyday.txt @@ -30,10 +30,6 @@ Everybody uses these commands to maintain git repositories. * gitlink:git-fsck[1] to check the repository for errors. - * gitlink:git-prune[1] to remove unused objects in the repository. - - * gitlink:git-repack[1] to pack loose objects for efficiency. - * gitlink:git-gc[1] to do common housekeeping tasks such as repack and prune. @@ -45,24 +41,21 @@ Check health and remove cruft.:: ------------ $ git fsck <1> $ git count-objects <2> -$ git repack <3> -$ git gc <4> +$ git gc <3> ------------ + <1> running without `\--full` is usually cheap and assures the repository health reasonably well. <2> check how many loose objects there are and how much disk space is wasted by not repacking. -<3> without `-a` repacks incrementally. repacking every 4-5MB -of loose objects accumulation may be a good rule of thumb. -<4> it is easier to use `git gc` than individual housekeeping commands -such as `prune` and `repack`. This runs `repack -a -d`. +<3> repacks the local repository and performs other housekeeping tasks. Running +without `--prune` is a safe operation even while other ones are in progress. Repack a small project into single pack.:: + ------------ -$ git repack -a -d <1> -$ git prune +$ git gc <1> +$ git gc --prune ------------ + <1> pack all the objects reachable from the refs into one pack, @@ -189,7 +182,7 @@ $ git pull <3> $ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 <4> $ git pull git://git.kernel.org/pub/.../jgarzik/libata-dev.git ALL <5> $ git reset --hard ORIG_HEAD <6> -$ git prune <7> +$ git gc --prune <7> $ git fetch --tags <8> ------------ + From d76a585d83aeb6910e7eb10d36b406dc27202675 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Thu, 20 Dec 2007 10:48:09 +0100 Subject: [PATCH 10/35] gitweb: fix whitespace in config_to_multi (indent with tab) Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 28bb8c3933..6256641ace 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1511,7 +1511,7 @@ sub config_to_int { sub config_to_multi { my $val = shift; - return ref($val) ? $val : (defined($val) ? [ $val ] : []); + return ref($val) ? $val : (defined($val) ? [ $val ] : []); } sub git_get_project_config { From d2f82950a9226ae1102a7a97f03440a4bf8c6c09 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 20 Dec 2007 20:22:46 -0800 Subject: [PATCH 11/35] Re(-re)*fix trim_common_tail() The tar-ball and the git archive itself is fine, but yes, the diff from 2.6.23 to 2.6.24-rc6 is bad. It's the "trim_common_tail()" optimization that has caused way too much pain. Very interesting breakage. The patch was actually "correct" in a (rather limited) technical sense, but the context at the end was missing because while the trim_common_tail() code made sure to keep enough common context to allow a valid diff to be generated, the diff machinery itself could decide that it could generate the diff differently than the "obvious" solution. Thee sad fact is that the git optimization (which is very important for "git blame", which needs no context), is only really valid for that one case where we really don't need any context. [jc: since this is shared with "git diff -U0" codepath, context recovery to the end of line needs to be done even for zero context case.] Signed-off-by: Junio C Hamano --- xdiff-interface.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/xdiff-interface.c b/xdiff-interface.c index 9ee877c6f4..4b8e5cca80 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -115,17 +115,20 @@ static void trim_common_tail(mmfile_t *a, mmfile_t *b, long ctx) char *bp = b->ptr + b->size; long smaller = (a->size < b->size) ? a->size : b->size; + if (ctx) + return; + while (blk + trimmed <= smaller && !memcmp(ap - blk, bp - blk, blk)) { trimmed += blk; ap -= blk; bp -= blk; } - while (recovered < trimmed && 0 <= ctx) + while (recovered < trimmed) if (ap[recovered++] == '\n') - ctx--; - a->size -= (trimmed - recovered); - b->size -= (trimmed - recovered); + break; + a->size -= trimmed - recovered; + b->size -= trimmed - recovered; } int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *xecb) From 56c3eb173293d512fa85add94a7d0a3bfc6fe74a Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 21 Dec 2007 13:50:58 -0800 Subject: [PATCH 12/35] Documentation: ls-files -v is about "assume unchanged". And refer the reader to update-index documentation. Signed-off-by: Junio C Hamano --- Documentation/git-ls-files.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt index 2ec0c0d270..d0c3aa21d2 100644 --- a/Documentation/git-ls-files.txt +++ b/Documentation/git-ls-files.txt @@ -105,7 +105,8 @@ OPTIONS -v:: Similar to `-t`, but use lowercase letters for files - that are marked as 'always matching index'. + that are marked as 'assume unchanged' (see + gitlink:git-update-index[1]). --full-name:: When run from a subdirectory, the command usually From 78d776a9699cd3e3d368366afaa66dee97e53ac5 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Fri, 21 Dec 2007 11:50:58 +0100 Subject: [PATCH 13/35] git-tag: fix -l switch handling regression. The command itself takes an optional argument that limits the shown tags to the ones that match when in listing mode that is triggered with '-l' option. The is not an optional option-argument to '-l'. With this fix, "git tag -l -n 4 v0.99" works as expected. It also removes a few bogus tests in t7004. Signed-off-by: Pierre Habouzit Signed-off-by: Junio C Hamano --- builtin-tag.c | 12 +++++------- t/t7004-tag.sh | 8 -------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/builtin-tag.c b/builtin-tag.c index 274901a408..020ee1cb77 100644 --- a/builtin-tag.c +++ b/builtin-tag.c @@ -16,7 +16,7 @@ static const char * const git_tag_usage[] = { "git-tag [-a|-s|-u ] [-f] [-m |-F ] []", "git-tag -d ...", - "git-tag [-n []] -l []", + "git-tag -l [-n []] []", "git-tag -v ...", NULL }; @@ -370,13 +370,11 @@ int cmd_tag(int argc, const char **argv, const char *prefix) struct ref_lock *lock; int annotate = 0, sign = 0, force = 0, lines = 0, - delete = 0, verify = 0; - char *list = NULL, *msgfile = NULL, *keyid = NULL; - const char *no_pattern = "NO_PATTERN"; + list = 0, delete = 0, verify = 0; + char *msgfile = NULL, *keyid = NULL; struct msg_arg msg = { 0, STRBUF_INIT }; struct option options[] = { - { OPTION_STRING, 'l', NULL, &list, "pattern", "list tag names", - PARSE_OPT_OPTARG, NULL, (intptr_t) no_pattern }, + OPT_BOOLEAN('l', NULL, &list, "list tag names"), { OPTION_INTEGER, 'n', NULL, &lines, NULL, "print n lines of each tag message", PARSE_OPT_OPTARG, NULL, 1 }, @@ -408,7 +406,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) annotate = 1; if (list) - return list_tags(list == no_pattern ? NULL : list, lines); + return list_tags(argv[0], lines); if (delete) return for_each_tag_name(argv, delete_tag); if (verify) diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 09d56e0839..6f41ce3a77 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -497,10 +497,6 @@ test_expect_success \ git diff expect actual && echo "tag-one-line A msg" >expect && - git-tag -n xxx -l | grep "^tag-one-line" >actual && - git diff expect actual && - git-tag -n "" -l | grep "^tag-one-line" >actual && - git diff expect actual && git-tag -n 1 -l | grep "^tag-one-line" >actual && git diff expect actual && git-tag -n -l | grep "^tag-one-line" >actual && @@ -912,10 +908,6 @@ test_expect_success \ git diff expect actual && echo "stag-one-line A message line signed" >expect && - git-tag -n xxx -l | grep "^stag-one-line" >actual && - git diff expect actual && - git-tag -n "" -l | grep "^stag-one-line" >actual && - git diff expect actual && git-tag -n 1 -l | grep "^stag-one-line" >actual && git diff expect actual && git-tag -n -l | grep "^stag-one-line" >actual && From 0e0278baad8752da6c3b37495f005dc1dd6f799a Mon Sep 17 00:00:00 2001 From: Gustaf Hendeby Date: Sat, 22 Dec 2007 01:40:52 +0100 Subject: [PATCH 14/35] Make git send-email accept $EDITOR with arguments Currently git send-email does not accept $EDITOR with arguments, eg, emacs -nw, when starting an editor to produce a cover letter. This patch changes this by letting the shell handle the option parsing. Signed-off-by: Gustaf Hendeby Signed-off-by: Junio C Hamano --- git-send-email.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-send-email.perl b/git-send-email.perl index 248d035088..e47994afc4 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -400,7 +400,7 @@ EOT close(C); my $editor = $ENV{GIT_EDITOR} || $repo->config("core.editor") || $ENV{VISUAL} || $ENV{EDITOR} || "vi"; - system($editor, $compose_filename); + system('sh', '-c', '$0 $@', $editor, $compose_filename); open(C2,">",$compose_filename . ".final") or die "Failed to open $compose_filename.final : " . $!; From 77190eb9b881118b78383a483973a85fe79cbf70 Mon Sep 17 00:00:00 2001 From: Stefan Sperling Date: Fri, 21 Dec 2007 16:57:26 +0100 Subject: [PATCH 15/35] Small comment fix for git-cvsimport. Signed-off-by: Stefan Sperling Signed-off-by: Junio C Hamano --- git-cvsimport.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 92648f40c9..1fa9a22376 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -848,7 +848,7 @@ while () { } if (!$opt_a && $starttime - 300 - (defined $opt_z ? $opt_z : 300) <= $date) { # skip if the commit is too recent - # that the cvsps default fuzz is 300s, we give ourselves another + # given that the cvsps default fuzz is 300s, we give ourselves another # 300s just in case -- this also prevents skipping commits # due to server clock drift print "skip patchset $patchset: $date too recent\n" if $opt_v; From 5e2de4f9bb666186e4f8ba0c9c5db640fd7a04bd Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 22 Dec 2007 09:45:10 -0800 Subject: [PATCH 16/35] Fix $EDITOR regression introduced by rewrite in C. When git-tag and git-commit launches the editor, they used to honor EDITOR="editor -options args..." but recent rewrite in C insisted on $EDITOR to be the path to the editor executable. This restores the older behaviour. Signed-off-by: Junio C Hamano --- builtin-tag.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/builtin-tag.c b/builtin-tag.c index 020ee1cb77..03e70155fc 100644 --- a/builtin-tag.c +++ b/builtin-tag.c @@ -47,7 +47,19 @@ void launch_editor(const char *path, struct strbuf *buffer, const char *const *e editor = "vi"; if (strcmp(editor, ":")) { - const char *args[] = { editor, path, NULL }; + size_t len = strlen(editor); + int i = 0; + const char *args[6]; + + if (strcspn(editor, "$ \t'") != len) { + /* there are specials */ + args[i++] = "sh"; + args[i++] = "-c"; + args[i++] = "$0 \"$@\""; + } + args[i++] = editor; + args[i++] = path; + args[i] = NULL; if (run_command_v_opt_cd_env(args, 0, NULL, env)) die("There was a problem with the editor %s.", editor); From c43a24834a9babd3ddd9c27ccc81174c2cb36859 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Fri, 21 Dec 2007 11:41:41 +0100 Subject: [PATCH 17/35] Force the sticked form for options with optional arguments. This forbids "git tag -n -l" we allowed earlier, so adjust t7004 while at it. Signed-off-by: Pierre Habouzit --- parse-options.c | 6 ++-- t/t7004-tag.sh | 96 ++++++++++++++++++++++++------------------------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/parse-options.c b/parse-options.c index e12b428c0a..7a08a0c64f 100644 --- a/parse-options.c +++ b/parse-options.c @@ -89,7 +89,7 @@ static int get_value(struct optparse_t *p, *(const char **)opt->value = NULL; return 0; } - if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-')) { + if (opt->flags & PARSE_OPT_OPTARG && !p->opt) { *(const char **)opt->value = (const char *)opt->defval; return 0; } @@ -103,7 +103,7 @@ static int get_value(struct optparse_t *p, return (*opt->callback)(opt, NULL, 1); if (opt->flags & PARSE_OPT_NOARG) return (*opt->callback)(opt, NULL, 0); - if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-')) + if (opt->flags & PARSE_OPT_OPTARG && !p->opt) return (*opt->callback)(opt, NULL, 0); if (!arg) return opterror(opt, "requires a value", flags); @@ -114,7 +114,7 @@ static int get_value(struct optparse_t *p, *(int *)opt->value = 0; return 0; } - if (opt->flags & PARSE_OPT_OPTARG && (!arg || !isdigit(*arg))) { + if (opt->flags & PARSE_OPT_OPTARG && !p->opt) { *(int *)opt->value = opt->defval; return 0; } diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 6f41ce3a77..df496a95ff 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -491,21 +491,21 @@ test_expect_success \ echo "tag-one-line" >expect && git-tag -l | grep "^tag-one-line" >actual && git diff expect actual && - git-tag -n 0 -l | grep "^tag-one-line" >actual && + git-tag -n0 -l | grep "^tag-one-line" >actual && git diff expect actual && - git-tag -n 0 -l tag-one-line >actual && + git-tag -n0 -l tag-one-line >actual && git diff expect actual && echo "tag-one-line A msg" >expect && - git-tag -n 1 -l | grep "^tag-one-line" >actual && + git-tag -n1 -l | grep "^tag-one-line" >actual && git diff expect actual && git-tag -n -l | grep "^tag-one-line" >actual && git diff expect actual && - git-tag -n 1 -l tag-one-line >actual && + git-tag -n1 -l tag-one-line >actual && git diff expect actual && - git-tag -n 2 -l tag-one-line >actual && + git-tag -n2 -l tag-one-line >actual && git diff expect actual && - git-tag -n 999 -l tag-one-line >actual && + git-tag -n999 -l tag-one-line >actual && git diff expect actual ' @@ -516,21 +516,21 @@ test_expect_success \ echo "tag-zero-lines" >expect && git-tag -l | grep "^tag-zero-lines" >actual && git diff expect actual && - git-tag -n 0 -l | grep "^tag-zero-lines" >actual && + git-tag -n0 -l | grep "^tag-zero-lines" >actual && git diff expect actual && - git-tag -n 0 -l tag-zero-lines >actual && + git-tag -n0 -l tag-zero-lines >actual && git diff expect actual && echo "tag-zero-lines " >expect && - git-tag -n 1 -l | grep "^tag-zero-lines" >actual && + git-tag -n1 -l | grep "^tag-zero-lines" >actual && git diff expect actual && git-tag -n -l | grep "^tag-zero-lines" >actual && git diff expect actual && - git-tag -n 1 -l tag-zero-lines >actual && + git-tag -n1 -l tag-zero-lines >actual && git diff expect actual && - git-tag -n 2 -l tag-zero-lines >actual && + git-tag -n2 -l tag-zero-lines >actual && git diff expect actual && - git-tag -n 999 -l tag-zero-lines >actual && + git-tag -n999 -l tag-zero-lines >actual && git diff expect actual ' @@ -544,37 +544,37 @@ test_expect_success \ echo "tag-lines" >expect && git-tag -l | grep "^tag-lines" >actual && git diff expect actual && - git-tag -n 0 -l | grep "^tag-lines" >actual && + git-tag -n0 -l | grep "^tag-lines" >actual && git diff expect actual && - git-tag -n 0 -l tag-lines >actual && + git-tag -n0 -l tag-lines >actual && git diff expect actual && echo "tag-lines tag line one" >expect && - git-tag -n 1 -l | grep "^tag-lines" >actual && + git-tag -n1 -l | grep "^tag-lines" >actual && git diff expect actual && git-tag -n -l | grep "^tag-lines" >actual && git diff expect actual && - git-tag -n 1 -l tag-lines >actual && + git-tag -n1 -l tag-lines >actual && git diff expect actual && echo " tag line two" >>expect && - git-tag -n 2 -l | grep "^ *tag.line" >actual && + git-tag -n2 -l | grep "^ *tag.line" >actual && git diff expect actual && - git-tag -n 2 -l tag-lines >actual && + git-tag -n2 -l tag-lines >actual && git diff expect actual && echo " tag line three" >>expect && - git-tag -n 3 -l | grep "^ *tag.line" >actual && + git-tag -n3 -l | grep "^ *tag.line" >actual && git diff expect actual && - git-tag -n 3 -l tag-lines >actual && + git-tag -n3 -l tag-lines >actual && git diff expect actual && - git-tag -n 4 -l | grep "^ *tag.line" >actual && + git-tag -n4 -l | grep "^ *tag.line" >actual && git diff expect actual && - git-tag -n 4 -l tag-lines >actual && + git-tag -n4 -l tag-lines >actual && git diff expect actual && - git-tag -n 99 -l | grep "^ *tag.line" >actual && + git-tag -n99 -l | grep "^ *tag.line" >actual && git diff expect actual && - git-tag -n 99 -l tag-lines >actual && + git-tag -n99 -l tag-lines >actual && git diff expect actual ' @@ -902,21 +902,21 @@ test_expect_success \ echo "stag-one-line" >expect && git-tag -l | grep "^stag-one-line" >actual && git diff expect actual && - git-tag -n 0 -l | grep "^stag-one-line" >actual && + git-tag -n0 -l | grep "^stag-one-line" >actual && git diff expect actual && - git-tag -n 0 -l stag-one-line >actual && + git-tag -n0 -l stag-one-line >actual && git diff expect actual && echo "stag-one-line A message line signed" >expect && - git-tag -n 1 -l | grep "^stag-one-line" >actual && + git-tag -n1 -l | grep "^stag-one-line" >actual && git diff expect actual && git-tag -n -l | grep "^stag-one-line" >actual && git diff expect actual && - git-tag -n 1 -l stag-one-line >actual && + git-tag -n1 -l stag-one-line >actual && git diff expect actual && - git-tag -n 2 -l stag-one-line >actual && + git-tag -n2 -l stag-one-line >actual && git diff expect actual && - git-tag -n 999 -l stag-one-line >actual && + git-tag -n999 -l stag-one-line >actual && git diff expect actual ' @@ -927,21 +927,21 @@ test_expect_success \ echo "stag-zero-lines" >expect && git-tag -l | grep "^stag-zero-lines" >actual && git diff expect actual && - git-tag -n 0 -l | grep "^stag-zero-lines" >actual && + git-tag -n0 -l | grep "^stag-zero-lines" >actual && git diff expect actual && - git-tag -n 0 -l stag-zero-lines >actual && + git-tag -n0 -l stag-zero-lines >actual && git diff expect actual && echo "stag-zero-lines " >expect && - git-tag -n 1 -l | grep "^stag-zero-lines" >actual && + git-tag -n1 -l | grep "^stag-zero-lines" >actual && git diff expect actual && git-tag -n -l | grep "^stag-zero-lines" >actual && git diff expect actual && - git-tag -n 1 -l stag-zero-lines >actual && + git-tag -n1 -l stag-zero-lines >actual && git diff expect actual && - git-tag -n 2 -l stag-zero-lines >actual && + git-tag -n2 -l stag-zero-lines >actual && git diff expect actual && - git-tag -n 999 -l stag-zero-lines >actual && + git-tag -n999 -l stag-zero-lines >actual && git diff expect actual ' @@ -955,37 +955,37 @@ test_expect_success \ echo "stag-lines" >expect && git-tag -l | grep "^stag-lines" >actual && git diff expect actual && - git-tag -n 0 -l | grep "^stag-lines" >actual && + git-tag -n0 -l | grep "^stag-lines" >actual && git diff expect actual && - git-tag -n 0 -l stag-lines >actual && + git-tag -n0 -l stag-lines >actual && git diff expect actual && echo "stag-lines stag line one" >expect && - git-tag -n 1 -l | grep "^stag-lines" >actual && + git-tag -n1 -l | grep "^stag-lines" >actual && git diff expect actual && git-tag -n -l | grep "^stag-lines" >actual && git diff expect actual && - git-tag -n 1 -l stag-lines >actual && + git-tag -n1 -l stag-lines >actual && git diff expect actual && echo " stag line two" >>expect && - git-tag -n 2 -l | grep "^ *stag.line" >actual && + git-tag -n2 -l | grep "^ *stag.line" >actual && git diff expect actual && - git-tag -n 2 -l stag-lines >actual && + git-tag -n2 -l stag-lines >actual && git diff expect actual && echo " stag line three" >>expect && - git-tag -n 3 -l | grep "^ *stag.line" >actual && + git-tag -n3 -l | grep "^ *stag.line" >actual && git diff expect actual && - git-tag -n 3 -l stag-lines >actual && + git-tag -n3 -l stag-lines >actual && git diff expect actual && - git-tag -n 4 -l | grep "^ *stag.line" >actual && + git-tag -n4 -l | grep "^ *stag.line" >actual && git diff expect actual && - git-tag -n 4 -l stag-lines >actual && + git-tag -n4 -l stag-lines >actual && git diff expect actual && - git-tag -n 99 -l | grep "^ *stag.line" >actual && + git-tag -n99 -l | grep "^ *stag.line" >actual && git diff expect actual && - git-tag -n 99 -l stag-lines >actual && + git-tag -n99 -l stag-lines >actual && git diff expect actual ' From 2f7ee089dff6e9225dbfca2bdd23efe93e1c0740 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Thu, 13 Dec 2007 11:20:01 +0100 Subject: [PATCH 18/35] parse-options: Add a gitcli(5) man page. This page should hold every information about the git ways to parse command lines, and best practices to be used for scripting. Signed-off-by: Pierre Habouzit --- Documentation/Makefile | 2 +- Documentation/gitcli.txt | 113 +++++++++++++++++++++++++++++++++++++++ Makefile | 1 + 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 Documentation/gitcli.txt diff --git a/Documentation/Makefile b/Documentation/Makefile index 76df06cd61..c4486d3d47 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -2,7 +2,7 @@ MAN1_TXT= \ $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \ $(wildcard git-*.txt)) \ gitk.txt -MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt +MAN5_TXT=gitattributes.txt gitignore.txt gitcli.txt gitmodules.txt MAN7_TXT=git.txt MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT) diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt new file mode 100644 index 0000000000..b7dcf9ca10 --- /dev/null +++ b/Documentation/gitcli.txt @@ -0,0 +1,113 @@ +gitcli(5) +========= + +NAME +---- +gitcli - git command line interface and conventions + +SYNOPSIS +-------- +gitcli + + +DESCRIPTION +----------- + +This manual describes best practice in how to use git CLI. Here are +the rules that you should follow when you are scripting git: + + * it's preferred to use the non dashed form of git commands, which means that + you should prefer `"git foo"` to `"git-foo"`. + + * splitting short options to separate words (prefer `"git foo -a -b"` + to `"git foo -ab"`, the latter may not even work). + + * when a command line option takes an argument, use the 'sticked' form. In + other words, write `"git foo -oArg"` instead of `"git foo -o Arg"` for short + options, and `"git foo --long-opt=Arg"` instead of `"git foo --long-opt Arg"` + for long options. An option that takes optional option-argument must be + written in the 'sticked' form. + + * when you give a revision parameter to a command, make sure the parameter is + not ambiguous with a name of a file in the work tree. E.g. do not write + `"git log -1 HEAD"` but write `"git log -1 HEAD --"`; the former will not work + if you happen to have a file called `HEAD` in the work tree. + + +ENHANCED CLI +------------ +From the git 1.5.4 series and further, many git commands (not all of them at the +time of the writing though) come with an enhanced option parser. + +Here is an exhaustive list of the facilities provided by this option parser. + + +Magic Options +~~~~~~~~~~~~~ +Commands which have the enhanced option parser activated all understand a +couple of magic command line options: + +-h:: + gives a pretty printed usage of the command. ++ +--------------------------------------------- +$ git describe -h +usage: git-describe [options] * + + --contains find the tag that comes after the commit + --debug debug search strategy on stderr + --all use any ref in .git/refs + --tags use any tag in .git/refs/tags + --abbrev [] use digits to display SHA-1s + --candidates consider most recent tags (default: 10) +--------------------------------------------- + +--help-all:: + Some git commands take options that are only used for plumbing or that + are deprecated, and such options are hidden from the default usage. This + option gives the full list of options. + + +Negating options +~~~~~~~~~~~~~~~~ +Options with long option names can be negated by prefixing `"--no-"`. For +example, `"git branch"` has the option `"--track"` which is 'on' by default. You +can use `"--no-track"` to override that behaviour. The same goes for `"--color"` +and `"--no-color"`. + + +Aggregating short options +~~~~~~~~~~~~~~~~~~~~~~~~~ +Commands that support the enhanced option parser allow you to aggregate short +options. This means that you can for example use `"git rm -rf"` or +`"git clean -fdx"`. + + +Separating argument from the option +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You can write the mandatory option parameter to an option as a separate +word on the command line. That means that all the following uses work: + +---------------------------- +$ git foo --long-opt=Arg +$ git foo --long-opt Arg +$ git foo -oArg +$ git foo -o Arg +---------------------------- + +However, this is *NOT* allowed for switches with an optionnal value, where the +'sticked' form must be used: +---------------------------- +$ git describe --abbrev HEAD # correct +$ git describe --abbrev=10 HEAD # correct +$ git describe --abbrev 10 HEAD # NOT WHAT YOU MEANT +---------------------------- + + +Documentation +------------- +Documentation by Pierre Habouzit. + +GIT +--- +Part of the gitlink:git[7] suite diff --git a/Makefile b/Makefile index d6d3d65b1b..21c80e6bf7 100644 --- a/Makefile +++ b/Makefile @@ -1173,6 +1173,7 @@ check-docs:: documented,gitattributes | \ documented,gitignore | \ documented,gitmodules | \ + documented,gitcli | \ documented,git-tools | \ sentinel,not,matching,is,ok ) continue ;; \ esac; \ From 97bc00a4909fb73eba8a05dc89fe7914d7123245 Mon Sep 17 00:00:00 2001 From: Wincent Colaiuta Date: Sat, 22 Dec 2007 18:31:25 +0100 Subject: [PATCH 19/35] Emit helpful status for accidental "git stash" save If the user types "git stash" mistakenly thinking that this will list their stashes he/she may be surprised to see that it actually saved a new stash and reset their working tree and index. In the worst case they might not know how to recover the state. So help them by telling them exactly what was saved and also how to restore it immediately. Signed-off-by: Wincent Colaiuta Signed-off-by: Junio C Hamano --- git-stash.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/git-stash.sh b/git-stash.sh index f16fd9c3c0..06cb177ec6 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -99,7 +99,7 @@ save_stash () { git update-ref -m "$stash_msg" $ref_stash $w_commit || die "Cannot save the current status" - printf >&2 'Saved "%s"\n' "$stash_msg" + printf >&2 'Saved working directory and index state "%s"\n' "$stash_msg" } have_stash () { @@ -228,7 +228,9 @@ create) *) if test $# -eq 0 then - save_stash && git-reset --hard + save_stash && + echo >&2 '(To restore them type "git stash apply")' && + git-reset --hard else usage fi From cc216827936e40bc2e8886623fd44f55e0674932 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Fri, 21 Dec 2007 11:56:32 +0100 Subject: [PATCH 20/35] Don't dereference NULL upon lookup failure. Instead, signal the error just like the case we do upon encountering an object with an unknown type. Signed-off-by: Jim Meyering Signed-off-by: Junio C Hamano --- object.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/object.c b/object.c index 16793d9958..5a5ebe27b0 100644 --- a/object.c +++ b/object.c @@ -136,29 +136,38 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t struct object *obj; int eaten = 0; + obj = NULL; if (type == OBJ_BLOB) { struct blob *blob = lookup_blob(sha1); - parse_blob_buffer(blob, buffer, size); - obj = &blob->object; + if (blob) { + parse_blob_buffer(blob, buffer, size); + obj = &blob->object; + } } else if (type == OBJ_TREE) { struct tree *tree = lookup_tree(sha1); - obj = &tree->object; - if (!tree->object.parsed) { - parse_tree_buffer(tree, buffer, size); - eaten = 1; + if (tree) { + obj = &tree->object; + if (!tree->object.parsed) { + parse_tree_buffer(tree, buffer, size); + eaten = 1; + } } } else if (type == OBJ_COMMIT) { struct commit *commit = lookup_commit(sha1); - parse_commit_buffer(commit, buffer, size); - if (!commit->buffer) { - commit->buffer = buffer; - eaten = 1; + if (commit) { + parse_commit_buffer(commit, buffer, size); + if (!commit->buffer) { + commit->buffer = buffer; + eaten = 1; + } + obj = &commit->object; } - obj = &commit->object; } else if (type == OBJ_TAG) { struct tag *tag = lookup_tag(sha1); - parse_tag_buffer(tag, buffer, size); - obj = &tag->object; + if (tag) { + parse_tag_buffer(tag, buffer, size); + obj = &tag->object; + } } else { warning("object %s has unknown type id %d\n", sha1_to_hex(sha1), type); obj = NULL; From 7263881253acc4c3af8b3131c60da1554b72f8b2 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 22 Dec 2007 19:14:33 -0800 Subject: [PATCH 21/35] t7005: do not exit inside test. The way to signal failure is to leave non-zero in $?, not abort the entire test. Signed-off-by: Junio C Hamano --- t/t7005-editor.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh index 44228b5ac1..c1cec55306 100755 --- a/t/t7005-editor.sh +++ b/t/t7005-editor.sh @@ -37,7 +37,7 @@ test_expect_success 'dumb should error out when falling back on vi' ' if git commit --amend then echo "Oops?" - exit 1 + false else : happy fi From d616a2396456fdb6679efa0c0bee301aeb606ca8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 22 Dec 2007 19:22:29 -0800 Subject: [PATCH 22/35] builtin-commit: fix amending of the initial commit When amending initial commit without editor, the command incorrectly barfed because the check to see if there is anything to commit referenced the non-existent HEAD^1. Signed-off-by: Junio C Hamano --- builtin-commit.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/builtin-commit.c b/builtin-commit.c index 96410de55d..eebd4cf066 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -374,7 +374,7 @@ static int prepare_log_message(const char *index_file, const char *prefix) if (no_edit) { struct rev_info rev; - unsigned char sha1[40]; + unsigned char sha1[20]; const char *parent = "HEAD"; fclose(fp); @@ -382,12 +382,12 @@ static int prepare_log_message(const char *index_file, const char *prefix) if (!active_nr && read_cache() < 0) die("Cannot read index"); - if (get_sha1("HEAD", sha1) != 0) - return !!active_nr; - if (amend) parent = "HEAD^1"; + if (get_sha1(parent, sha1)) + return !!active_nr; + init_revisions(&rev, ""); rev.abbrev = 0; setup_revisions(0, NULL, &rev, parent); From 4803466f62777fe3d0b33c8f999ec392f47a5b09 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 22 Dec 2007 19:25:37 -0800 Subject: [PATCH 23/35] builtin-commit: avoid double-negation in the code. The flag no_edit meant "we have got final message from the user and will not editing it any further", but there were quite a few places that needed to check !no_edit. Rename the variable to use_editor and reverse the logic everywhere. Signed-off-by: Junio C Hamano --- builtin-commit.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/builtin-commit.c b/builtin-commit.c index eebd4cf066..1d544cbe35 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -48,7 +48,7 @@ static char *edit_message, *use_message; static int all, edit_flag, also, interactive, only, amend, signoff; static int quiet, verbose, untracked_files, no_verify, allow_empty; -static int no_edit, initial_commit, in_merge; +static int use_editor = 1, initial_commit, in_merge; const char *only_include_assumed; struct strbuf message; @@ -372,7 +372,7 @@ static int prepare_log_message(const char *index_file, const char *prefix) strbuf_release(&sb); - if (no_edit) { + if (!use_editor) { struct rev_info rev; unsigned char sha1[20]; const char *parent = "HEAD"; @@ -398,7 +398,7 @@ static int prepare_log_message(const char *index_file, const char *prefix) return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES); } - if (in_merge && !no_edit) + if (in_merge) fprintf(fp, "#\n" "# It looks like you may be committing a MERGE.\n" @@ -513,9 +513,9 @@ static int parse_and_validate_options(int argc, const char *argv[], argc = parse_options(argc, argv, builtin_commit_options, usage, 0); if (logfile || message.len || use_message) - no_edit = 1; + use_editor = 0; if (edit_flag) - no_edit = 0; + use_editor = 1; if (get_sha1("HEAD", head_sha1)) initial_commit = 1; @@ -796,7 +796,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) /* Get the commit message and validate it */ header_len = sb.len; - if (!no_edit) { + if (use_editor) { char index[PATH_MAX]; const char *env[2] = { index, NULL }; snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); From 5f0657374344a5d8cf5ce5a9920a08c0be422194 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Sat, 22 Dec 2007 19:46:24 +0100 Subject: [PATCH 24/35] Allow selection of different cleanup modes for commit messages Although we traditionally stripped away excess blank lines, trailing whitespaces and lines that begin with "#" from the commit log message, sometimes the message just has to be the way user wants it. For instance, a commit message template can contain lines that begin with "#", the message must be kept as close to its original source as possible if you are converting from a foreign SCM, or maybe the message has a shell script including its comments for future reference. The cleanup modes are default, verbatim, whitespace and strip. The default mode depends on if the message is being edited and will either strip whitespace and comments (if editor active) or just strip the whitespace (for where the message is given explicitely). Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- Documentation/git-commit.txt | 12 ++++++- builtin-commit.c | 42 ++++++++++++++++++++--- t/t7502-commit.sh | 65 ++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 5 deletions(-) diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 4261384158..96383b6543 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -11,7 +11,7 @@ SYNOPSIS 'git-commit' [-a | --interactive] [-s] [-v] [-u] [(-c | -C) | -F | -m | --amend] [--allow-empty] [--no-verify] [-e] [--author ] - [--] [[-i | -o ]...] + [--cleanup=] [--] [[-i | -o ]...] DESCRIPTION ----------- @@ -95,6 +95,16 @@ OPTIONS from making such a commit. This option bypasses the safety, and is primarily for use by foreign scm interface scripts. +--cleanup=:: + This option sets how the commit message is cleaned up. + The '' can be one of 'verbatim', 'whitespace', 'strip', + and 'default'. The 'default' mode will strip leading and + trailing empty lines and #commentary from the commit message + only if the message is to be edited. Otherwise only whitespace + removed. The 'verbatim' mode does not change message at all, + 'whitespace' removes just leading/trailing whitespace lines + and 'strip' removes both whitespace and commentary. + -e|--edit:: The message taken from file with `-F`, command line with `-m`, and from file with `-C` are usually used as the diff --git a/builtin-commit.c b/builtin-commit.c index 1d544cbe35..73f1e3576a 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -47,6 +47,19 @@ static char *logfile, *force_author, *template_file; static char *edit_message, *use_message; static int all, edit_flag, also, interactive, only, amend, signoff; static int quiet, verbose, untracked_files, no_verify, allow_empty; +/* + * The default commit message cleanup mode will remove the lines + * beginning with # (shell comments) and leading and trailing + * whitespaces (empty lines or containing only whitespaces) + * if editor is used, and only the whitespaces if the message + * is specified explicitly. + */ +static enum { + CLEANUP_SPACE, + CLEANUP_NONE, + CLEANUP_ALL, +} cleanup_mode; +static char *cleanup_arg; static int use_editor = 1, initial_commit, in_merge; const char *only_include_assumed; @@ -88,6 +101,7 @@ static struct option builtin_commit_options[] = { OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"), OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"), OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"), + OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"), OPT_END() }; @@ -346,7 +360,8 @@ static int prepare_log_message(const char *index_file, const char *prefix) if (fp == NULL) die("could not open %s", git_path(commit_editmsg)); - stripspace(&sb, 0); + if (cleanup_mode != CLEANUP_NONE) + stripspace(&sb, 0); if (signoff) { struct strbuf sob; @@ -411,7 +426,12 @@ static int prepare_log_message(const char *index_file, const char *prefix) fprintf(fp, "\n" "# Please enter the commit message for your changes.\n" - "# (Comment lines starting with '#' will not be included)\n"); + "# (Comment lines starting with '#' will "); + if (cleanup_mode == CLEANUP_ALL) + fprintf(fp, "not be included)\n"); + else /* CLEANUP_SPACE, that is. */ + fprintf(fp, "be kept.\n" + "# You can remove them yourself if you want to)\n"); if (only_include_assumed) fprintf(fp, "# %s\n", only_include_assumed); @@ -435,10 +455,13 @@ static int message_is_empty(struct strbuf *sb, int start) const char *nl; int eol, i; + if (cleanup_mode == CLEANUP_NONE && sb->len) + return 0; + /* See if the template is just a prefix of the message. */ strbuf_init(&tmpl, 0); if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) { - stripspace(&tmpl, 1); + stripspace(&tmpl, cleanup_mode == CLEANUP_ALL); if (start + tmpl.len <= sb->len && memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0) start += tmpl.len; @@ -591,6 +614,16 @@ static int parse_and_validate_options(int argc, const char *argv[], only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths..."; also = 0; } + if (!cleanup_arg || !strcmp(cleanup_arg, "default")) + cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE; + else if (!strcmp(cleanup_arg, "verbatim")) + cleanup_mode = CLEANUP_NONE; + else if (!strcmp(cleanup_arg, "whitespace")) + cleanup_mode = CLEANUP_SPACE; + else if (!strcmp(cleanup_arg, "strip")) + cleanup_mode = CLEANUP_ALL; + else + die("Invalid cleanup mode %s", cleanup_arg); if (all && argc > 0) die("Paths with -a does not make sense."); @@ -817,7 +850,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) if (p != NULL) strbuf_setlen(&sb, p - sb.buf + 1); - stripspace(&sb, 1); + if (cleanup_mode != CLEANUP_NONE) + stripspace(&sb, cleanup_mode == CLEANUP_ALL); if (sb.len < header_len || message_is_empty(&sb, header_len)) { rollback_index_files(); die("no commit message? aborting commit."); diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index 21ac785e3d..aaf497e6a5 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -89,4 +89,69 @@ test_expect_success 'verbose' ' ' +test_expect_success 'cleanup commit messages (verbatim,-t)' ' + + echo >>negative && + { echo;echo "# text";echo; } >expect && + git commit --cleanup=verbatim -t expect -a && + git cat-file -p HEAD |sed -e "1,/^\$/d" |head -n 3 >actual && + diff -u expect actual + +' + +test_expect_success 'cleanup commit messages (verbatim,-F)' ' + + echo >>negative && + git commit --cleanup=verbatim -F expect -a && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + diff -u expect actual + +' + +test_expect_success 'cleanup commit messages (verbatim,-m)' ' + + echo >>negative && + git commit --cleanup=verbatim -m "$(cat expect)" -a && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + diff -u expect actual + +' + +test_expect_success 'cleanup commit messages (whitespace,-F)' ' + + echo >>negative && + { echo;echo "# text";echo; } >text && + echo "# text" >expect && + git commit --cleanup=whitespace -F text -a && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + diff -u expect actual + +' + +test_expect_success 'cleanup commit messages (strip,-F)' ' + + echo >>negative && + { echo;echo "# text";echo sample;echo; } >text && + echo sample >expect && + git commit --cleanup=strip -F text -a && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + diff -u expect actual + +' + +echo "sample + +# Please enter the commit message for your changes. +# (Comment lines starting with '#' will not be included)" >expect + +test_expect_success 'cleanup commit messages (strip,-F,-e)' ' + + echo >>negative && + { echo;echo sample;echo; } >text && + git commit -e -F text -a && + head -n 4 .git/COMMIT_EDITMSG >actual && + diff -u expect actual + +' + test_done From 0e545f75169e2c260dfb4445203c23cafdfc76ef Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 22 Dec 2007 23:14:59 -0800 Subject: [PATCH 25/35] Documentation: describe 'union' low-level merge driver Signed-off-by: Junio C Hamano --- Documentation/git-check-attr.txt | 5 +++++ Documentation/git-merge.txt | 3 ++- Documentation/gitattributes.txt | 37 +++++++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt index 856d2af2ed..47cb1bdfa3 100644 --- a/Documentation/git-check-attr.txt +++ b/Documentation/git-check-attr.txt @@ -23,6 +23,11 @@ OPTIONS be treated as an attribute. +SEE ALSO +-------- +gitlink:gitattributes[5]. + + Author ------ Written by Junio C Hamano diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index eabd7ef33f..1521a9ee0f 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -163,7 +163,8 @@ After seeing a conflict, you can do two things: SEE ALSO -------- -gitlink:git-fmt-merge-msg[1], gitlink:git-pull[1] +gitlink:git-fmt-merge-msg[1], gitlink:git-pull[1], +gitlink:gitattributes[5] Author diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 71c7ad76d5..cc9c7c52c0 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -322,12 +322,43 @@ String:: requested with "binary". +Built-in merge drivers +^^^^^^^^^^^^^^^^^^^^^^ + +There are a few built-in low-level merge drivers defined that +can be asked for via the `merge` attribute. + +text:: + + Usual 3-way file level merge for text files. Conflicted + regions are marked with conflict markers `<<<<<<<`, + `=======` and `>>>>>>>`. The version from your branch + appears before the `=======` marker, and the version + from the merged branch appears after the `=======` + marker. + +binary:: + + Keep the version from your branch in the work tree, but + leave the path in the conflicted state for the user to + sort out. + +union:: + + Run 3-way file level merge for text files, but take + lines from both versions, instead of leaving conflict + markers. This tends to leave the added lines in the + resulting file in random order and the user should + verify the result. Do not use this if you do not + understand the implications. + + Defining a custom merge driver ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The definition of a merge driver is done in `gitconfig` not -`gitattributes` file, so strictly speaking this manual page is a -wrong place to talk about it. However... +The definition of a merge driver is done in the `.git/config` +file, not in the `gitattributes` file, so strictly speaking this +manual page is a wrong place to talk about it. However... To define a custom merge driver `filfre`, add a section to your `$GIT_DIR/config` file (or `$HOME/.gitconfig` file) like this: From ba4c32bdd506841c3f73cdfce5e9fb6760afd02c Mon Sep 17 00:00:00 2001 From: Gustaf Hendeby Date: Sun, 23 Dec 2007 10:37:01 -0800 Subject: [PATCH 26/35] shortlog manpage documentation: work around asciidoc markup issues We wanted to have a list in which one (and the sole, as it happen to be) item in it is ".mailmap", but do not seem to be able to convince AsciiDoc to format it correctly for manpages. Reformat it into a paragraph that describes the said file to work around the issue. Signed-off-by: Gustaf Hendeby Acked-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/git-shortlog.txt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt index e14720b73f..36510a8451 100644 --- a/Documentation/git-shortlog.txt +++ b/Documentation/git-shortlog.txt @@ -38,15 +38,16 @@ OPTIONS FILES ----- -.mailmap:: - If this file exists, it will be used for mapping author email - addresses to a real author name. One mapping per line, first - the author name followed by the email address enclosed by - '<' and '>'. Use hash '#' for comments. Example: +If the file `.mailmap` exists, it will be used for mapping author +email addresses to a real author name. One mapping per line, first +the author name followed by the email address enclosed by +'<' and '>'. Use hash '#' for comments. Example: - # Keep alphabetized - Adam Morrow - Eve Jones +------------ +# Keep alphabetized +Adam Morrow +Eve Jones +------------ Author ------ From 3a969ef1d67e3b3a26c36cfbe94f6dba05d6dc69 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 23 Dec 2007 22:08:19 -0500 Subject: [PATCH 27/35] cvsimport: die on cvsps errors We were not previously checking the exit status of cvsps at all. If it exited before producing any useful output, we ended up with an empty import, which caused a spew of confusing error messages from other parts of git: $ git-cvsimport foo Initialized empty Git repository in ... some error from cvsps fatal: refs/heads/origin: not a valid SHA1 fatal: master: not a valid SHA1 warning: You appear to be on a branch yet to be born. warning: Forcing checkout of HEAD. fatal: just how do you expect me to merge 0 trees? checkout failed: 256 Now we get: $ git-cvsimport foo Initialized empty Git repository in ... some error from cvsps git-cvsimport: fatal: cvsps reported error Signed-off-by: Jeff King Acked-by: Martin Langhoff Signed-off-by: Junio C Hamano --- git-cvsimport.perl | 1 + 1 file changed, 1 insertion(+) diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 1fa9a22376..6d8ff93f5f 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -632,6 +632,7 @@ unless ($opt_P) { print $cvspsfh $_; } close CVSPS; + $? == 0 or die "git-cvsimport: fatal: cvsps reported error\n"; close $cvspsfh; } else { $cvspsfile = $opt_P; From c8deb5a14686c9c2d0ca1e8f42aec8ed44d16954 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 25 Dec 2007 02:18:05 -0500 Subject: [PATCH 28/35] Improve error messages when int/long cannot be parsed from config If a config file has become mildly corrupted due to a missing LF we may discover some other option joined up against the end of a numeric value. For example: [section] number = 1auto where the "auto" flag was meant to occur on the next line, below "number", but the missing LF has caused it to no longer be its own option. Instead the word "auto" is parsed as a 'unit factor' for the value of "number". Before this change we got the confusing error message: fatal: unknown unit: 'auto' which told us nothing about where the problem appeared. Now we get: fatal: bad config value for 'aninvalid.unit' which at least points the user in the right direction of where to search for the incorrectly formatted configuration file. Noticed by erikh on #git, which received the original error from a simple `git checkout -b` due to a midly corrupted config. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- config.c | 31 +++++++++++++++++++++---------- t/t1300-repo-config.sh | 17 +++++++++++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/config.c b/config.c index 9a5c5470cc..80db92990a 100644 --- a/config.c +++ b/config.c @@ -234,17 +234,23 @@ static int git_parse_file(config_fn_t fn) die("bad config file line %d in %s", config_linenr, config_file_name); } -static unsigned long get_unit_factor(const char *end) +static int parse_unit_factor(const char *end, unsigned long *val) { if (!*end) return 1; - else if (!strcasecmp(end, "k")) - return 1024; - else if (!strcasecmp(end, "m")) - return 1024 * 1024; - else if (!strcasecmp(end, "g")) - return 1024 * 1024 * 1024; - die("unknown unit: '%s'", end); + else if (!strcasecmp(end, "k")) { + *val *= 1024; + return 1; + } + else if (!strcasecmp(end, "m")) { + *val *= 1024 * 1024; + return 1; + } + else if (!strcasecmp(end, "g")) { + *val *= 1024 * 1024 * 1024; + return 1; + } + return 0; } int git_parse_long(const char *value, long *ret) @@ -252,7 +258,10 @@ int git_parse_long(const char *value, long *ret) if (value && *value) { char *end; long val = strtol(value, &end, 0); - *ret = val * get_unit_factor(end); + unsigned long factor = 1; + if (!parse_unit_factor(end, &factor)) + return 0; + *ret = val * factor; return 1; } return 0; @@ -263,7 +272,9 @@ int git_parse_ulong(const char *value, unsigned long *ret) if (value && *value) { char *end; unsigned long val = strtoul(value, &end, 0); - *ret = val * get_unit_factor(end); + if (!parse_unit_factor(end, &val)) + return 0; + *ret = val; return 1; } return 0; diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index e894629e7e..42eac2a7cb 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -448,6 +448,23 @@ test_expect_success numbers ' test z1048576 = "z$m" ' +cat > expect <actual + then + echo config should have failed + false + fi && + cmp actual expect +' + cat > expect << EOF true false From 0faf2da7e5ee5c2f472d8a7afaf8616101f34e80 Mon Sep 17 00:00:00 2001 From: Arjen Laarhoven Date: Tue, 25 Dec 2007 12:06:47 +0100 Subject: [PATCH 29/35] Fix "git log --diff-filter" bug In commit b7bb760d5ed4881422673d32f869d140221d3564 (Fix revision log diff setup, avoid unnecessary diff generation) an optimization was made to avoid unnecessary diff generation. This was partly fixed in 99516e35d096f41e7133cacde8fbed8ee9a3ecd0 (Fix embarrassing "git log --follow" bug). The '--diff-filter' option also needs the diff machinery in action. Signed-off-by: Arjen Laarhoven Signed-off-by: Junio C Hamano --- revision.c | 6 ++-- t/t4202-log.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100755 t/t4202-log.sh diff --git a/revision.c b/revision.c index 7e2f4f1eb5..6e85aaa3fb 100644 --- a/revision.c +++ b/revision.c @@ -1290,8 +1290,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch if (revs->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) revs->diff = 1; - /* Pickaxe and rename following needs diffs */ - if (revs->diffopt.pickaxe || DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) + /* Pickaxe, diff-filter and rename following need diffs */ + if (revs->diffopt.pickaxe || + revs->diffopt.filter || + DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES)) revs->diff = 1; if (revs->topo_order) diff --git a/t/t4202-log.sh b/t/t4202-log.sh new file mode 100755 index 0000000000..b53645417b --- /dev/null +++ b/t/t4202-log.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +test_description='git log' + +. ./test-lib.sh + +test_expect_success setup ' + + echo one >one && + git add one && + test_tick && + git commit -m initial && + + echo ichi >one && + git add one && + test_tick && + git commit -m second && + + mkdir a && + echo ni >a/two && + git add a/two && + test_tick && + git commit -m third && + + echo san >a/three && + git add a/three && + test_tick && + git commit -m fourth && + + git rm a/three && + test_tick && + git commit -m fifth + +' + +test_expect_success 'diff-filter=A' ' + + actual=$(git log --pretty="format:%s" --diff-filter=A HEAD) && + expect=$(echo fourth ; echo third ; echo initial) && + test "$actual" = "$expect" || { + echo Oops + echo "Actual: $actual" + false + } + +' + +test_expect_success 'diff-filter=M' ' + + actual=$(git log --pretty="format:%s" --diff-filter=M HEAD) && + expect=$(echo second) && + test "$actual" = "$expect" || { + echo Oops + echo "Actual: $actual" + false + } + +' + +test_expect_success 'diff-filter=D' ' + + actual=$(git log --pretty="format:%s" --diff-filter=D HEAD) && + expect=$(echo fifth) && + test "$actual" = "$expect" || { + echo Oops + echo "Actual: $actual" + false + } + +' + + + +test_done \ No newline at end of file From 25db465a34ab6fe840011e5d746701186e9e9884 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 26 Dec 2007 16:04:05 -0800 Subject: [PATCH 30/35] Fix documentation of --first-parent in git-log and copy it to git-rev-list Credit goes to Avi Kivity for noticing the lack of description in rev-list manual page. Signed-off-by: Junio C Hamano --- Documentation/git-log.txt | 8 ++++++-- Documentation/git-rev-list.txt | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 5920d1799a..d71e51ad46 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -43,8 +43,12 @@ include::diff-options.txt[] --first-parent:: Follow only the first parent commit upon seeing a merge - commit. This option gives a better overview of the - evolution of a particular branch. + commit. This option can give a better overview when + viewing the evolution of a particular topic branch, + because merges into a topic branch tend to be only about + adjusting to updated upstream from time to time, and + this option allows you to ignore the individual commits + brought in to your history by such a merge. -g, \--walk-reflogs:: Show commits as they were recorded in the reflog. The log contains diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index a03f9fe5fa..438dae02e2 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -15,6 +15,7 @@ SYNOPSIS [ \--min-age=timestamp ] [ \--sparse ] [ \--no-merges ] + [ \--first-parent ] [ \--remove-empty ] [ \--full-history ] [ \--not ] @@ -256,6 +257,15 @@ limiting may be applied. Do not print commits with more than one parent. +--first-parent:: + Follow only the first parent commit upon seeing a merge + commit. This option can give a better overview when + viewing the evolution of a particular topic branch, + because merges into a topic branch tend to be only about + adjusting to updated upstream from time to time, and + this option allows you to ignore the individual commits + brought in to your history by such a merge. + --not:: Reverses the meaning of the '{caret}' prefix (or lack thereof) From 462a15bc82e6adbcb8db5fcc4791ec70a026aa4b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 26 Dec 2007 16:51:19 -0800 Subject: [PATCH 31/35] combine-diff: Fix path quoting Earlier when showing combined diff, the filenames on the ---/+++ header lines were quoted incorrectly. a/ (or b/) prefix was output literally and then the path was output, with c-quoting. This fixes the quoting logic, and while at it, adjusts the code to use the customizable prefix (a_prefix and b_prefix) introduced recently. Signed-off-by: Junio C Hamano --- combine-diff.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index e22db89932..7d710334ff 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -646,12 +646,28 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt, sline->p_lno[i] = sline->p_lno[j]; } -static void dump_quoted_path(const char *prefix, const char *path, +static void dump_quoted_path(const char *head, + const char *prefix, + const char *path, const char *c_meta, const char *c_reset) { - printf("%s%s", c_meta, prefix); - quote_c_style(path, NULL, stdout, 0); - printf("%s\n", c_reset); + static struct strbuf buf = STRBUF_INIT; + + strbuf_reset(&buf); + strbuf_addstr(&buf, c_meta); + strbuf_addstr(&buf, head); + if (quote_c_style(prefix, NULL, NULL, 0) || + quote_c_style(path, NULL, NULL, 0)) { + strbuf_addch(&buf, '"'); + quote_c_style(prefix, &buf, NULL, 1); + quote_c_style(path, &buf, NULL, 1); + strbuf_addch(&buf, '"'); + } else { + strbuf_addstr(&buf, prefix); + strbuf_addstr(&buf, path); + } + strbuf_addstr(&buf, c_reset); + puts(buf.buf); } static void show_patch_diff(struct combine_diff_path *elem, int num_parent, @@ -793,7 +809,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, if (rev->loginfo && !rev->no_commit_id) show_log(rev, opt->msg_sep); dump_quoted_path(dense ? "diff --cc " : "diff --combined ", - elem->path, c_meta, c_reset); + "", elem->path, c_meta, c_reset); printf("%sindex ", c_meta); for (i = 0; i < num_parent; i++) { abb = find_unique_abbrev(elem->parent[i].sha1, @@ -829,14 +845,19 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, printf("%s\n", c_reset); } if (added) - dump_quoted_path("--- /dev/", "null", c_meta, c_reset); + dump_quoted_path("--- ", "", "/dev/null", + c_meta, c_reset); else - dump_quoted_path("--- a/", elem->path, c_meta, c_reset); + dump_quoted_path("--- ", opt->a_prefix, elem->path, + c_meta, c_reset); if (deleted) - dump_quoted_path("+++ /dev/", "null", c_meta, c_reset); + dump_quoted_path("+++ ", "", "/dev/null", + c_meta, c_reset); else - dump_quoted_path("+++ b/", elem->path, c_meta, c_reset); - dump_sline(sline, cnt, num_parent, DIFF_OPT_TST(opt, COLOR_DIFF)); + dump_quoted_path("+++ ", opt->b_prefix, elem->path, + c_meta, c_reset); + dump_sline(sline, cnt, num_parent, + DIFF_OPT_TST(opt, COLOR_DIFF)); } free(result); From d56250911f4ec074048f4edb34551eaf384172cc Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 26 Dec 2007 17:13:36 -0800 Subject: [PATCH 32/35] Fix rewrite_diff() name quoting. This moves the logic to quote two paths (prefix + path) in C-style introduced in the previous commit from the dump_quoted_path() in combine-diff.c to quote.c, and uses it to fix rewrite_diff() that never C-quoted the pathnames correctly. Signed-off-by: Junio C Hamano --- combine-diff.c | 11 +---------- diff.c | 12 +++++++++--- quote.c | 16 ++++++++++++++++ quote.h | 1 + 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index 7d710334ff..0e19cbaacc 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -656,16 +656,7 @@ static void dump_quoted_path(const char *head, strbuf_reset(&buf); strbuf_addstr(&buf, c_meta); strbuf_addstr(&buf, head); - if (quote_c_style(prefix, NULL, NULL, 0) || - quote_c_style(path, NULL, NULL, 0)) { - strbuf_addch(&buf, '"'); - quote_c_style(prefix, &buf, NULL, 1); - quote_c_style(path, &buf, NULL, 1); - strbuf_addch(&buf, '"'); - } else { - strbuf_addstr(&buf, prefix); - strbuf_addstr(&buf, path); - } + quote_two_c_style(&buf, prefix, path, 0); strbuf_addstr(&buf, c_reset); puts(buf.buf); } diff --git a/diff.c b/diff.c index 61fd49236a..5bdc111378 100644 --- a/diff.c +++ b/diff.c @@ -300,19 +300,25 @@ static void emit_rewrite_diff(const char *name_a, const char *old = diff_get_color(color_diff, DIFF_FILE_OLD); const char *new = diff_get_color(color_diff, DIFF_FILE_NEW); const char *reset = diff_get_color(color_diff, DIFF_RESET); + static struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT; name_a += (*name_a == '/'); name_b += (*name_b == '/'); name_a_tab = strchr(name_a, ' ') ? "\t" : ""; name_b_tab = strchr(name_b, ' ') ? "\t" : ""; + strbuf_reset(&a_name); + strbuf_reset(&b_name); + quote_two_c_style(&a_name, o->a_prefix, name_a, 0); + quote_two_c_style(&b_name, o->b_prefix, name_b, 0); + diff_populate_filespec(one, 0); diff_populate_filespec(two, 0); lc_a = count_lines(one->data, one->size); lc_b = count_lines(two->data, two->size); - printf("%s--- %s%s%s%s\n%s+++ %s%s%s%s\n%s@@ -", - metainfo, o->a_prefix, name_a, name_a_tab, reset, - metainfo, o->b_prefix, name_b, name_b_tab, reset, fraginfo); + printf("%s--- %s%s%s\n%s+++ %s%s%s\n%s@@ -", + metainfo, a_name.buf, name_a_tab, reset, + metainfo, b_name.buf, name_b_tab, reset, fraginfo); print_line_count(lc_a); printf(" +"); print_line_count(lc_b); diff --git a/quote.c b/quote.c index 6986b4420f..d061626c34 100644 --- a/quote.c +++ b/quote.c @@ -213,6 +213,22 @@ size_t quote_c_style(const char *name, struct strbuf *sb, FILE *fp, int nodq) return quote_c_style_counted(name, -1, sb, fp, nodq); } +void quote_two_c_style(struct strbuf *sb, const char *prefix, const char *path, int nodq) +{ + if (quote_c_style(prefix, NULL, NULL, 0) || + quote_c_style(path, NULL, NULL, 0)) { + if (!nodq) + strbuf_addch(sb, '"'); + quote_c_style(prefix, sb, NULL, 1); + quote_c_style(path, sb, NULL, 1); + if (!nodq) + strbuf_addch(sb, '"'); + } else { + strbuf_addstr(sb, prefix); + strbuf_addstr(sb, path); + } +} + void write_name_quoted(const char *name, FILE *fp, int terminator) { if (terminator) { diff --git a/quote.h b/quote.h index ab7596f57b..4da110ec01 100644 --- a/quote.h +++ b/quote.h @@ -41,6 +41,7 @@ extern char *sq_dequote(char *); extern int unquote_c_style(struct strbuf *, const char *quoted, const char **endp); extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq); +extern void quote_two_c_style(struct strbuf *, const char *, const char *, int); extern void write_name_quoted(const char *name, FILE *, int terminator); extern void write_name_quotedpfx(const char *pfx, size_t pfxlen, From e25cfae6677423d05a81c0862f58d3319141794c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 26 Dec 2007 17:38:00 -0800 Subject: [PATCH 33/35] contrib: resurrect scripted git-revert. Signed-off-by: Junio C Hamano --- contrib/examples/git-revert.sh | 197 +++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100755 contrib/examples/git-revert.sh diff --git a/contrib/examples/git-revert.sh b/contrib/examples/git-revert.sh new file mode 100755 index 0000000000..49f00321b2 --- /dev/null +++ b/contrib/examples/git-revert.sh @@ -0,0 +1,197 @@ +#!/bin/sh +# +# Copyright (c) 2005 Linus Torvalds +# Copyright (c) 2005 Junio C Hamano +# + +case "$0" in +*-revert* ) + test -t 0 && edit=-e + replay= + me=revert + USAGE='[--edit | --no-edit] [-n] ' ;; +*-cherry-pick* ) + replay=t + edit= + me=cherry-pick + USAGE='[--edit] [-n] [-r] [-x] ' ;; +* ) + echo >&2 "What are you talking about?" + exit 1 ;; +esac + +SUBDIRECTORY_OK=Yes ;# we will cd up +. git-sh-setup +require_work_tree +cd_to_toplevel + +no_commit= +while case "$#" in 0) break ;; esac +do + case "$1" in + -n|--n|--no|--no-|--no-c|--no-co|--no-com|--no-comm|\ + --no-commi|--no-commit) + no_commit=t + ;; + -e|--e|--ed|--edi|--edit) + edit=-e + ;; + --n|--no|--no-|--no-e|--no-ed|--no-edi|--no-edit) + edit= + ;; + -r) + : no-op ;; + -x|--i-really-want-to-expose-my-private-commit-object-name) + replay= + ;; + -*) + usage + ;; + *) + break + ;; + esac + shift +done + +set_reflog_action "$me" + +test "$me,$replay" = "revert,t" && usage + +case "$no_commit" in +t) + # We do not intend to commit immediately. We just want to + # merge the differences in. + head=$(git-write-tree) || + die "Your index file is unmerged." + ;; +*) + head=$(git-rev-parse --verify HEAD) || + die "You do not have a valid HEAD" + files=$(git-diff-index --cached --name-only $head) || exit + if [ "$files" ]; then + die "Dirty index: cannot $me (dirty: $files)" + fi + ;; +esac + +rev=$(git-rev-parse --verify "$@") && +commit=$(git-rev-parse --verify "$rev^0") || + die "Not a single commit $@" +prev=$(git-rev-parse --verify "$commit^1" 2>/dev/null) || + die "Cannot run $me a root commit" +git-rev-parse --verify "$commit^2" >/dev/null 2>&1 && + die "Cannot run $me a multi-parent commit." + +encoding=$(git config i18n.commitencoding || echo UTF-8) + +# "commit" is an existing commit. We would want to apply +# the difference it introduces since its first parent "prev" +# on top of the current HEAD if we are cherry-pick. Or the +# reverse of it if we are revert. + +case "$me" in +revert) + git show -s --pretty=oneline --encoding="$encoding" $commit | + sed -e ' + s/^[^ ]* /Revert "/ + s/$/"/ + ' + echo + echo "This reverts commit $commit." + test "$rev" = "$commit" || + echo "(original 'git revert' arguments: $@)" + base=$commit next=$prev + ;; + +cherry-pick) + pick_author_script=' + /^author /{ + s/'\''/'\''\\'\'\''/g + h + s/^author \([^<]*\) <[^>]*> .*$/\1/ + s/'\''/'\''\'\'\''/g + s/.*/GIT_AUTHOR_NAME='\''&'\''/p + + g + s/^author [^<]* <\([^>]*\)> .*$/\1/ + s/'\''/'\''\'\'\''/g + s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p + + g + s/^author [^<]* <[^>]*> \(.*\)$/\1/ + s/'\''/'\''\'\'\''/g + s/.*/GIT_AUTHOR_DATE='\''&'\''/p + + q + }' + + logmsg=`git show -s --pretty=raw --encoding="$encoding" "$commit"` + set_author_env=`echo "$logmsg" | + LANG=C LC_ALL=C sed -ne "$pick_author_script"` + eval "$set_author_env" + export GIT_AUTHOR_NAME + export GIT_AUTHOR_EMAIL + export GIT_AUTHOR_DATE + + echo "$logmsg" | + sed -e '1,/^$/d' -e 's/^ //' + case "$replay" in + '') + echo "(cherry picked from commit $commit)" + test "$rev" = "$commit" || + echo "(original 'git cherry-pick' arguments: $@)" + ;; + esac + base=$prev next=$commit + ;; + +esac >.msg + +eval GITHEAD_$head=HEAD +eval GITHEAD_$next='`git show -s \ + --pretty=oneline --encoding="$encoding" "$commit" | + sed -e "s/^[^ ]* //"`' +export GITHEAD_$head GITHEAD_$next + +# This three way merge is an interesting one. We are at +# $head, and would want to apply the change between $commit +# and $prev on top of us (when reverting), or the change between +# $prev and $commit on top of us (when cherry-picking or replaying). + +git-merge-recursive $base -- $head $next && +result=$(git-write-tree 2>/dev/null) || { + mv -f .msg "$GIT_DIR/MERGE_MSG" + { + echo ' +Conflicts: +' + git ls-files --unmerged | + sed -e 's/^[^ ]* / /' | + uniq + } >>"$GIT_DIR/MERGE_MSG" + echo >&2 "Automatic $me failed. After resolving the conflicts," + echo >&2 "mark the corrected paths with 'git-add '" + echo >&2 "and commit the result." + case "$me" in + cherry-pick) + echo >&2 "You may choose to use the following when making" + echo >&2 "the commit:" + echo >&2 "$set_author_env" + esac + exit 1 +} +echo >&2 "Finished one $me." + +# If we are cherry-pick, and if the merge did not result in +# hand-editing, we will hit this commit and inherit the original +# author date and name. +# If we are revert, or if our cherry-pick results in a hand merge, +# we had better say that the current user is responsible for that. + +case "$no_commit" in +'') + git-commit -n -F .msg $edit + rm -f .msg + ;; +esac From 7ed0988adc0a3cb3f103c105af387e3ac48eea61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Thu, 20 Dec 2007 13:20:15 +0100 Subject: [PATCH 34/35] Make "--pretty=format" parser a bit more careful. When a commit message that does not have a terminating LF is read in and the memory that was allocated to read it happens to have a LF immediately after that, the code was not careful and went past the terminating NUL. Signed-off-by: Junio C Hamano --- pretty.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pretty.c b/pretty.c index 9db75b4e4f..5b1078beb6 100644 --- a/pretty.c +++ b/pretty.c @@ -412,7 +412,7 @@ static void parse_commit_header(struct format_commit_context *context) if (i == eol) { state++; /* strip empty lines */ - while (msg[eol + 1] == '\n') + while (msg[eol] == '\n' && msg[eol + 1] == '\n') eol++; } else if (!prefixcmp(msg + i, "author ")) { context->author.off = i + 7; @@ -425,6 +425,8 @@ static void parse_commit_header(struct format_commit_context *context) context->encoding.len = eol - i - 9; } i = eol; + if (!msg[i]) + break; } context->body_off = i; context->commit_header_parsed = 1; From bbff2dce2baf840cca6ddfd79be3c27f93322f47 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 26 Dec 2007 18:16:52 -0800 Subject: [PATCH 35/35] GIT 1.5.4-rc2 Although everybody was quiet during the Christmas holiday, it's been a week since -rc1, so here is -rc2. Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.5.4.txt | 19 ++++++++++++++++++- GIT-VERSION-GEN | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Documentation/RelNotes-1.5.4.txt b/Documentation/RelNotes-1.5.4.txt index 528b26f7c7..e6fbcdb2e1 100644 --- a/Documentation/RelNotes-1.5.4.txt +++ b/Documentation/RelNotes-1.5.4.txt @@ -91,6 +91,16 @@ Updates since v1.5.3 * "git diff" Porcelain now respects diff.external configuration, which is another way to specify GIT_EXTERNAL_DIFF. + * "git diff" can be told to use different prefixes other than + "a/" and "b/" e.g. "git diff --src-prefix=l/ --dst-prefix=k/". + + * "git diff" sometimes did not quote paths with funny + characters properly. + + * "git log" (and any revision traversal commands) misbehaved + when --diff-filter is given but was not asked to actually + produce diff. + * HTTP proxy can be specified per remote repository using remote.*.httpproxy configuration, or global http.proxy configuration variable. @@ -208,6 +218,10 @@ Updates since v1.5.3 * "git commit --amend" can amend a merge that does not change the tree from its first parent. + * "git commit" used to unconditionally strip comment lines that + began with '#' and removed excess blank lines. This + behaviour has been made configurable. + * "git commit" has been rewritten in C. * "git stash random-text" does not create a new stash anymore. It was @@ -251,6 +265,9 @@ Updates since v1.5.3 reasonable usability fix and people's scripts shouldn't have been relying on the exact output from "git show" Porcelain anyway. + * "git cvsimport" did not notice errors from underlying "cvsps" + and produced a corrupt import silently. + * "git cvsexportcommit" learned -w option to specify and switch to the CVS working directory. @@ -327,6 +344,6 @@ series. -- exec >/var/tmp/1 -O=v1.5.4-rc0-85-gdbedf97 +O=v1.5.4-rc1-36-g49e6be5 echo O=`git describe refs/heads/master` git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index ad7e056620..817df1798c 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.5.4-rc1.GIT +DEF_VER=v1.5.4-rc2.GIT LF=' '