From: Junio C Hamano Date: Wed, 28 May 2008 05:22:47 +0000 (-0700) Subject: Merge 1.5.5.3 in X-Git-Tag: v1.5.6-rc1~37 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/b71ce7f3f13ebd0e212bdda82b012ee36df4f63f?hp=-c Merge 1.5.5.3 in --- b71ce7f3f13ebd0e212bdda82b012ee36df4f63f diff --combined Documentation/git.txt index 1f68dec541,ccaa655d1f..7182bb7f7e --- a/Documentation/git.txt +++ b/Documentation/git.txt @@@ -20,10 -20,10 +20,10 @@@ Git is a fast, scalable, distributed re unusually rich command set that provides both high-level operations and full access to internals. -See this link:tutorial.html[tutorial] to get started, then see +See this linkgit:gittutorial[7][tutorial] to get started, then see link:everyday.html[Everyday Git] for a useful minimum set of commands, and "man git-commandname" for documentation of each command. CVS users may -also want to read link:cvs-migration.html[CVS migration]. See +also want to read linkgit:gitcvs-migration[7][CVS migration]. See link:user-manual.html[Git User's Manual] for a more in-depth introduction. @@@ -46,11 -46,12 +46,12 @@@ Documentation for older releases are av * link:v1.5.5/git.html[documentation for release 1.5.5] * release notes for + link:RelNotes-1.5.5.3.txt[1.5.5.3], link:RelNotes-1.5.5.2.txt[1.5.5.2], link:RelNotes-1.5.5.1.txt[1.5.5.1], link:RelNotes-1.5.5.txt[1.5.5]. - * link:v1.5.5.2/git.html[documentation for release 1.5.5.2] + * link:v1.5.5.3/git.html[documentation for release 1.5.5.3] * link:v1.5.4.5/git.html[documentation for release 1.5.4.5] @@@ -144,8 -145,7 +145,8 @@@ help ...' --git-dir=:: Set the path to the repository. This can also be controlled by - setting the GIT_DIR environment variable. + setting the GIT_DIR environment variable. It can be an absolute + path or relative path to current working directory. --work-tree=:: Set the path to the working tree. The value will not be @@@ -153,12 -153,7 +154,12 @@@ a .git directory (i.e. $GIT_DIR is not set). This can also be controlled by setting the GIT_WORK_TREE environment variable and the core.worktree configuration - variable. + variable. It can be an absolute path or relative path to + the directory specified by --git-dir or GIT_DIR. + Note: If --git-dir or GIT_DIR are specified but none of + --work-tree, GIT_WORK_TREE and core.worktree is specified, + the current working directory is regarded as the top directory + of your working tree. --bare:: Treat the repository as a bare repository. If GIT_DIR @@@ -365,7 -360,7 +366,7 @@@ File/Directory Structur Please see the link:repository-layout.html[repository layout] document. -Read link:hooks.html[hooks] for more details about each hook. +Read linkgit:githooks[5][hooks] for more details about each hook. Higher level SCMs may provide and manage additional information in the `$GIT_DIR`. diff --combined builtin-commit.c index 07872c8ea7,b0fe69ecad..b294c1f88c --- a/builtin-commit.c +++ b/builtin-commit.c @@@ -47,7 -47,6 +47,7 @@@ static enum static char *logfile, *force_author, *template_file; static char *edit_message, *use_message; +static char *author_name, *author_email, *author_date; static int all, edit_flag, also, interactive, only, amend, signoff; static int quiet, verbose, untracked_files, no_verify, allow_empty; /* @@@ -176,13 -175,10 +176,13 @@@ static void add_remove_files(struct pat { int i; for (i = 0; i < list->nr; i++) { + struct stat st; struct path_list_item *p = &(list->items[i]); - if (file_exists(p->path)) - add_file_to_cache(p->path, 0); - else + + if (!lstat(p->path, &st)) { + if (add_to_cache(p->path, &st, 0)) + die("updating files failed"); + } else remove_file_from_cache(p->path); } } @@@ -223,6 -219,8 +223,8 @@@ static char *prepare_index(int argc, co if (interactive) { interactive_add(argc, argv, prefix); + if (read_cache() < 0) + die("index file corrupt"); commit_style = COMMIT_AS_IS; return get_index_file(); } @@@ -247,7 -245,7 +249,7 @@@ */ if (all || (also && pathspec && *pathspec)) { int fd = hold_locked_index(&index_lock, 1); - add_files_to_cache(0, also ? prefix : NULL, pathspec); + add_files_to_cache(also ? prefix : NULL, pathspec, 0); refresh_cache(REFRESH_QUIET); if (write_cache(fd, active_cache, active_nr) || close_lock_file(&index_lock)) @@@ -399,47 -397,6 +401,47 @@@ static int is_a_merge(const unsigned ch static const char sign_off_header[] = "Signed-off-by: "; +static void determine_author_info(void) +{ + char *name, *email, *date; + + name = getenv("GIT_AUTHOR_NAME"); + email = getenv("GIT_AUTHOR_EMAIL"); + date = getenv("GIT_AUTHOR_DATE"); + + if (use_message) { + const char *a, *lb, *rb, *eol; + + a = strstr(use_message_buffer, "\nauthor "); + if (!a) + die("invalid commit: %s", use_message); + + lb = strstr(a + 8, " <"); + rb = strstr(a + 8, "> "); + eol = strchr(a + 8, '\n'); + if (!lb || !rb || !eol) + die("invalid commit: %s", use_message); + + name = xstrndup(a + 8, lb - (a + 8)); + email = xstrndup(lb + 2, rb - (lb + 2)); + date = xstrndup(rb + 2, eol - (rb + 2)); + } + + if (force_author) { + const char *lb = strstr(force_author, " <"); + const char *rb = strchr(force_author, '>'); + + if (!lb || !rb) + die("malformed --author parameter"); + name = xstrndup(force_author, lb - force_author); + email = xstrndup(lb + 2, rb - (lb + 2)); + } + + author_name = name; + author_email = email; + author_date = date; +} + static int prepare_to_commit(const char *index_file, const char *prefix) { struct stat statbuf; @@@ -449,7 -406,6 +451,7 @@@ FILE *fp; const char *hook_arg1 = NULL; const char *hook_arg2 = NULL; + int ident_shown = 0; if (!no_verify && run_hook(index_file, "pre-commit", NULL)) return 0; @@@ -529,14 -485,7 +531,14 @@@ strbuf_release(&sb); + determine_author_info(); + + /* This checks if committer ident is explicitly given */ + git_committer_info(0); if (use_editor) { + char *author_ident; + const char *committer_ident; + if (in_merge) fprintf(fp, "#\n" @@@ -559,27 -508,6 +561,27 @@@ if (only_include_assumed) fprintf(fp, "# %s\n", only_include_assumed); + author_ident = xstrdup(fmt_name(author_name, author_email)); + committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"), + getenv("GIT_COMMITTER_EMAIL")); + if (strcmp(author_ident, committer_ident)) + fprintf(fp, + "%s" + "# Author: %s\n", + ident_shown++ ? "" : "#\n", + author_ident); + free(author_ident); + + if (!user_ident_explicitly_given) + fprintf(fp, + "%s" + "# Committer: %s\n", + ident_shown++ ? "" : "#\n", + committer_ident); + + if (ident_shown) + fprintf(fp, "#\n"); + saved_color_setting = wt_status_use_color; wt_status_use_color = 0; commitable = run_status(fp, index_file, prefix, 1); @@@ -696,6 -624,45 +698,6 @@@ static int message_is_empty(struct strb return 1; } -static void determine_author_info(struct strbuf *sb) -{ - char *name, *email, *date; - - name = getenv("GIT_AUTHOR_NAME"); - email = getenv("GIT_AUTHOR_EMAIL"); - date = getenv("GIT_AUTHOR_DATE"); - - if (use_message) { - const char *a, *lb, *rb, *eol; - - a = strstr(use_message_buffer, "\nauthor "); - if (!a) - die("invalid commit: %s", use_message); - - lb = strstr(a + 8, " <"); - rb = strstr(a + 8, "> "); - eol = strchr(a + 8, '\n'); - if (!lb || !rb || !eol) - die("invalid commit: %s", use_message); - - name = xstrndup(a + 8, lb - (a + 8)); - email = xstrndup(lb + 2, rb - (lb + 2)); - date = xstrndup(rb + 2, eol - (rb + 2)); - } - - if (force_author) { - const char *lb = strstr(force_author, " <"); - const char *rb = strchr(force_author, '>'); - - if (!lb || !rb) - die("malformed --author parameter"); - name = xstrndup(force_author, lb - force_author); - email = xstrndup(lb + 2, rb - (lb + 2)); - } - - strbuf_addf(sb, "author %s\n", fmt_ident(name, email, date, IDENT_ERROR_ON_NO_NAME)); -} - static int parse_and_validate_options(int argc, const char *argv[], const char * const usage[]) { @@@ -780,8 -747,10 +782,8 @@@ die("No paths with --include/--only does not make sense."); if (argc == 0 && only && amend) only_include_assumed = "Clever... amending the last one with dirty index."; - if (argc > 0 && !also && !only) { + if (argc > 0 && !also && !only) 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")) @@@ -806,7 -775,7 +808,7 @@@ int cmd_status(int argc, const char **a const char *index_file; int commitable; - git_config(git_status_config); + git_config(git_status_config, NULL); if (wt_status_use_color == -1) wt_status_use_color = git_use_color_default; @@@ -843,7 -812,7 +845,7 @@@ static void print_summary(const char *p rev.verbose_header = 1; rev.show_root_diff = 1; - rev.commit_format = get_commit_format("format:%h: %s"); + get_commit_format("format:%h: %s", &rev); rev.always_show_header = 0; rev.diffopt.detect_rename = 1; rev.diffopt.rename_limit = 100; @@@ -860,7 -829,7 +862,7 @@@ } } -int git_commit_config(const char *k, const char *v) +int git_commit_config(const char *k, const char *v, void *cb) { if (!strcmp(k, "commit.template")) { if (!v) @@@ -869,7 -838,7 +871,7 @@@ return 0; } - return git_status_config(k, v); + return git_status_config(k, v, cb); } static const char commit_utf8_warn[] = @@@ -897,7 -866,7 +899,7 @@@ int cmd_commit(int argc, const char **a unsigned char commit_sha1[20]; struct ref_lock *ref_lock; - git_config(git_commit_config); + git_config(git_commit_config, NULL); argc = parse_and_validate_options(argc, argv, builtin_commit_usage); @@@ -955,8 -924,7 +957,8 @@@ strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1)); } - determine_author_info(&sb); + strbuf_addf(&sb, "author %s\n", + fmt_ident(author_name, author_email, author_date, IDENT_ERROR_ON_NO_NAME)); strbuf_addf(&sb, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME)); if (!is_encoding_utf8(git_commit_encoding)) strbuf_addf(&sb, "encoding %s\n", git_commit_encoding); diff --combined git-filter-branch.sh index 80e99e5394,d846cd9c92..d04c346e12 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@@ -234,7 -234,7 +234,7 @@@ case "$filter_subdir" i ;; *) git rev-list --reverse --topo-order --default HEAD \ - --parents --full-history "$@" -- "$filter_subdir" + --parents "$@" -- "$filter_subdir" esac > ../revs || die "Could not get the commits" commits=$(wc -l <../revs | tr -d " ") @@@ -406,22 -406,8 +406,22 @@@ if [ "$filter_tag_name" ]; the echo "$ref -> $new_ref ($sha1 -> $new_sha1)" if [ "$type" = "tag" ]; then - # Warn that we are not rewriting the tag object itself. - warn "unreferencing tag object $sha1t" + new_sha1=$(git cat-file tag "$ref" | + sed -n \ + -e "1,/^$/{ + s/^object .*/object $new_sha1/ + s/^type .*/type commit/ + s/^tag .*/tag $new_ref/ + }" \ + -e '/^-----BEGIN PGP SIGNATURE-----/q' \ + -e 'p' | + git mktag) || + die "Could not create new tag object for $ref" + if git cat-file tag "$ref" | \ + grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1 + then + warn "gpg signature stripped from tag object $sha1t" + fi fi git update-ref "refs/tags/$new_ref" "$new_sha1" || @@@ -435,17 -421,11 +435,17 @@@ rm -rf "$tempdir trap - 0 unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE -test -z "$ORIG_GIT_DIR" || GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR -test -z "$ORIG_GIT_WORK_TREE" || GIT_WORK_TREE="$ORIG_GIT_WORK_TREE" && +test -z "$ORIG_GIT_DIR" || { + GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR +} +test -z "$ORIG_GIT_WORK_TREE" || { + GIT_WORK_TREE="$ORIG_GIT_WORK_TREE" && export GIT_WORK_TREE -test -z "$ORIG_GIT_INDEX_FILE" || GIT_INDEX_FILE="$ORIG_GIT_INDEX_FILE" && +} +test -z "$ORIG_GIT_INDEX_FILE" || { + GIT_INDEX_FILE="$ORIG_GIT_INDEX_FILE" && export GIT_INDEX_FILE +} git read-tree -u -m HEAD exit $ret diff --combined gitweb/gitweb.perl index 8308e2208e,345acf4520..57a19058a4 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@@ -369,12 -369,7 +369,12 @@@ sub filter_snapshot_fmts } our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++"; -do $GITWEB_CONFIG if -e $GITWEB_CONFIG; +if (-e $GITWEB_CONFIG) { + do $GITWEB_CONFIG; +} else { + our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++"; + do $GITWEB_CONFIG_SYSTEM if -e $GITWEB_CONFIG_SYSTEM; +} # version of the core git binary our $git_version = qx($GIT --version) =~ m/git version (.*)$/ ? $1 : "unknown"; @@@ -592,7 -587,7 +592,7 @@@ exit ## ====================================================================== ## action links -sub href(%) { +sub href (%) { my %params = @_; # default is to use -absolute url() i.e. $my_uri my $href = $params{-full} ? $my_url : $my_uri; @@@ -866,10 -861,6 +866,10 @@@ sub chop_str my $add_len = shift || 10; my $where = shift || 'right'; # 'left' | 'center' | 'right' + # Make sure perl knows it is utf8 encoded so we don't + # cut in the middle of a utf8 multibyte char. + $str = to_utf8($str); + # allow only $len chars, but don't cut a word if it would fit in $add_len # if it doesn't fit, cut it if it's still longer than the dots we would add # remove chopped character entities entirely @@@ -1452,46 -1443,6 +1452,46 @@@ sub format_snapshot_links } } +## ...................................................................... +## functions returning values to be passed, perhaps after some +## transformation, to other functions; e.g. returning arguments to href() + +# returns hash to be passed to href to generate gitweb URL +# in -title key it returns description of link +sub get_feed_info { + my $format = shift || 'Atom'; + my %res = (action => lc($format)); + + # feed links are possible only for project views + return unless (defined $project); + # some views should link to OPML, or to generic project feed, + # or don't have specific feed yet (so they should use generic) + return if ($action =~ /^(?:tags|heads|forks|tag|search)$/x); + + my $branch; + # branches refs uses 'refs/heads/' prefix (fullname) to differentiate + # from tag links; this also makes possible to detect branch links + if ((defined $hash_base && $hash_base =~ m!^refs/heads/(.*)$!) || + (defined $hash && $hash =~ m!^refs/heads/(.*)$!)) { + $branch = $1; + } + # find log type for feed description (title) + my $type = 'log'; + if (defined $file_name) { + $type = "history of $file_name"; + $type .= "/" if ($action eq 'tree'); + $type .= " on '$branch'" if (defined $branch); + } else { + $type = "log of $branch" if (defined $branch); + } + + $res{-title} = $type; + $res{'hash'} = (defined $branch ? "refs/heads/$branch" : undef); + $res{'file_name'} = $file_name; + + return %res; +} + ## ---------------------------------------------------------------------- ## git utility subroutines, invoking git commands @@@ -2554,49 -2505,30 +2554,49 @@@ EO } } if (defined $project) { - printf(''."\n", - esc_param($project), href(action=>"rss")); - printf(''."\n", - esc_param($project), href(action=>"rss", - extra_options=>"--no-merges")); - printf(''."\n", - esc_param($project), href(action=>"atom")); - printf(''."\n", - esc_param($project), href(action=>"atom", - extra_options=>"--no-merges")); + my %href_params = get_feed_info(); + if (!exists $href_params{'-title'}) { + $href_params{'-title'} = 'log'; + } + + foreach my $format qw(RSS Atom) { + my $type = lc($format); + my %link_attr = ( + '-rel' => 'alternate', + '-title' => "$project - $href_params{'-title'} - $format feed", + '-type' => "application/$type+xml" + ); + + $href_params{'action'} = $type; + $link_attr{'-href'} = href(%href_params); + print "\n"; + + $href_params{'extra_options'} = '--no-merges'; + $link_attr{'-href'} = href(%href_params); + $link_attr{'-title'} .= ' (no merges)'; + print "\n"; + } + } else { printf(''."\n", + 'href="%s" type="text/plain; charset=utf-8" />'."\n", $site_name, href(project=>undef, action=>"project_index")); printf(''."\n", + 'href="%s" type="text/x-opml" />'."\n", $site_name, href(project=>undef, action=>"opml")); } if (defined $favicon) { - print qq(\n); + print qq(\n); } print "\n" . @@@ -2664,35 -2596,23 +2664,35 @@@ } sub git_footer_html { + my $feed_class = 'rss_logo'; + print "
\n"; if (defined $project) { my $descr = git_get_project_description($project); if (defined $descr) { print "\n"; } - print $cgi->a({-href => href(action=>"rss"), - -class => "rss_logo"}, "RSS") . " "; - print $cgi->a({-href => href(action=>"atom"), - -class => "rss_logo"}, "Atom") . "\n"; + + my %href_params = get_feed_info(); + if (!%href_params) { + $feed_class .= ' generic'; + } + $href_params{'-title'} ||= 'log'; + + foreach my $format qw(RSS Atom) { + $href_params{'action'} = lc($format); + print $cgi->a({-href => href(%href_params), + -title => "$href_params{'-title'} $format feed", + -class => $feed_class}, $format)."\n"; + } + } else { print $cgi->a({-href => href(project=>undef, action=>"opml"), - -class => "rss_logo"}, "OPML") . " "; + -class => $feed_class}, "OPML") . " "; print $cgi->a({-href => href(project=>undef, action=>"project_index"), - -class => "rss_logo"}, "TXT") . "\n"; + -class => $feed_class}, "TXT") . "\n"; } - print "
\n" ; + print "\n"; # class="page_footer" if (-f $site_footer) { open (my $fd, $site_footer); @@@ -2756,7 -2676,7 +2756,7 @@@ sub git_print_page_nav } sub format_paging_nav { - my ($action, $hash, $head, $page, $nrevs) = @_; + my ($action, $hash, $head, $page, $has_next_link) = @_; my $paging_nav; @@@ -2774,7 -2694,7 +2774,7 @@@ $paging_nav .= " ⋅ prev"; } - if ($nrevs >= (100 * ($page+1)-1)) { + if ($has_next_link) { $paging_nav .= " ⋅ " . $cgi->a({-href => href(-replay=>1, page=>$page+1), -accesskey => "n", -title => "Alt-n"}, "next"); @@@ -4665,7 -4585,7 +4665,7 @@@ sub git_log my @commitlist = parse_commits($hash, 101, (100 * $page)); - my $paging_nav = format_paging_nav('log', $hash, $head, $page, (100 * ($page+1))); + my $paging_nav = format_paging_nav('log', $hash, $head, $page, $#commitlist >= 100); git_header_html(); git_print_page_nav('log','', $hash,undef,undef, $paging_nav); @@@ -5585,7 -5505,7 +5585,7 @@@ sub git_shortlog my @commitlist = parse_commits($hash, 101, (100 * $page)); - my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, (100 * ($page+1))); + my $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, $#commitlist >= 100); my $next_link = ''; if ($#commitlist >= 100) { $next_link = diff --combined t/t7003-filter-branch.sh index 1e8a205e53,f126204d49..e26f726930 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@@ -97,7 -97,7 +97,7 @@@ test_expect_success 'subdirectory filte test_must_fail git show sub:subdir ' - test_expect_success 'setup and filter history that requires --full-history' ' + test_expect_success 'more setup' ' git checkout master && mkdir subdir && echo A > subdir/new && @@@ -107,16 -107,7 +107,7 @@@ git rm a && test_tick && git commit -m "again subdir on master" && - git merge branch && - git branch sub-master && - git-filter-branch -f --subdirectory-filter subdir sub-master - ' - - test_expect_success 'subdirectory filter result looks okay' ' - test 3 = $(git rev-list -1 --parents sub-master | wc -w) && - git show sub-master^:new && - git show sub-master^2:new && - test_must_fail git show sub:subdir + git merge branch ' test_expect_success 'use index-filter to move into a subdirectory' ' @@@ -125,7 -116,7 +116,7 @@@ "git ls-files -s | sed \"s-\\t-&newsubdir/-\" | GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \ git update-index --index-info && - mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" directorymoved && + mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved && test -z "$(git diff HEAD directorymoved:newsubdir)"' test_expect_success 'stops when msg filter fails' ' @@@ -219,36 -210,4 +210,36 @@@ test_expect_success 'Subdirectory filte test $(git rev-list master | wc -l) = 3 ' +test_expect_success 'Tag name filtering retains tag message' ' + git tag -m atag T && + git cat-file tag T > expect && + git filter-branch -f --tag-name-filter cat && + git cat-file tag T > actual && + test_cmp expect actual +' + +faux_gpg_tag='object XXXXXX +type commit +tag S +tagger T A Gger 1206026339 -0500 + +This is a faux gpg signed tag. +-----BEGIN PGP SIGNATURE----- +Version: FauxGPG v0.0.0 (FAUX/Linux) + +gdsfoewhxu/6l06f1kxyxhKdZkrcbaiOMtkJUA9ITAc1mlamh0ooasxkH1XwMbYQ +acmwXaWET20H0GeAGP+7vow= +=agpO +-----END PGP SIGNATURE----- +' +test_expect_success 'Tag name filtering strips gpg signature' ' + sha1=$(git rev-parse HEAD) && + sha1t=$(echo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | git mktag) && + git update-ref "refs/tags/S" "$sha1t" && + echo "$faux_gpg_tag" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect && + git filter-branch -f --tag-name-filter cat && + git cat-file tag S > actual && + test_cmp expect actual +' + test_done