Code

Merge branch 'cn/maint-rev-list-doc' into maint-1.7.8
authorJunio C Hamano <gitster@pobox.com>
Mon, 9 Apr 2012 20:36:44 +0000 (13:36 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Apr 2012 20:36:44 +0000 (13:36 -0700)
* cn/maint-rev-list-doc:
  Documentation: use {asterisk} in rev-list-options.txt when needed

13 files changed:
Documentation/diff-options.txt
Documentation/git-rerere.txt
Documentation/technical/api-strbuf.txt
advice.c
builtin/revert.c
bundle.c
gitweb/gitweb.perl
strbuf.c
strbuf.h
t/Makefile
t/t5510-fetch.sh
t/t5704-bundle.sh
t/t9500-gitweb-standalone-no-errors.sh

index 9f7cba2be6a97cb85072d22b3317d37d1afe80bf..ba7cd13483194399762b0f48e218ddb4011dfcf1 100644 (file)
@@ -52,6 +52,9 @@ endif::git-format-patch[]
 --patience::
        Generate a diff using the "patience diff" algorithm.
 
+--histogram::
+       Generate a diff using the "histogram diff" algorithm.
+
 --stat[=<width>[,<name-width>[,<count>]]]::
        Generate a diffstat.  You can override the default
        output width for 80-column terminal by `--stat=<width>`.
index a6253ba617f5ebcd82e4cfb1702999c145fa346c..b43b7c8c0ed67fa37e20c41f35a703c28c4d9844 100644 (file)
@@ -8,7 +8,7 @@ git-rerere - Reuse recorded resolution of conflicted merges
 SYNOPSIS
 --------
 [verse]
-'git rerere' ['clear'|'forget' <pathspec>|'diff'|'status'|'gc']
+'git rerere' ['clear'|'forget' <pathspec>|'diff'|'remaining'|'status'|'gc']
 
 DESCRIPTION
 -----------
@@ -37,30 +37,35 @@ its working state.
 
 'clear'::
 
-This resets the metadata used by rerere if a merge resolution is to be
+Reset the metadata used by rerere if a merge resolution is to be
 aborted.  Calling 'git am [--skip|--abort]' or 'git rebase [--skip|--abort]'
 will automatically invoke this command.
 
 'forget' <pathspec>::
 
-This resets the conflict resolutions which rerere has recorded for the current
+Reset the conflict resolutions which rerere has recorded for the current
 conflict in <pathspec>.
 
 'diff'::
 
-This displays diffs for the current state of the resolution.  It is
+Display diffs for the current state of the resolution.  It is
 useful for tracking what has changed while the user is resolving
 conflicts.  Additional arguments are passed directly to the system
 'diff' command installed in PATH.
 
 'status'::
 
-Like 'diff', but this only prints the filenames that will be tracked
-for resolutions.
+Print paths with conflicts whose merge resolution rerere will record.
+
+'remaining'::
+
+Print paths with conflicts that have not been autoresolved by rerere.
+This includes paths whose resolutions cannot be tracked by rerere,
+such as conflicting submodules.
 
 'gc'::
 
-This prunes records of conflicted merges that
+Prune records of conflicted merges that
 occurred a long time ago.  By default, unresolved conflicts older
 than 15 days and resolved conflicts older than 60
 days are pruned.  These defaults are controlled via the
index afe27599511c5f6bab6e4f799fd18e7d83bdd454..95a8bf3846b30650f3ee089a4fbadfcc5a42da20 100644 (file)
@@ -255,8 +255,24 @@ same behaviour as well.
 
 `strbuf_getline`::
 
-       Read a line from a FILE* pointer. The second argument specifies the line
+       Read a line from a FILE *, overwriting the existing contents
+       of the strbuf. The second argument specifies the line
        terminator character, typically `'\n'`.
+       Reading stops after the terminator or at EOF.  The terminator
+       is removed from the buffer before returning.  Returns 0 unless
+       there was nothing left before EOF, in which case it returns `EOF`.
+
+`strbuf_getwholeline`::
+
+       Like `strbuf_getline`, but keeps the trailing terminator (if
+       any) in the buffer.
+
+`strbuf_getwholeline_fd`::
+
+       Like `strbuf_getwholeline`, but operates on a file descriptor.
+       It reads one character at a time, so it is very slow.  Do not
+       use it unless you need the correct position in the file
+       descriptor.
 
 `stripspace`::
 
index e02e632df380a8e9772d9cd9b1282204c56a7d4e..65a07859f261e12e88d638a1f4546583e0133d4c 100644 (file)
--- a/advice.c
+++ b/advice.c
@@ -21,11 +21,21 @@ static struct {
 
 void advise(const char *advice, ...)
 {
+       struct strbuf buf = STRBUF_INIT;
        va_list params;
+       const char *cp, *np;
 
        va_start(params, advice);
-       vreportf("hint: ", advice, params);
+       strbuf_addf(&buf, advice, params);
        va_end(params);
+
+       for (cp = buf.buf; *cp; cp = np) {
+               np = strchrnul(cp, '\n');
+               fprintf(stderr, _("hint: %.*s\n"), (int)(np - cp), cp);
+               if (*np)
+                       np++;
+       }
+       strbuf_release(&buf);
 }
 
 int git_default_advice_config(const char *var, const char *value)
@@ -46,16 +56,15 @@ int git_default_advice_config(const char *var, const char *value)
 int error_resolve_conflict(const char *me)
 {
        error("'%s' is not possible because you have unmerged files.", me);
-       if (advice_resolve_conflict) {
+       if (advice_resolve_conflict)
                /*
                 * Message used both when 'git commit' fails and when
                 * other commands doing a merge do.
                 */
-               advise("Fix them up in the work tree,");
-               advise("and then use 'git add/rm <file>' as");
-               advise("appropriate to mark resolution and make a commit,");
-               advise("or use 'git commit -a'.");
-       }
+               advise(_("Fix them up in the work tree,\n"
+                        "and then use 'git add/rm <file>' as\n"
+                        "appropriate to mark resolution and make a commit,\n"
+                        "or use 'git commit -a'."));
        return -1;
 }
 
index 028bcbcd75d21ada2bc0406ff74e3073014bb41f..00df5266d574ea1f8c9ab745ed606bac566392b5 100644 (file)
@@ -343,11 +343,10 @@ static void print_advice(int show_hint)
                return;
        }
 
-       if (show_hint) {
-               advise("after resolving the conflicts, mark the corrected paths");
-               advise("with 'git add <paths>' or 'git rm <paths>'");
-               advise("and commit the result with 'git commit'");
-       }
+       if (show_hint)
+               advise(_("after resolving the conflicts, mark the corrected paths\n"
+                        "with 'git add <paths>' or 'git rm <paths>'\n"
+                        "and commit the result with 'git commit'"));
 }
 
 static void write_message(struct strbuf *msgbuf, const char *filename)
index 8a1d53ba29a434139123bd7d4e37db47ba8728cb..6c4695eb9103efe3e825ce20303bd220bc6f8827 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -23,23 +23,6 @@ static void add_to_ref_list(const unsigned char *sha1, const char *name,
        list->nr++;
 }
 
-/* Eventually this should go to strbuf.[ch] */
-static int strbuf_readline_fd(struct strbuf *sb, int fd)
-{
-       strbuf_reset(sb);
-
-       while (1) {
-               char ch;
-               ssize_t len = xread(fd, &ch, 1);
-               if (len <= 0)
-                       return len;
-               strbuf_addch(sb, ch);
-               if (ch == '\n')
-                       break;
-       }
-       return 0;
-}
-
 static int parse_bundle_header(int fd, struct bundle_header *header,
                               const char *report_path)
 {
@@ -47,7 +30,7 @@ static int parse_bundle_header(int fd, struct bundle_header *header,
        int status = 0;
 
        /* The bundle header begins with the signature */
-       if (strbuf_readline_fd(&buf, fd) ||
+       if (strbuf_getwholeline_fd(&buf, fd, '\n') ||
            strcmp(buf.buf, bundle_signature)) {
                if (report_path)
                        error("'%s' does not look like a v2 bundle file",
@@ -57,7 +40,7 @@ static int parse_bundle_header(int fd, struct bundle_header *header,
        }
 
        /* The bundle header ends with an empty line */
-       while (!strbuf_readline_fd(&buf, fd) &&
+       while (!strbuf_getwholeline_fd(&buf, fd, '\n') &&
               buf.len && buf.buf[0] != '\n') {
                unsigned char sha1[20];
                int is_prereq = 0;
@@ -251,7 +234,7 @@ int create_bundle(struct bundle_header *header, const char *path,
        const char **argv_boundary = xmalloc((argc + 4) * sizeof(const char *));
        const char **argv_pack = xmalloc(6 * sizeof(const char *));
        int i, ref_count = 0;
-       char buffer[1024];
+       struct strbuf buf = STRBUF_INIT;
        struct rev_info revs;
        struct child_process rls;
        FILE *rls_fout;
@@ -283,20 +266,21 @@ int create_bundle(struct bundle_header *header, const char *path,
        if (start_command(&rls))
                return -1;
        rls_fout = xfdopen(rls.out, "r");
-       while (fgets(buffer, sizeof(buffer), rls_fout)) {
+       while (strbuf_getwholeline(&buf, rls_fout, '\n') != EOF) {
                unsigned char sha1[20];
-               if (buffer[0] == '-') {
-                       write_or_die(bundle_fd, buffer, strlen(buffer));
-                       if (!get_sha1_hex(buffer + 1, sha1)) {
+               if (buf.len > 0 && buf.buf[0] == '-') {
+                       write_or_die(bundle_fd, buf.buf, buf.len);
+                       if (!get_sha1_hex(buf.buf + 1, sha1)) {
                                struct object *object = parse_object(sha1);
                                object->flags |= UNINTERESTING;
-                               add_pending_object(&revs, object, buffer);
+                               add_pending_object(&revs, object, xstrdup(buf.buf));
                        }
-               } else if (!get_sha1_hex(buffer, sha1)) {
+               } else if (!get_sha1_hex(buf.buf, sha1)) {
                        struct object *object = parse_object(sha1);
                        object->flags |= SHOWN;
                }
        }
+       strbuf_release(&buf);
        fclose(rls_fout);
        if (finish_command(&rls))
                return error("rev-list died");
index 874023a33e9162b99bfa5b0e4038b102c129f6f1..6cf38853b5a1577ae0c7df80c39a98f44b22915e 100755 (executable)
@@ -1122,8 +1122,10 @@ sub dispatch {
        if (!defined $action) {
                if (defined $hash) {
                        $action = git_get_type($hash);
+                       $action or die_error(404, "Object does not exist");
                } elsif (defined $hash_base && defined $file_name) {
                        $action = git_get_type("$hash_base:$file_name");
+                       $action or die_error(404, "File or directory does not exist");
                } elsif (defined $project) {
                        $action = 'summary';
                } else {
@@ -2364,7 +2366,7 @@ sub get_feed_info {
        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);
+       return if (!$action || $action =~ /^(?:tags|heads|forks|tag|search)$/x);
 
        my $branch;
        # branches refs uses 'refs/heads/' prefix (fullname) to differentiate
index 3ad2cc00160fbf24e1e4904bb37ce44e8c414ce5..692cf1bd9a5e7d97d68eb44722afbdd1b59d2cda 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -383,6 +383,22 @@ int strbuf_getline(struct strbuf *sb, FILE *fp, int term)
        return 0;
 }
 
+int strbuf_getwholeline_fd(struct strbuf *sb, int fd, int term)
+{
+       strbuf_reset(sb);
+
+       while (1) {
+               char ch;
+               ssize_t len = xread(fd, &ch, 1);
+               if (len <= 0)
+                       return EOF;
+               strbuf_addch(sb, ch);
+               if (ch == term)
+                       break;
+       }
+       return 0;
+}
+
 int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
 {
        int fd, len;
index 46a33f8c46985c4377071011d6ea48d6d3fe5331..e42dbe5ac8e632d268916bfbfc2f830159f4a760 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -108,6 +108,7 @@ extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
 
 extern int strbuf_getwholeline(struct strbuf *, FILE *, int);
 extern int strbuf_getline(struct strbuf *, FILE *, int);
+extern int strbuf_getwholeline_fd(struct strbuf *, int, int);
 
 extern void stripspace(struct strbuf *buf, int skip_comments);
 extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env);
index 9046ec98164f44811b67124e869353db4050ec06..66ceefefccac693d29077ef8020fc4f9dbe7a0bc 100644 (file)
@@ -17,9 +17,9 @@ DEFAULT_TEST_TARGET ?= test
 # Shell quote;
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
 
-T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
-TSVN = $(wildcard t91[0-9][0-9]-*.sh)
-TGITWEB = $(wildcard t95[0-9][0-9]-*.sh)
+T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
+TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh))
+TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh))
 
 all: $(DEFAULT_TEST_TARGET)
 
index e0af4c4e62c40a563f692361944cc58e2c8e38e2..9d72b16393e3cbee30d16519ae641e84d7485f39 100755 (executable)
@@ -14,6 +14,14 @@ test_bundle_object_count () {
        test "$2" = $(grep '^[0-9a-f]\{40\} ' verify.out | wc -l)
 }
 
+convert_bundle_to_pack () {
+       while read x && test -n "$x"
+       do
+               :;
+       done
+       cat
+}
+
 test_expect_success setup '
        echo >file original &&
        git add file &&
@@ -207,13 +215,7 @@ test_expect_success 'unbundle 1' '
 
 test_expect_success 'bundle 1 has only 3 files ' '
        cd "$D" &&
-       (
-               while read x && test -n "$x"
-               do
-                       :;
-               done
-               cat
-       ) <bundle1 >bundle.pack &&
+       convert_bundle_to_pack <bundle1 >bundle.pack &&
        git index-pack bundle.pack &&
        test_bundle_object_count bundle.pack 3
 '
@@ -230,13 +232,7 @@ test_expect_success 'bundle does not prerequisite objects' '
        git add file2 &&
        git commit -m add.file2 file2 &&
        git bundle create bundle3 -1 HEAD &&
-       (
-               while read x && test -n "$x"
-               do
-                       :;
-               done
-               cat
-       ) <bundle3 >bundle.pack &&
+       convert_bundle_to_pack <bundle3 >bundle.pack &&
        git index-pack bundle.pack &&
        test_bundle_object_count bundle.pack 3
 '
@@ -434,14 +430,31 @@ test_expect_success 'fetch --dry-run' '
 '
 
 test_expect_success "should be able to fetch with duplicate refspecs" '
-        mkdir dups &&
-        cd dups &&
-        git init &&
-        git config branch.master.remote three &&
-        git config remote.three.url ../three/.git &&
-        git config remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
-        git config --add remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
-        git fetch three
+       mkdir dups &&
+       (
+               cd dups &&
+               git init &&
+               git config branch.master.remote three &&
+               git config remote.three.url ../three/.git &&
+               git config remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
+               git config --add remote.three.fetch +refs/heads/*:refs/remotes/origin/* &&
+               git fetch three
+       )
+'
+
+test_expect_success 'all boundary commits are excluded' '
+       test_commit base &&
+       test_commit oneside &&
+       git checkout HEAD^ &&
+       test_commit otherside &&
+       git checkout master &&
+       test_tick &&
+       git merge otherside &&
+       ad=$(git log --no-walk --format=%ad HEAD) &&
+       git bundle create twoside-boundary.bdl master --since="$ad" &&
+       convert_bundle_to_pack <twoside-boundary.bdl >twoside-boundary.pack &&
+       pack=$(git index-pack --fix-thin --stdin <twoside-boundary.pack) &&
+       test_bundle_object_count .git/objects/pack/pack-${pack##pack    }.pack 3
 '
 
 test_done
index 4ae127d106c4a8ada0cea928affeff933bf0dbaa..a51c8b0560f85d31dc73d40a58ae3e4c6655f140 100755 (executable)
@@ -4,59 +4,58 @@ test_description='some bundle related tests'
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-
-       : > file &&
-       git add file &&
-       test_tick &&
-       git commit -m initial &&
+       test_commit initial &&
        test_tick &&
        git tag -m tag tag &&
-       : > file2 &&
-       git add file2 &&
-       : > file3 &&
-       test_tick &&
-       git commit -m second &&
-       git add file3 &&
-       test_tick &&
-       git commit -m third
-
+       test_commit second &&
+       test_commit third &&
+       git tag -d initial &&
+       git tag -d second &&
+       git tag -d third
 '
 
 test_expect_success 'tags can be excluded by rev-list options' '
-
        git bundle create bundle --all --since=7.Apr.2005.15:16:00.-0700 &&
        git ls-remote bundle > output &&
        ! grep tag output
-
 '
 
 test_expect_success 'die if bundle file cannot be created' '
-
        mkdir adir &&
        test_must_fail git bundle create adir --all
-
 '
 
 test_expect_failure 'bundle --stdin' '
-
        echo master | git bundle create stdin-bundle.bdl --stdin &&
        git ls-remote stdin-bundle.bdl >output &&
        grep master output
-
 '
 
 test_expect_failure 'bundle --stdin <rev-list options>' '
-
        echo master | git bundle create hybrid-bundle.bdl --stdin tag &&
        git ls-remote hybrid-bundle.bdl >output &&
        grep master output
-
 '
 
 test_expect_success 'empty bundle file is rejected' '
+       : >empty-bundle &&
+       test_must_fail git fetch empty-bundle
+'
 
-    >empty-bundle && test_must_fail git fetch empty-bundle
-
+# This triggers a bug in older versions where the resulting line (with
+# --pretty=oneline) was longer than a 1024-char buffer.
+test_expect_success 'ridiculously long subject in boundary' '
+       : >file4 &&
+       test_tick &&
+       git add file4 &&
+       printf "%01200d\n" 0 | git commit -F - &&
+       test_commit fifth &&
+       git bundle create long-subject-bundle.bdl HEAD^..HEAD &&
+       git bundle list-heads long-subject-bundle.bdl >heads &&
+       test -s heads &&
+       git fetch long-subject-bundle.bdl &&
+       sed -n "/^-/{p;q}" long-subject-bundle.bdl >boundary &&
+       grep "^-$_x40 " boundary
 '
 
 test_done
index 53297156a314a5b5e03385a3ad887eff959359c4..94365bb0068661d0a964199f91878decb983b986 100755 (executable)
@@ -403,6 +403,14 @@ test_expect_success \
        'path_info: project/branch:dir/' \
        'gitweb_run "" "/.git/master:foo/"'
 
+test_expect_success \
+       'path_info: project/branch (non-existent)' \
+       'gitweb_run "" "/.git/non-existent"'
+
+test_expect_success \
+       'path_info: project/branch:filename (non-existent branch)' \
+       'gitweb_run "" "/.git/non-existent:non-existent"'
+
 test_expect_success \
        'path_info: project/branch:file (non-existent)' \
        'gitweb_run "" "/.git/master:non-existent"'